diff --git a/.cirrus.yml b/.cirrus.yml index 83af9d1f6f..3d83be3b41 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -10,6 +10,7 @@ task: PATH: "$CIRRUS_WORKING_DIR/bin:$CIRRUS_WORKING_DIR/bin/cache/dart-sdk/bin:$PATH" ANDROID_SDK_ROOT: "/opt/android_sdk" git_fetch_script: + - git clean -xfd - git fetch origin - git fetch origin master # To set FETCH_HEAD for "git merge-base" to work pub_cache: @@ -27,9 +28,9 @@ task: env: SHARD: docs # For uploading master docs to Firebase master branch staging site - FIREBASE_MASTER_TOKEN: ENCRYPTED[37e8b82f167864cae9a3f4d2cf3f37dea331d9375c295327c45de524f6c588fa6f6d63e5784f10f6d43ce29689f36c92] + FIREBASE_MASTER_TOKEN: ENCRYPTED[eb768d18798fdc5abfe09b224e1724c4d82831d715ccf90df2c79d618c317216cbd99493278361f6fe7948b409b603f0] # For uploading beta docs to Firebase public live site - FIREBASE_PUBLIC_TOKEN: ENCRYPTED[c422da192f06da7b4449ca8e7aa866dabeb8a0f8d7488497c2e7e447e6fd31d917e6c813db081dc4e2a7a63afdf41864] + FIREBASE_PUBLIC_TOKEN: ENCRYPTED[37e8b82f167864cae9a3f4d2cf3f37dea331d9375c295327c45de524f6c588fa6f6d63e5784f10f6d43ce29689f36c92] docs_script: ./dev/bots/docs.sh - name: deploy_gallery only_if: $CIRRUS_BRANCH == 'dev' @@ -49,6 +50,7 @@ task: - dart --enable-asserts ./dev/bots/analyze.dart - name: tests-linux env: + GCLOUD_SERVICE_ACCOUNT_KEY: ENCRYPTED[f12abe60f5045d619ef4c79b83dd1e0722a0b0b13dbea95fbe334e2db7fffbcd841a5a92da8824848b539a19afe0c9fb] SHARD: tests test_script: - dart --enable-asserts ./dev/bots/test.dart @@ -57,6 +59,7 @@ task: memory: 12G - name: tool_tests-linux env: + GCLOUD_SERVICE_ACCOUNT_KEY: ENCRYPTED[f12abe60f5045d619ef4c79b83dd1e0722a0b0b13dbea95fbe334e2db7fffbcd841a5a92da8824848b539a19afe0c9fb] SHARD: tool_tests test_script: - dart --enable-asserts ./dev/bots/test.dart @@ -66,6 +69,9 @@ task: - name: build_tests-linux env: SHARD: build_tests + - name: integration_tests-linux + env: + SHARD: integration_tests test_script: # Unsetting CIRRUS_CHANGE_MESSAGE and CIRRUS_COMMIT_MESSAGE as they # might include non-ASCII characters which makes Gradle crash. @@ -83,21 +89,18 @@ task: container: cpu: 4 memory: 12G - - name: codelabs-build-test - env: - SHARD: codelabs-build-test - build_test_script: ./dev/bots/codelabs_build_test.sh task: use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' && $CIRRUS_PR == '' windows_container: - image: cirrusci/windowsservercore:2016 + image: cirrusci/android-sdk:28-windowsservercore-ltsc2016 os_version: 2016 cpu: 4 env: CIRRUS_WORKING_DIR: "C:\\Windows\\Temp\\flutter sdk" git_fetch_script: + - git clean -xfd - git fetch origin - git fetch origin master # To set FETCH_HEAD for "git merge-base" to work pub_cache: @@ -119,9 +122,11 @@ task: matrix: - name: tests-windows env: + GCLOUD_SERVICE_ACCOUNT_KEY: ENCRYPTED[f12abe60f5045d619ef4c79b83dd1e0722a0b0b13dbea95fbe334e2db7fffbcd841a5a92da8824848b539a19afe0c9fb] SHARD: tests - name: tool_tests-windows env: + GCLOUD_SERVICE_ACCOUNT_KEY: ENCRYPTED[f12abe60f5045d619ef4c79b83dd1e0722a0b0b13dbea95fbe334e2db7fffbcd841a5a92da8824848b539a19afe0c9fb] SHARD: tool_tests - name: build_tests-windows env: @@ -129,6 +134,12 @@ task: container: cpu: 4 memory: 12G + - name: integration_tests-windows + env: + SHARD: integration_tests + container: + cpu: 4 + memory: 12G task: use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' @@ -141,6 +152,7 @@ task: - tests-macos - tool_tests-macos - build_tests-macos + - add2app-macos env: # Name the SDK directory to include a space so that we constantly # test path names with spaces in them. @@ -155,8 +167,13 @@ task: # Private repo for publishing certificates. PUBLISHING_MATCH_CERTIFICATE_REPO: git@github.com:flutter/private_publishing_certificates.git osx_instance: - image: high-sierra-xcode-9.4.1 + image: mojave-xcode-10.1 + # occasionally the clock on these machines is out of sync + # with the actual time - this should help to verify + print_date_script: + - date git_fetch_script: + - git clean -xfd - git fetch origin - git fetch origin master # To set FETCH_HEAD setup_script: @@ -168,14 +185,42 @@ task: task: use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' osx_instance: - image: high-sierra-xcode-9.4.1 + image: mojave-xcode-10.1 depends_on: - analyze env: CIRRUS_WORKING_DIR: "/tmp/flutter sdk" + COCOAPODS_DISABLE_STATS: true + matrix: + - name: tests-macos + env: + GCLOUD_SERVICE_ACCOUNT_KEY: ENCRYPTED[f12abe60f5045d619ef4c79b83dd1e0722a0b0b13dbea95fbe334e2db7fffbcd841a5a92da8824848b539a19afe0c9fb] + SHARD: tests + - name: tool_tests-macos + env: + GCLOUD_SERVICE_ACCOUNT_KEY: ENCRYPTED[f12abe60f5045d619ef4c79b83dd1e0722a0b0b13dbea95fbe334e2db7fffbcd841a5a92da8824848b539a19afe0c9fb] + SHARD: tool_tests + - name: $SHARD-macos + env: + matrix: + - SHARD: integration_tests + - SHARD: build_tests + COCOAPODS_DISABLE_STATS: true + FLUTTER_FRAMEWORK_DIR: "/tmp/flutter sdk/bin/cache/artifacts/engine/ios/" + osx_instance: + image: mojave-flutter + remove_preinstalled_fluuter_script: rm -rf $FLUTTER_HOME + - name: add2app-macos + env: + SHARD: add2app_test + # occasionally the clock on these machines is out of sync + # with the actual time - this should help to verify + print_date_script: + - date install_cocoapods_script: - sudo gem install cocoapods git_fetch_script: + - git clean -xfd - git fetch origin - git fetch origin master # To set FETCH_HEAD for "git merge-base" to work pub_cache: @@ -193,22 +238,6 @@ task: test_all_script: | ulimit -S -n 2048 # https://github.com/flutter/flutter/issues/2976 bin/cache/dart-sdk/bin/dart --enable-asserts dev/bots/test.dart - matrix: - - name: tests-macos - env: - SHARD: tests - - name: tool_tests-macos - env: - SHARD: tool_tests - - name: build_tests-macos - env: - SHARD: build_tests - COCOAPODS_DISABLE_STATS: true - FLUTTER_FRAMEWORK_DIR: "/tmp/flutter sdk/bin/cache/artifacts/engine/ios/" - container: - cpu: 4 - memory: 12G - docker_builder: # Only build a new docker image when we tag a release (for dev, beta, or release.) @@ -221,7 +250,7 @@ docker_builder: - tests-linux - tool_tests-linux - build_tests-linux + - integration_tests-linux build_script: "$CIRRUS_WORKING_DIR/dev/ci/docker_linux/docker_build.sh" login_script: "$CIRRUS_WORKING_DIR/dev/ci/docker_linux/docker_login.sh" push_script: "$CIRRUS_WORKING_DIR/dev/ci/docker_linux/docker_push.sh" - diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..3a14634667 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,36 @@ +## Description + +*Replace this paragraph with a description of what this PR is doing. If you're modifying existing behavior, describe the existing behavior, how this PR is changing it, and what motivated the change. If you're changing visual properties, consider including before/after screenshots (and runnable code snippets to reproduce them).* + +## Related Issues + +*Replace this paragraph with a list of issues related to this PR from our [issue database]. Indicate, which of these issues are resolved or fixed by this PR.* + +## 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 tests for *all* changed/updated/fixed behaviors (See [Test Coverage]). +- [ ] All existing and new tests are passing. +- [ ] I updated/added relevant documentation (doc comments with `///`). +- [ ] The analyzer (`flutter analyze --flutter-repo`) does not report any problems on my PR. +- [ ] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. +- [ ] I signed the [CLA]. +- [ ] I am willing to follow-up on review comments in a timely manner. + +## Breaking Change + +Does your PR require Flutter developers to manually update their apps to accommodate your change? + +- [ ] Yes, this is a breaking change (Please read [Handling breaking changes]). +- [ ] No, this is *not* a breaking change. + + +[issue database]: https://github.com/flutter/flutter/issues +[Contributor Guide]: https://github.com/flutter/flutter/wiki/Tree-hygiene#overview +[Test Coverage]: https://github.com/flutter/flutter/wiki/Test-coverage-for-package%3Aflutter +[Flutter Style Guide]: https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo +[Features we expect every widget to implement]: https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#features-we-expect-every-widget-to-implement +[CLA]: https://cla.developers.google.com/ +[Handling breaking changes]: https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes diff --git a/.gitignore b/.gitignore index ce9e65c132..40308abf0a 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,9 @@ /packages/flutter/coverage/ version +# packages file containing multi-root paths +.packages.generated + # Flutter/Dart/Pub related **/doc/api/ .dart_tool/ diff --git a/AUTHORS b/AUTHORS index 2b9f1a8a2b..b96fcbd960 100644 --- a/AUTHORS +++ b/AUTHORS @@ -32,8 +32,10 @@ Chema Molins Stefan Mitev Jasper van Riet Mattijs Fuijkschot +Volodymyr Lykhonis TruongSinh Tran-Nguyen Sander Dalby Larsen Marco Scannadinari Frederik Schweiger Martin Staadecker +Igor Katsuba diff --git a/README.md b/README.md index 030e05666a..cf919a3dbc 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,10 @@ Flutter is Google’s mobile app SDK for crafting high-quality native interfaces ### Documentation -**Main site: [flutter.io][]** -* [Install](https://flutter.io/get-started/install/) -* [Get started](https://flutter.io/get-started/) -* [API documentation](https://docs.flutter.io/) +**Main site: [flutter.dev][]** +* [Install](https://flutter.dev/get-started/install/) +* [Get started](https://flutter.dev/get-started/) +* [API documentation](https://docs.flutter.dev/) * [Changelog](https://github.com/flutter/flutter/wiki/Changelog) * [How to contribute](https://github.com/flutter/flutter/blob/master/CONTRIBUTING.md) @@ -42,12 +42,12 @@ Cupertino (iOS-flavor) widgets, rich motion APIs, smooth natural scrolling, and platform awareness. [Brand-first shopping design](https://github.com/flutter/flutter/tree/master/examples/flutter_gallery/lib/demo/animation) -[Fitness app design](https://github.com/flutter/posse_gallery) +Fitness app design [Contact app design](https://github.com/flutter/flutter/blob/master/examples/flutter_gallery/lib/demo/contacts_demo.dart) [iOS chat app design](https://codelabs.developers.google.com/codelabs/flutter/) -Browse the widget catalog. +Browse the widget catalog. ## Modern, reactive framework @@ -89,9 +89,9 @@ class CounterState extends State { } ``` -Browse the widget catalog +Browse the widget catalog and learn more about the -functional-reactive framework. +functional-reactive framework. ## Access native features and SDKs @@ -118,8 +118,8 @@ Future getBatteryLevel() async { } ``` -Learn how to use packages or -write platform channels +Learn how to use packages or +write platform channels to access native code, APIs, and SDKs. ## Unified app development @@ -133,7 +133,7 @@ you can use Flutter for your views and leverage much of your existing Java/Kotlin/ObjC/Swift investment. Learn more about what makes Flutter special in the -technical overview. +technical overview. # More resources @@ -146,7 +146,7 @@ To join the team working on Flutter, see our [contributor guide](CONTRIBUTING.md [Build Status - Cirrus]: https://api.cirrus-ci.com/github/flutter/flutter.svg [Build status]: https://cirrus-ci.com/github/flutter/flutter/master -[flutter.io]: https://flutter.io +[flutter.dev]: https://flutter.dev [Flutter logo]: https://github.com/dart-lang/site-shared/blob/master/src/_assets/image/flutter/icon/64.png?raw=1 [Gitter Channel]: https://badges.gitter.im/flutter/flutter.svg -[Gitter badge]: https://gitter.im/flutter/flutter?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge +[Gitter badge]: https://gitter.im/flutter/flutter?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge \ No newline at end of file diff --git a/bin/flutter b/bin/flutter index b626802446..178994f56d 100755 --- a/bin/flutter +++ b/bin/flutter @@ -121,7 +121,7 @@ function upgrade_flutter () { retry_upgrade - "$DART" --snapshot="$SNAPSHOT_PATH" --packages="$FLUTTER_TOOLS_DIR/.packages" "$SCRIPT_PATH" + "$DART" --snapshot="$SNAPSHOT_PATH" --snapshot-kind=app-jit --packages="$FLUTTER_TOOLS_DIR/.packages" "$SCRIPT_PATH" training echo "$revision" > "$STAMP_PATH" fi # The exit here is duplicitous since the function is run in a subshell, diff --git a/bin/flutter.bat b/bin/flutter.bat index 544e77a8d7..7aa7020c2b 100644 --- a/bin/flutter.bat +++ b/bin/flutter.bat @@ -138,7 +138,7 @@ GOTO :after_subroutine ECHO Running pub upgrade... CALL "%pub%" upgrade "%VERBOSITY%" IF "%ERRORLEVEL%" EQU "0" goto :upgrade_succeeded - ECHO Error Unable to 'pub upgrade' flutter tool. Retrying in five seconds... (%remaining_tries% tries left) + ECHO Error (%ERRORLEVEL%): Unable to 'pub upgrade' flutter tool. Retrying in five seconds... (%remaining_tries% tries left) timeout /t 5 /nobreak 2>NUL SET /A remaining_tries-=1 IF "%remaining_tries%" EQU "0" GOTO upgrade_retries_exhausted @@ -152,7 +152,7 @@ GOTO :after_subroutine POPD - "%dart%" --snapshot="%snapshot_path%" --packages="%flutter_tools_dir%\.packages" "%script_path%" + "%dart%" --snapshot="%snapshot_path%" --snapshot-kind=app-jit --packages="%flutter_tools_dir%\.packages" "%script_path%" IF "%ERRORLEVEL%" NEQ "0" ( ECHO Error: Unable to create dart snapshot for flutter tool. SET exit_code=%ERRORLEVEL% diff --git a/bin/internal/engine.version b/bin/internal/engine.version index ab5b6b1532..3f047b14fd 100644 --- a/bin/internal/engine.version +++ b/bin/internal/engine.version @@ -1 +1 @@ -3757390fa4b00d2d261bfdf5182d2e87c9113ff9 +0d83a2ecd1bb78f8e1f0ed9719ff3751cdfdd064 diff --git a/bin/internal/goldens.version b/bin/internal/goldens.version index 9bace5c36f..3100f32ba6 100644 --- a/bin/internal/goldens.version +++ b/bin/internal/goldens.version @@ -1 +1 @@ -ec90c64e598804d691c1c6bfcd191a63480e3053 +894e9634cda6eb940d1ad4efb20b63a174bb7797 diff --git a/bin/internal/update_dart_sdk.sh b/bin/internal/update_dart_sdk.sh index a53eb70597..999576c178 100755 --- a/bin/internal/update_dart_sdk.sh +++ b/bin/internal/update_dart_sdk.sh @@ -44,9 +44,11 @@ if [ ! -f "$ENGINE_STAMP" ] || [ "$ENGINE_VERSION" != `cat "$ENGINE_STAMP"` ]; t case "$(uname -s)" in Darwin) DART_ZIP_NAME="dart-sdk-darwin-x64.zip" + IS_USER_EXECUTABLE="-perm +100" ;; Linux) DART_ZIP_NAME="dart-sdk-linux-x64.zip" + IS_USER_EXECUTABLE="-perm /u+x" ;; *) echo "Unknown operating system. Cannot install Dart SDK." @@ -65,7 +67,7 @@ if [ ! -f "$ENGINE_STAMP" ] || [ "$ENGINE_VERSION" != `cat "$ENGINE_STAMP"` ]; t # install the new sdk rm -rf -- "$DART_SDK_PATH" - mkdir -p -- "$DART_SDK_PATH" + mkdir -m 755 -p -- "$DART_SDK_PATH" DART_SDK_ZIP="$FLUTTER_ROOT/bin/cache/$DART_ZIP_NAME" curl --continue-at - --location --output "$DART_SDK_ZIP" "$DART_SDK_URL" 2>&1 || { @@ -87,6 +89,8 @@ if [ ! -f "$ENGINE_STAMP" ] || [ "$ENGINE_VERSION" != `cat "$ENGINE_STAMP"` ]; t exit 1 } rm -f -- "$DART_SDK_ZIP" + find "$DART_SDK_PATH" -type d -exec chmod 755 {} \; + find "$DART_SDK_PATH" -type f $IS_USER_EXECUTABLE -exec chmod a+x,a+r {} \; echo "$ENGINE_VERSION" > "$ENGINE_STAMP" # delete any temporary sdk path diff --git a/dev/automated_tests/pubspec.yaml b/dev/automated_tests/pubspec.yaml index 0d472fa920..116f819896 100644 --- a/dev/automated_tests/pubspec.yaml +++ b/dev/automated_tests/pubspec.yaml @@ -11,7 +11,7 @@ dependencies: sdk: flutter test: 1.5.3 - analyzer: 0.35.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + analyzer: 0.35.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" args: 1.5.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" async: 2.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -20,16 +20,16 @@ dependencies: convert: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" crypto: 2.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.14.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - front_end: 0.1.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + front_end: 0.1.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" glob: 1.1.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - html: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + html: 0.13.4+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http: 0.12.0+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_multi_server: 2.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_parser: 3.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" io: 0.3.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" js: 0.6.1+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" json_rpc_2: 2.0.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - kernel: 0.3.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + kernel: 0.3.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" logging: 0.11.3+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" matcher: 0.12.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -37,9 +37,9 @@ dependencies: multi_server_socket: 1.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" node_preamble: 1.4.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" package_config: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - package_resolver: 1.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + package_resolver: 1.0.10 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path: 1.6.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - pedantic: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + pedantic: 1.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" plugin: 0.2.0+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pool: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pub_semver: 1.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -50,7 +50,7 @@ dependencies: shelf_web_socket: 0.2.2+4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" source_map_stack_trace: 1.1.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" source_maps: 0.10.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - source_span: 1.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + source_span: 1.5.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 1.6.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" string_scanner: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -68,4 +68,4 @@ dependencies: flutter: uses-material-design: true -# PUBSPEC CHECKSUM: 0823 +# PUBSPEC CHECKSUM: 9655 diff --git a/dev/benchmarks/complex_layout/lib/main.dart b/dev/benchmarks/complex_layout/lib/main.dart index c8ba78879b..2d349aea53 100644 --- a/dev/benchmarks/complex_layout/lib/main.dart +++ b/dev/benchmarks/complex_layout/lib/main.dart @@ -71,7 +71,7 @@ class TileScrollLayout extends StatelessWidget { child: IconBar(), ), ); - } + }, ), drawer: const GalleryDrawer(), ); @@ -101,8 +101,8 @@ class ComplexLayoutState extends State { print('Pressed search'); }, ), - TopBarMenu() - ] + TopBarMenu(), + ], ), body: Column( children: [ @@ -115,7 +115,7 @@ class ComplexLayoutState extends State { else return FancyGalleryItem(index, key: PageStorageKey(index)); }, - ) + ), ), BottomBar(), ], @@ -133,45 +133,45 @@ class TopBarMenu extends StatelessWidget { itemBuilder: (BuildContext context) => >[ const PopupMenuItem( value: 'Friends', - child: MenuItemWithIcon(Icons.people, 'Friends', '5 new') + child: MenuItemWithIcon(Icons.people, 'Friends', '5 new'), ), const PopupMenuItem( value: 'Events', - child: MenuItemWithIcon(Icons.event, 'Events', '12 upcoming') + child: MenuItemWithIcon(Icons.event, 'Events', '12 upcoming'), ), const PopupMenuItem( value: 'Events', - child: MenuItemWithIcon(Icons.group, 'Groups', '14') + child: MenuItemWithIcon(Icons.group, 'Groups', '14'), ), const PopupMenuItem( value: 'Events', - child: MenuItemWithIcon(Icons.image, 'Pictures', '12') + child: MenuItemWithIcon(Icons.image, 'Pictures', '12'), ), const PopupMenuItem( value: 'Events', - child: MenuItemWithIcon(Icons.near_me, 'Nearby', '33') + child: MenuItemWithIcon(Icons.near_me, 'Nearby', '33'), ), const PopupMenuItem( value: 'Friends', - child: MenuItemWithIcon(Icons.people, 'Friends', '5') + child: MenuItemWithIcon(Icons.people, 'Friends', '5'), ), const PopupMenuItem( value: 'Events', - child: MenuItemWithIcon(Icons.event, 'Events', '12') + child: MenuItemWithIcon(Icons.event, 'Events', '12'), ), const PopupMenuItem( value: 'Events', - child: MenuItemWithIcon(Icons.group, 'Groups', '14') + child: MenuItemWithIcon(Icons.group, 'Groups', '14'), ), const PopupMenuItem( value: 'Events', - child: MenuItemWithIcon(Icons.image, 'Pictures', '12') + child: MenuItemWithIcon(Icons.image, 'Pictures', '12'), ), const PopupMenuItem( value: 'Events', - child: MenuItemWithIcon(Icons.near_me, 'Nearby', '33') - ) - ] + child: MenuItemWithIcon(Icons.near_me, 'Nearby', '33'), + ), + ], ); } } @@ -190,10 +190,10 @@ class MenuItemWithIcon extends StatelessWidget { Icon(icon), Padding( padding: const EdgeInsets.only(left: 8.0, right: 8.0), - child: Text(title) + child: Text(title), ), - Text(subtitle, style: Theme.of(context).textTheme.caption) - ] + Text(subtitle, style: Theme.of(context).textTheme.caption), + ], ); } } @@ -213,11 +213,11 @@ class FancyImageItem extends StatelessWidget { InfoBar(), const Padding( padding: EdgeInsets.symmetric(horizontal: 8.0), - child: Divider() + child: Divider(), ), IconBar(), - FatDivider() - ] + FatDivider(), + ], ); } } @@ -235,11 +235,11 @@ class FancyGalleryItem extends StatelessWidget { InfoBar(), const Padding( padding: EdgeInsets.symmetric(horizontal: 8.0), - child: Divider() + child: Divider(), ), IconBar(), - FatDivider() - ] + FatDivider(), + ], ); } } @@ -253,9 +253,9 @@ class InfoBar extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const MiniIconWithText(Icons.thumb_up, '42'), - Text('3 Comments', style: Theme.of(context).textTheme.caption) - ] - ) + Text('3 Comments', style: Theme.of(context).textTheme.caption), + ], + ), ); } } @@ -271,8 +271,8 @@ class IconBar extends StatelessWidget { IconWithText(Icons.thumb_up, 'Like'), IconWithText(Icons.comment, 'Comment'), IconWithText(Icons.share, 'Share'), - ] - ) + ], + ), ); } } @@ -290,10 +290,10 @@ class IconWithText extends StatelessWidget { children: [ IconButton( icon: Icon(icon), - onPressed: () { print('Pressed $title button'); } + onPressed: () { print('Pressed $title button'); }, ), - Text(title) - ] + Text(title), + ], ); } } @@ -316,13 +316,13 @@ class MiniIconWithText extends StatelessWidget { height: 16.0, decoration: BoxDecoration( color: Theme.of(context).primaryColor, - shape: BoxShape.circle + shape: BoxShape.circle, ), - child: Icon(icon, color: Colors.white, size: 12.0) - ) + child: Icon(icon, color: Colors.white, size: 12.0), + ), ), - Text(title, style: Theme.of(context).textTheme.caption) - ] + Text(title, style: Theme.of(context).textTheme.caption), + ], ); } } @@ -354,8 +354,8 @@ class UserHeader extends StatelessWidget { child: Image( image: AssetImage('packages/flutter_gallery_assets/people/square/ali.png'), width: 32.0, - height: 32.0 - ) + height: 32.0, + ), ), Expanded( child: Column( @@ -367,21 +367,21 @@ class UserHeader extends StatelessWidget { children: [ TextSpan(text: userName, style: const TextStyle(fontWeight: FontWeight.bold)), const TextSpan(text: ' shared a new '), - const TextSpan(text: 'photo', style: TextStyle(fontWeight: FontWeight.bold)) - ] + const TextSpan(text: 'photo', style: TextStyle(fontWeight: FontWeight.bold)), + ], )), Row( children: [ Text('Yesterday at 11:55 • ', style: Theme.of(context).textTheme.caption), - Icon(Icons.people, size: 16.0, color: Theme.of(context).textTheme.caption.color) - ] - ) - ] - ) + Icon(Icons.people, size: 16.0, color: Theme.of(context).textTheme.caption.color), + ], + ), + ], + ), ), - TopBarMenu() - ] - ) + TopBarMenu(), + ], + ), ); } } @@ -391,7 +391,7 @@ class ItemDescription extends StatelessWidget { Widget build(BuildContext context) { return const Padding( padding: EdgeInsets.all(8.0), - child: Text('Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.') + child: Text('Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'), ); } } @@ -411,7 +411,7 @@ class ItemImageBox extends StatelessWidget { height: 230.0, child: Image( image: AssetImage('packages/flutter_gallery_assets/places/india_chettinad_silk_maker.png') - ) + ), ), Theme( data: ThemeData.dark(), @@ -420,14 +420,14 @@ class ItemImageBox extends StatelessWidget { children: [ IconButton( icon: const Icon(Icons.edit), - onPressed: () { print('Pressed edit button'); } + onPressed: () { print('Pressed edit button'); }, ), IconButton( icon: const Icon(Icons.zoom_in), - onPressed: () { print('Pressed zoom button'); } + onPressed: () { print('Pressed zoom button'); }, ), - ] - ) + ], + ), ), Positioned( bottom: 4.0, @@ -435,7 +435,7 @@ class ItemImageBox extends StatelessWidget { child: Container( decoration: BoxDecoration( color: Colors.black54, - borderRadius: BorderRadius.circular(2.0) + borderRadius: BorderRadius.circular(2.0), ), padding: const EdgeInsets.all(4.0), child: const RichText( @@ -447,14 +447,14 @@ class ItemImageBox extends StatelessWidget { ), TextSpan( style: TextStyle(fontWeight: FontWeight.bold), - text: 'Chris Godley' - ) - ] - ) - ) - ) - ) - ] + text: 'Chris Godley', + ), + ], + ), + ), + ), + ), + ], ) , Padding( @@ -464,13 +464,13 @@ class ItemImageBox extends StatelessWidget { children: [ Text('Artisans of Southern India', style: Theme.of(context).textTheme.body2), Text('Silk Spinners', style: Theme.of(context).textTheme.body1), - Text('Sivaganga, Tamil Nadu', style: Theme.of(context).textTheme.caption) - ] - ) - ) - ] - ) - ) + Text('Sivaganga, Tamil Nadu', style: Theme.of(context).textTheme.caption), + ], + ), + ), + ], + ), + ), ); } } @@ -483,7 +483,7 @@ class ItemGalleryBox extends StatelessWidget { @override Widget build(BuildContext context) { final List tabNames = [ - 'A', 'B', 'C', 'D' + 'A', 'B', 'C', 'D', ]; return SizedBox( @@ -507,8 +507,8 @@ class ItemGalleryBox extends StatelessWidget { color: Theme.of(context).primaryColor, child: Center( child: Text(tabName, style: Theme.of(context).textTheme.headline.copyWith(color: Colors.white)), - ) - ) + ), + ), ), Row( children: [ @@ -524,24 +524,24 @@ class ItemGalleryBox extends StatelessWidget { child: Padding( padding: const EdgeInsets.only(left: 8.0), child: Text('This is item $tabName'), - ) - ) - ] - ) - ] - ) - ) - ) + ), + ), + ], + ), + ], + ), + ), + ), ); - }).toList() - ) + }).toList(), + ), ), Container( - child: const TabPageSelector() - ) - ] - ) - ) + child: const TabPageSelector(), + ), + ], + ), + ), ); } } @@ -554,9 +554,9 @@ class BottomBar extends StatelessWidget { border: Border( top: BorderSide( color: Theme.of(context).dividerColor, - width: 1.0 - ) - ) + width: 1.0, + ), + ), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -586,11 +586,11 @@ class BottomBarButton extends StatelessWidget { children: [ IconButton( icon: Icon(icon), - onPressed: () { print('Pressed: $title'); } + onPressed: () { print('Pressed: $title'); }, ), - Text(title, style: Theme.of(context).textTheme.caption) - ] - ) + Text(title, style: Theme.of(context).textTheme.caption), + ], + ), ); } } @@ -625,7 +625,7 @@ class GalleryDrawer extends StatelessWidget { _changeScrollMode(context, currentMode == ScrollMode.complex ? ScrollMode.tile : ScrollMode.complex); Navigator.pop(context); }, - trailing: Text(currentMode == ScrollMode.complex ? 'Tile' : 'Complex') + trailing: Text(currentMode == ScrollMode.complex ? 'Tile' : 'Complex'), ), ListTile( leading: const Icon(Icons.brightness_5), @@ -635,7 +635,7 @@ class GalleryDrawer extends StatelessWidget { trailing: Radio( value: true, groupValue: ComplexLayoutApp.of(context).lightTheme, - onChanged: (bool value) { _changeTheme(context, value); } + onChanged: (bool value) { _changeTheme(context, value); }, ), ), ListTile( @@ -657,7 +657,7 @@ class GalleryDrawer extends StatelessWidget { onTap: () { ComplexLayoutApp.of(context).toggleAnimationSpeed(); }, trailing: Checkbox( value: timeDilation != 1.0, - onChanged: (bool value) { ComplexLayoutApp.of(context).toggleAnimationSpeed(); } + onChanged: (bool value) { ComplexLayoutApp.of(context).toggleAnimationSpeed(); }, ), ), ], diff --git a/dev/benchmarks/complex_layout/pubspec.yaml b/dev/benchmarks/complex_layout/pubspec.yaml index 35db9983b4..299ce115e7 100644 --- a/dev/benchmarks/complex_layout/pubspec.yaml +++ b/dev/benchmarks/complex_layout/pubspec.yaml @@ -15,7 +15,7 @@ dependencies: # //packages/flutter_tools/lib/src/commands/update_packages.dart # and run # flutter update-packages --force-upgrade - flutter_gallery_assets: 0.1.6 + flutter_gallery_assets: 0.1.8 async: 2.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -28,7 +28,7 @@ dependencies: meta: 1.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path: 1.6.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pub_semver: 1.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - source_span: 1.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + source_span: 1.5.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 1.6.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" term_glyph: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -42,27 +42,27 @@ dev_dependencies: sdk: flutter test: 1.5.3 - analyzer: 0.35.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + analyzer: 0.35.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" args: 1.5.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.14.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - front_end: 0.1.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + front_end: 0.1.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" glob: 1.1.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - html: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + html: 0.13.4+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http: 0.12.0+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_multi_server: 2.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_parser: 3.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" io: 0.3.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" js: 0.6.1+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - kernel: 0.3.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + kernel: 0.3.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" logging: 0.11.3+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" matcher: 0.12.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" mime: 0.9.6+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" multi_server_socket: 1.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" node_preamble: 1.4.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" package_config: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - package_resolver: 1.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - pedantic: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + package_resolver: 1.0.10 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + pedantic: 1.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" plugin: 0.2.0+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pool: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" quiver: 2.0.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -85,4 +85,4 @@ flutter: - packages/flutter_gallery_assets/people/square/ali.png - packages/flutter_gallery_assets/places/india_chettinad_silk_maker.png -# PUBSPEC CHECKSUM: 4ff3 +# PUBSPEC CHECKSUM: ca28 diff --git a/dev/benchmarks/macrobenchmarks/lib/common.dart b/dev/benchmarks/macrobenchmarks/lib/common.dart index e88a70800a..741920d712 100644 --- a/dev/benchmarks/macrobenchmarks/lib/common.dart +++ b/dev/benchmarks/macrobenchmarks/lib/common.dart @@ -1 +1,6 @@ +// Copyright 2015 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. + const String kCullOpacityRouteName = '/cull_opacity'; +const String kCubicBezierRouteName = '/cubic_bezier'; diff --git a/dev/benchmarks/macrobenchmarks/lib/main.dart b/dev/benchmarks/macrobenchmarks/lib/main.dart index c7a2778aa2..0b89ba0f5e 100644 --- a/dev/benchmarks/macrobenchmarks/lib/main.dart +++ b/dev/benchmarks/macrobenchmarks/lib/main.dart @@ -1,6 +1,11 @@ +// Copyright 2015 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 'package:flutter/material.dart'; import 'common.dart'; +import 'src/cubic_bezier.dart'; import 'src/cull_opacity.dart'; const String kMacrobenchmarks ='Macrobenchmarks'; @@ -16,6 +21,7 @@ class MacrobenchmarksApp extends StatelessWidget { routes: { '/': (BuildContext context) => HomePage(), kCullOpacityRouteName: (BuildContext context) => CullOpacityPage(), + kCubicBezierRouteName: (BuildContext context) => CubicBezierPage(), }, ); } @@ -34,7 +40,14 @@ class HomePage extends StatelessWidget { onPressed: (){ Navigator.pushNamed(context, kCullOpacityRouteName); }, - ) + ), + RaisedButton( + key: const Key(kCubicBezierRouteName), + child: const Text('Cubic Bezier'), + onPressed: (){ + Navigator.pushNamed(context, kCubicBezierRouteName); + }, + ), ], ), ); diff --git a/dev/benchmarks/macrobenchmarks/lib/src/cubic_bezier.dart b/dev/benchmarks/macrobenchmarks/lib/src/cubic_bezier.dart new file mode 100644 index 0000000000..a14b71cda8 --- /dev/null +++ b/dev/benchmarks/macrobenchmarks/lib/src/cubic_bezier.dart @@ -0,0 +1,380 @@ +// 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 'dart:math'; + +import 'package:flutter/widgets.dart'; +import 'package:flutter/animation.dart'; +import 'package:flutter/material.dart'; + +// Based on https://github.com/eseidelGoogle/bezier_perf/blob/master/lib/main.dart +class CubicBezierPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Bezier(Colors.amber, 1.0), + ], + ), + ); + } +} + +class Bezier extends StatelessWidget { + const Bezier(this.color, this.scale, {this.blur = 0.0, this.delay = 0.0}); + + final Color color; + final double scale; + final double blur; + final double delay; + + List _getLogoPath() { + final List paths = []; + + final Path path = Path(); + path.moveTo(100.0, 97.0); + path.cubicTo(100.0, 97.0, 142.0, 59.0, 169.91, 41.22); + path.cubicTo(197.82, 23.44, 249.24, 5.52, 204.67, 85.84); + + paths.add(PathDetail(path)); + + // Path 2 + final Path bezier2Path = Path(); + bezier2Path.moveTo(0.0, 70.55); + bezier2Path.cubicTo(0.0, 70.55, 42.0, 31.55, 69.91, 14.77); + bezier2Path.cubicTo(97.82, -2.01, 149.24, -20.93, 104.37, 59.39); + + paths.add(PathDetail(bezier2Path, + translate: [29.45, 151.0], rotation: -1.5708)); + + // Path 3 + final Path bezier3Path = Path(); + bezier3Path.moveTo(0.0, 69.48); + bezier3Path.cubicTo(0.0, 69.48, 44.82, 27.92, 69.91, 13.7); + bezier3Path.cubicTo(95.0, -0.52, 149.24, -22.0, 104.37, 58.32); + + paths.add(PathDetail(bezier3Path, + translate: [53.0, 200.48], rotation: -3.14159)); + + // Path 4 + final Path bezier4Path = Path(); + bezier4Path.moveTo(0.0, 69.48); + bezier4Path.cubicTo(0.0, 69.48, 43.82, 27.92, 69.91, 13.7); + bezier4Path.cubicTo(96.0, -0.52, 149.24, -22.0, 104.37, 58.32); + + paths.add(PathDetail(bezier4Path, + translate: [122.48, 77.0], rotation: -4.71239)); + + return paths; + } + + @override + Widget build(BuildContext context) { + return Stack(children: [ + CustomPaint( + foregroundPainter: + BezierPainter(Colors.grey, 0.0, _getLogoPath(), false), + size: const Size(100.0, 100.0), + ), + AnimatedBezier(color, scale, blur: blur, delay: delay), + ]); + } +} + +class PathDetail { + PathDetail(this.path, {this.translate, this.rotation}); + + Path path; + List translate = []; + double rotation; +} + +class AnimatedBezier extends StatefulWidget { + const AnimatedBezier(this.color, this.scale, {this.blur = 0.0, this.delay}); + + final Color color; + final double scale; + final double blur; + final double delay; + + @override + State createState() => AnimatedBezierState(); +} + +class Point { + Point(this.x, this.y); + + double x; + double y; +} + +class AnimatedBezierState extends State + with SingleTickerProviderStateMixin { + double scale; + AnimationController controller; + CurvedAnimation curve; + bool isPlaying = false; + List> pointList = >[] + ..add([]) + ..add([]) + ..add([]) + ..add([]); + bool isReversed = false; + + List _playForward() { + final List paths = []; + final double t = curve.value; + final double b = controller.upperBound; + double pX; + double pY; + + final Path path = Path(); + + if (t < b / 2) { + pX = _getCubicPoint(t * 2, 100.0, 100.0, 142.0, 169.91); + pY = _getCubicPoint(t * 2, 97.0, 97.0, 59.0, 41.22); + pointList[0].add(Point(pX, pY)); + } else { + pX = _getCubicPoint(t * 2 - b, 169.91, 197.80, 249.24, 204.67); + pY = _getCubicPoint(t * 2 - b, 41.22, 23.44, 5.52, 85.84); + pointList[0].add(Point(pX, pY)); + } + + path.moveTo(100.0, 97.0); + + for (Point p in pointList[0]) { + path.lineTo(p.x, p.y); + } + + paths.add(PathDetail(path)); + + // Path 2 + final Path bezier2Path = Path(); + + if (t <= b / 2) { + final double pX = _getCubicPoint(t * 2, 0.0, 0.0, 42.0, 69.91); + final double pY = _getCubicPoint(t * 2, 70.55, 70.55, 31.55, 14.77); + pointList[1].add(Point(pX, pY)); + } else { + final double pX = _getCubicPoint(t * 2 - b, 69.91, 97.82, 149.24, 104.37); + final double pY = _getCubicPoint(t * 2 - b, 14.77, -2.01, -20.93, 59.39); + pointList[1].add(Point(pX, pY)); + } + + bezier2Path.moveTo(0.0, 70.55); + + for (Point p in pointList[1]) { + bezier2Path.lineTo(p.x, p.y); + } + + paths.add(PathDetail(bezier2Path, + translate: [29.45, 151.0], rotation: -1.5708)); + + // Path 3 + final Path bezier3Path = Path(); + if (t <= b / 2) { + pX = _getCubicPoint(t * 2, 0.0, 0.0, 44.82, 69.91); + pY = _getCubicPoint(t * 2, 69.48, 69.48, 27.92, 13.7); + pointList[2].add(Point(pX, pY)); + } else { + pX = _getCubicPoint(t * 2 - b, 69.91, 95.0, 149.24, 104.37); + pY = _getCubicPoint(t * 2 - b, 13.7, -0.52, -22.0, 58.32); + pointList[2].add(Point(pX, pY)); + } + + bezier3Path.moveTo(0.0, 69.48); + + for (Point p in pointList[2]) { + bezier3Path.lineTo(p.x, p.y); + } + + paths.add(PathDetail(bezier3Path, + translate: [53.0, 200.48], rotation: -3.14159)); + + // Path 4 + final Path bezier4Path = Path(); + + if (t < b / 2) { + final double pX = _getCubicPoint(t * 2, 0.0, 0.0, 43.82, 69.91); + final double pY = _getCubicPoint(t * 2, 69.48, 69.48, 27.92, 13.7); + pointList[3].add(Point(pX, pY)); + } else { + final double pX = _getCubicPoint(t * 2 - b, 69.91, 96.0, 149.24, 104.37); + final double pY = _getCubicPoint(t * 2 - b, 13.7, -0.52, -22.0, 58.32); + pointList[3].add(Point(pX, pY)); + } + + bezier4Path.moveTo(0.0, 69.48); + + for (Point p in pointList[3]) { + bezier4Path.lineTo(p.x, p.y); + } + + paths.add(PathDetail(bezier4Path, + translate: [122.48, 77.0], rotation: -4.71239)); + + return paths; + } + + List _playReversed() { + for (List list in pointList) { + if (list.isNotEmpty) { + list.removeLast(); + } + } + + final List points = pointList[0]; + final Path path = Path(); + + path.moveTo(100.0, 97.0); + + for (Point point in points) { + path.lineTo(point.x, point.y); + } + + final Path bezier2Path = Path(); + + bezier2Path.moveTo(0.0, 70.55); + + for (Point p in pointList[1]) { + bezier2Path.lineTo(p.x, p.y); + } + + final Path bezier3Path = Path(); + bezier3Path.moveTo(0.0, 69.48); + + for (Point p in pointList[2]) { + bezier3Path.lineTo(p.x, p.y); + } + + final Path bezier4Path = Path(); + + bezier4Path.moveTo(0.0, 69.48); + + for (Point p in pointList[3]) { + bezier4Path.lineTo(p.x, p.y); + } + + return [ + PathDetail(path), + PathDetail(bezier2Path, translate: [29.45, 151.0], rotation: -1.5708), + PathDetail(bezier3Path, + translate: [53.0, 200.48], rotation: -3.14159), + PathDetail(bezier4Path, translate: [122.48, 77.0], rotation: -4.71239), + ]; + } + + List _getLogoPath() { + if (!isReversed) { + return _playForward(); + } + + return _playReversed(); + } + + //From http://wiki.roblox.com/index.php?title=File:Beziereq4.png + double _getCubicPoint(double t, double p0, double p1, double p2, double p3) { + return pow(1 - t, 3) * p0 + + 3 * pow(1 - t, 2) * t * p1 + + 3 * (1 - t) * pow(t, 2) * p2 + + pow(t, 3) * p3; + } + + void playAnimation() { + isPlaying = true; + isReversed = false; + for (List list in pointList) { + list.clear(); + } + controller.reset(); + controller.forward(); + } + + void stopAnimation() { + isPlaying = false; + controller.stop(); + for (List list in pointList) { + list.clear(); + } + } + + void reverseAnimation() { + isReversed = true; + controller.reverse(); + } + + @override + void initState() { + super.initState(); + controller = AnimationController( + vsync: this, duration: const Duration(milliseconds: 1000)); + curve = CurvedAnimation(parent: controller, curve: Curves.linear) + ..addListener(() { + setState(() {}); + }) + ..addStatusListener((AnimationStatus state) { + if (state == AnimationStatus.completed) { + reverseAnimation(); + } else if (state == AnimationStatus.dismissed) { + playAnimation(); + } + }); + + playAnimation(); + } + + @override + Widget build(BuildContext context) { + return CustomPaint( + foregroundPainter: BezierPainter(widget.color, + curve.value * widget.blur, _getLogoPath(), isPlaying), + size: const Size(100.0, 100.0)); + } +} + +class BezierPainter extends CustomPainter { + BezierPainter(this.color, this.blur, this.path, this.isPlaying); + + Color color; + final double blur; + List path; + bool isPlaying; + + @override + void paint(Canvas canvas, Size size) { + final Paint paint = Paint(); + paint.strokeWidth = 18.0; + paint.style = PaintingStyle.stroke; + paint.strokeCap = StrokeCap.round; + paint.color = color; + canvas.scale(0.5, 0.5); + + for (int i = 0; i < path.length; i++) { + if (path[i].translate != null) { + canvas.translate(path[i].translate[0], path[i].translate[1]); + } + + if (path[i].rotation != null) { + canvas.rotate(path[i].rotation); + } + + if (blur > 0) { + final MaskFilter blur = MaskFilter.blur(BlurStyle.normal, this.blur); + paint.maskFilter = blur; + canvas.drawPath(path[i].path, paint); + } + + paint.maskFilter = null; + canvas.drawPath(path[i].path, paint); + } + } + + @override + bool shouldRepaint(BezierPainter oldDelegate) => true; + + @override + bool shouldRebuildSemantics(BezierPainter oldDelegate) => false; +} diff --git a/dev/benchmarks/macrobenchmarks/pubspec.yaml b/dev/benchmarks/macrobenchmarks/pubspec.yaml index e58c5d3272..efa702c596 100644 --- a/dev/benchmarks/macrobenchmarks/pubspec.yaml +++ b/dev/benchmarks/macrobenchmarks/pubspec.yaml @@ -15,7 +15,7 @@ dependencies: # //packages/flutter_tools/lib/src/commands/update_packages.dart # and run # flutter update-packages --force-upgrade - flutter_gallery_assets: 0.1.6 + flutter_gallery_assets: 0.1.8 async: 2.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -28,7 +28,7 @@ dependencies: meta: 1.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path: 1.6.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pub_semver: 1.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - source_span: 1.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + source_span: 1.5.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 1.6.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" term_glyph: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -42,27 +42,27 @@ dev_dependencies: sdk: flutter test: 1.5.3 - analyzer: 0.35.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + analyzer: 0.35.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" args: 1.5.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.14.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - front_end: 0.1.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + front_end: 0.1.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" glob: 1.1.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - html: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + html: 0.13.4+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http: 0.12.0+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_multi_server: 2.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_parser: 3.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" io: 0.3.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" js: 0.6.1+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - kernel: 0.3.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + kernel: 0.3.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" logging: 0.11.3+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" matcher: 0.12.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" mime: 0.9.6+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" multi_server_socket: 1.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" node_preamble: 1.4.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" package_config: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - package_resolver: 1.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - pedantic: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + package_resolver: 1.0.10 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + pedantic: 1.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" plugin: 0.2.0+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pool: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" quiver: 2.0.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -82,4 +82,4 @@ dev_dependencies: flutter: uses-material-design: true -# PUBSPEC CHECKSUM: 4ff3 +# PUBSPEC CHECKSUM: ca28 diff --git a/dev/benchmarks/macrobenchmarks/test_driver/cubic_bezier_perf.dart b/dev/benchmarks/macrobenchmarks/test_driver/cubic_bezier_perf.dart new file mode 100644 index 0000000000..3dae64149b --- /dev/null +++ b/dev/benchmarks/macrobenchmarks/test_driver/cubic_bezier_perf.dart @@ -0,0 +1,40 @@ +// 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 'dart:ui'; + +import 'package:flutter_driver/driver_extension.dart'; +import 'package:flutter/painting.dart' show DefaultShaderWarmUp, PaintingBinding; +import 'package:macrobenchmarks/main.dart' as app; + +class CubicBezierShaderWarmUp extends DefaultShaderWarmUp { + @override + Future warmUpOnCanvas(Canvas canvas) async { + await super.warmUpOnCanvas(canvas); + + // Warm up the cubic shaders used by CubicBezierPage. + // + // This tests that our custom shader warm up is working properly. + // Without this custom shader warm up, the worst frame time is about 115ms. + // With this, the worst frame time is about 70ms. (Data collected on a Moto + // G4 based on Flutter version 704814c67a874077710524d30412337884bf0254. + final Path path = Path(); + path.moveTo(20.0, 20.0); + // This cubic path is based on + // https://skia.org/user/api/SkPath_Reference#SkPath_cubicTo + path.cubicTo(300.0, 80.0, -140.0, 90.0, 220.0, 10.0); + final Paint paint = Paint(); + paint.isAntiAlias = true; + paint.strokeWidth = 18.0; + paint.style = PaintingStyle.stroke; + paint.strokeCap = StrokeCap.round; + canvas.drawPath(path, paint); + } +} + +void main() { + PaintingBinding.shaderWarmUp = CubicBezierShaderWarmUp(); + enableFlutterDriverExtension(); + app.main(); +} diff --git a/dev/benchmarks/macrobenchmarks/test_driver/cubic_bezier_perf_test.dart b/dev/benchmarks/macrobenchmarks/test_driver/cubic_bezier_perf_test.dart new file mode 100644 index 0000000000..3ead8877d7 --- /dev/null +++ b/dev/benchmarks/macrobenchmarks/test_driver/cubic_bezier_perf_test.dart @@ -0,0 +1,11 @@ +// 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 'package:macrobenchmarks/common.dart'; + +import 'util.dart'; + +void main() { + macroPerfTest('cubic_bezier_perf', kCubicBezierRouteName); +} diff --git a/dev/benchmarks/macrobenchmarks/test_driver/cull_opacity_perf_test.dart b/dev/benchmarks/macrobenchmarks/test_driver/cull_opacity_perf_test.dart index 6493a1abad..951f50c950 100644 --- a/dev/benchmarks/macrobenchmarks/test_driver/cull_opacity_perf_test.dart +++ b/dev/benchmarks/macrobenchmarks/test_driver/cull_opacity_perf_test.dart @@ -2,42 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:async'; - -import 'package:flutter_driver/flutter_driver.dart'; -import 'package:test/test.dart' hide TypeMatcher, isInstanceOf; - import 'package:macrobenchmarks/common.dart'; +import 'util.dart'; + void main() { - const String kName = 'cull_opacity_perf'; - - test(kName, () async { - final FlutterDriver driver = await FlutterDriver.connect(); - - // The slight initial delay avoids starting the timing during a - // period of increased load on the device. Without this delay, the - // benchmark has greater noise. - // See: https://github.com/flutter/flutter/issues/19434 - await Future.delayed(const Duration(milliseconds: 250)); - - await driver.forceGC(); - - final SerializableFinder button = find.byValueKey(kCullOpacityRouteName); - expect(button, isNotNull); - await driver.tap(button); - - // Wait for the page to load - await Future.delayed(const Duration(seconds: 1)); - - final Timeline timeline = await driver.traceAction(() async { - await Future.delayed(const Duration(seconds: 10)); - }); - - final TimelineSummary summary = TimelineSummary.summarize(timeline); - summary.writeSummaryToFile(kName, pretty: true); - summary.writeTimelineToFile(kName, pretty: true); - - driver.close(); - }); + macroPerfTest( + 'cull_opacity_perf', + kCullOpacityRouteName, + pageDelay: const Duration(seconds: 1), + duration: const Duration(seconds: 10), + ); } diff --git a/dev/benchmarks/macrobenchmarks/test_driver/util.dart b/dev/benchmarks/macrobenchmarks/test_driver/util.dart new file mode 100644 index 0000000000..79fe4f1a66 --- /dev/null +++ b/dev/benchmarks/macrobenchmarks/test_driver/util.dart @@ -0,0 +1,44 @@ +// 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 'dart:async'; + +import 'package:flutter_driver/flutter_driver.dart'; +import 'package:test/test.dart' hide TypeMatcher, isInstanceOf; + +void macroPerfTest( + String testName, + String routeName, + {Duration pageDelay, Duration duration = const Duration(seconds: 3)}) { + test(testName, () async { + final FlutterDriver driver = await FlutterDriver.connect(); + + // The slight initial delay avoids starting the timing during a + // period of increased load on the device. Without this delay, the + // benchmark has greater noise. + // See: https://github.com/flutter/flutter/issues/19434 + await Future.delayed(const Duration(milliseconds: 250)); + + await driver.forceGC(); + + final SerializableFinder button = find.byValueKey(routeName); + expect(button, isNotNull); + await driver.tap(button); + + if (pageDelay != null) { + // Wait for the page to load + await Future.delayed(pageDelay); + } + + final Timeline timeline = await driver.traceAction(() async { + await Future.delayed(duration); + }); + + final TimelineSummary summary = TimelineSummary.summarize(timeline); + summary.writeSummaryToFile(testName, pretty: true); + summary.writeTimelineToFile(testName, pretty: true); + + driver.close(); + }); +} diff --git a/dev/benchmarks/microbenchmarks/lib/gestures/data/velocity_tracker_data.dart b/dev/benchmarks/microbenchmarks/lib/gestures/data/velocity_tracker_data.dart index 4cd9ff974e..b0b1485f39 100644 --- a/dev/benchmarks/microbenchmarks/lib/gestures/data/velocity_tracker_data.dart +++ b/dev/benchmarks/microbenchmarks/lib/gestures/data/velocity_tracker_data.dart @@ -9,1531 +9,1531 @@ final List velocityEventData = [ const PointerDownEvent( timeStamp: Duration(milliseconds: 216690896), pointer: 1, - position: Offset(270.0, 538.2857055664062) + position: Offset(270.0, 538.2857055664062), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216690906), pointer: 1, - position: Offset(270.0, 538.2857055664062) + position: Offset(270.0, 538.2857055664062), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216690951), pointer: 1, - position: Offset(270.0, 530.8571166992188) + position: Offset(270.0, 530.8571166992188), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216690959), pointer: 1, - position: Offset(270.0, 526.8571166992188) + position: Offset(270.0, 526.8571166992188), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216690967), pointer: 1, - position: Offset(270.0, 521.4285888671875) + position: Offset(270.0, 521.4285888671875), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216690975), pointer: 1, - position: Offset(270.0, 515.4285888671875) + position: Offset(270.0, 515.4285888671875), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216690983), pointer: 1, - position: Offset(270.0, 506.8571472167969) + position: Offset(270.0, 506.8571472167969), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216690991), pointer: 1, - position: Offset(268.8571472167969, 496.0) + position: Offset(268.8571472167969, 496.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216690998), pointer: 1, - position: Offset(267.4285583496094, 483.1428527832031) + position: Offset(267.4285583496094, 483.1428527832031), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691006), pointer: 1, - position: Offset(266.28570556640625, 469.71429443359375) + position: Offset(266.28570556640625, 469.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691014), pointer: 1, - position: Offset(265.4285583496094, 456.8571472167969) + position: Offset(265.4285583496094, 456.8571472167969), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691021), pointer: 1, - position: Offset(264.28570556640625, 443.71429443359375) + position: Offset(264.28570556640625, 443.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691029), pointer: 1, - position: Offset(264.0, 431.71429443359375) + position: Offset(264.0, 431.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691036), pointer: 1, - position: Offset(263.4285583496094, 421.1428527832031) + position: Offset(263.4285583496094, 421.1428527832031), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691044), pointer: 1, - position: Offset(263.4285583496094, 412.5714416503906) + position: Offset(263.4285583496094, 412.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691052), pointer: 1, - position: Offset(263.4285583496094, 404.5714416503906) + position: Offset(263.4285583496094, 404.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691060), pointer: 1, - position: Offset(263.4285583496094, 396.5714416503906) + position: Offset(263.4285583496094, 396.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691068), pointer: 1, - position: Offset(264.5714416503906, 390.0) + position: Offset(264.5714416503906, 390.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691075), pointer: 1, - position: Offset(265.1428527832031, 384.8571472167969) + position: Offset(265.1428527832031, 384.8571472167969), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691083), pointer: 1, - position: Offset(266.0, 380.28570556640625) + position: Offset(266.0, 380.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691091), pointer: 1, - position: Offset(266.5714416503906, 376.28570556640625) + position: Offset(266.5714416503906, 376.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691098), pointer: 1, - position: Offset(267.1428527832031, 373.1428527832031) + position: Offset(267.1428527832031, 373.1428527832031), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691106), pointer: 1, - position: Offset(267.71429443359375, 370.28570556640625) + position: Offset(267.71429443359375, 370.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691114), pointer: 1, - position: Offset(268.28570556640625, 367.71429443359375) + position: Offset(268.28570556640625, 367.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691121), pointer: 1, - position: Offset(268.5714416503906, 366.0) + position: Offset(268.5714416503906, 366.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691130), pointer: 1, - position: Offset(268.8571472167969, 364.5714416503906) + position: Offset(268.8571472167969, 364.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691137), pointer: 1, - position: Offset(269.1428527832031, 363.71429443359375) + position: Offset(269.1428527832031, 363.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691145), pointer: 1, - position: Offset(269.1428527832031, 362.8571472167969) + position: Offset(269.1428527832031, 362.8571472167969), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691153), pointer: 1, - position: Offset(269.4285583496094, 362.8571472167969) + position: Offset(269.4285583496094, 362.8571472167969), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691168), pointer: 1, - position: Offset(268.5714416503906, 365.4285583496094) + position: Offset(268.5714416503906, 365.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691176), pointer: 1, - position: Offset(267.1428527832031, 370.28570556640625) + position: Offset(267.1428527832031, 370.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691183), pointer: 1, - position: Offset(265.4285583496094, 376.8571472167969) + position: Offset(265.4285583496094, 376.8571472167969), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691191), pointer: 1, - position: Offset(263.1428527832031, 385.71429443359375) + position: Offset(263.1428527832031, 385.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691199), pointer: 1, - position: Offset(261.4285583496094, 396.5714416503906) + position: Offset(261.4285583496094, 396.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691207), pointer: 1, - position: Offset(259.71429443359375, 408.5714416503906) + position: Offset(259.71429443359375, 408.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691215), pointer: 1, - position: Offset(258.28570556640625, 419.4285583496094) + position: Offset(258.28570556640625, 419.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691222), pointer: 1, - position: Offset(257.4285583496094, 428.5714416503906) + position: Offset(257.4285583496094, 428.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691230), pointer: 1, - position: Offset(256.28570556640625, 436.0) + position: Offset(256.28570556640625, 436.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691238), pointer: 1, - position: Offset(255.7142791748047, 442.0) + position: Offset(255.7142791748047, 442.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691245), pointer: 1, - position: Offset(255.14285278320312, 447.71429443359375) + position: Offset(255.14285278320312, 447.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691253), pointer: 1, - position: Offset(254.85714721679688, 453.1428527832031) + position: Offset(254.85714721679688, 453.1428527832031), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691261), pointer: 1, - position: Offset(254.57142639160156, 458.5714416503906) + position: Offset(254.57142639160156, 458.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691268), pointer: 1, - position: Offset(254.2857208251953, 463.71429443359375) + position: Offset(254.2857208251953, 463.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691276), pointer: 1, - position: Offset(254.2857208251953, 470.28570556640625) + position: Offset(254.2857208251953, 470.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691284), pointer: 1, - position: Offset(254.2857208251953, 477.71429443359375) + position: Offset(254.2857208251953, 477.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691292), pointer: 1, - position: Offset(255.7142791748047, 487.1428527832031) + position: Offset(255.7142791748047, 487.1428527832031), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691300), pointer: 1, - position: Offset(256.8571472167969, 498.5714416503906) + position: Offset(256.8571472167969, 498.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691307), pointer: 1, - position: Offset(258.28570556640625, 507.71429443359375) + position: Offset(258.28570556640625, 507.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691315), pointer: 1, - position: Offset(259.4285583496094, 516.0) + position: Offset(259.4285583496094, 516.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691323), pointer: 1, - position: Offset(260.28570556640625, 521.7142944335938) + position: Offset(260.28570556640625, 521.7142944335938), ), const PointerUpEvent( timeStamp: Duration(milliseconds: 216691338), pointer: 1, - position: Offset(260.28570556640625, 521.7142944335938) + position: Offset(260.28570556640625, 521.7142944335938), ), const PointerDownEvent( timeStamp: Duration(milliseconds: 216691573), pointer: 2, - position: Offset(266.0, 327.4285583496094) + position: Offset(266.0, 327.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691588), pointer: 2, - position: Offset(266.0, 327.4285583496094) + position: Offset(266.0, 327.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691626), pointer: 2, - position: Offset(261.1428527832031, 337.1428527832031) + position: Offset(261.1428527832031, 337.1428527832031), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691634), pointer: 2, - position: Offset(258.28570556640625, 343.1428527832031) + position: Offset(258.28570556640625, 343.1428527832031), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691642), pointer: 2, - position: Offset(254.57142639160156, 354.0) + position: Offset(254.57142639160156, 354.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691650), pointer: 2, - position: Offset(250.2857208251953, 368.28570556640625) + position: Offset(250.2857208251953, 368.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691657), pointer: 2, - position: Offset(247.42857360839844, 382.8571472167969) + position: Offset(247.42857360839844, 382.8571472167969), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691665), pointer: 2, - position: Offset(245.14285278320312, 397.4285583496094) + position: Offset(245.14285278320312, 397.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691673), pointer: 2, - position: Offset(243.14285278320312, 411.71429443359375) + position: Offset(243.14285278320312, 411.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691680), pointer: 2, - position: Offset(242.2857208251953, 426.28570556640625) + position: Offset(242.2857208251953, 426.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691688), pointer: 2, - position: Offset(241.7142791748047, 440.5714416503906) + position: Offset(241.7142791748047, 440.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691696), pointer: 2, - position: Offset(241.7142791748047, 454.5714416503906) + position: Offset(241.7142791748047, 454.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691703), pointer: 2, - position: Offset(242.57142639160156, 467.71429443359375) + position: Offset(242.57142639160156, 467.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691712), pointer: 2, - position: Offset(243.42857360839844, 477.4285583496094) + position: Offset(243.42857360839844, 477.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691720), pointer: 2, - position: Offset(244.85714721679688, 485.71429443359375) + position: Offset(244.85714721679688, 485.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691727), pointer: 2, - position: Offset(246.2857208251953, 493.1428527832031) + position: Offset(246.2857208251953, 493.1428527832031), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216691735), pointer: 2, - position: Offset(248.0, 499.71429443359375) + position: Offset(248.0, 499.71429443359375), ), const PointerUpEvent( timeStamp: Duration(milliseconds: 216691750), pointer: 2, - position: Offset(248.0, 499.71429443359375) + position: Offset(248.0, 499.71429443359375), ), const PointerDownEvent( timeStamp: Duration(milliseconds: 216692255), pointer: 3, - position: Offset(249.42857360839844, 351.4285583496094) + position: Offset(249.42857360839844, 351.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692270), pointer: 3, - position: Offset(249.42857360839844, 351.4285583496094) + position: Offset(249.42857360839844, 351.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692309), pointer: 3, - position: Offset(246.2857208251953, 361.71429443359375) + position: Offset(246.2857208251953, 361.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692317), pointer: 3, - position: Offset(244.0, 368.5714416503906) + position: Offset(244.0, 368.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692325), pointer: 3, - position: Offset(241.42857360839844, 377.71429443359375) + position: Offset(241.42857360839844, 377.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692333), pointer: 3, - position: Offset(237.7142791748047, 391.71429443359375) + position: Offset(237.7142791748047, 391.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692340), pointer: 3, - position: Offset(235.14285278320312, 406.5714416503906) + position: Offset(235.14285278320312, 406.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692348), pointer: 3, - position: Offset(232.57142639160156, 421.4285583496094) + position: Offset(232.57142639160156, 421.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692356), pointer: 3, - position: Offset(230.2857208251953, 436.5714416503906) + position: Offset(230.2857208251953, 436.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692363), pointer: 3, - position: Offset(228.2857208251953, 451.71429443359375) + position: Offset(228.2857208251953, 451.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692371), pointer: 3, - position: Offset(227.42857360839844, 466.0) + position: Offset(227.42857360839844, 466.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692378), pointer: 3, - position: Offset(226.2857208251953, 479.71429443359375) + position: Offset(226.2857208251953, 479.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692387), pointer: 3, - position: Offset(225.7142791748047, 491.71429443359375) + position: Offset(225.7142791748047, 491.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692395), pointer: 3, - position: Offset(225.14285278320312, 501.71429443359375) + position: Offset(225.14285278320312, 501.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692402), pointer: 3, - position: Offset(224.85714721679688, 509.1428527832031) + position: Offset(224.85714721679688, 509.1428527832031), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692410), pointer: 3, - position: Offset(224.57142639160156, 514.8571166992188) + position: Offset(224.57142639160156, 514.8571166992188), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692418), pointer: 3, - position: Offset(224.2857208251953, 519.4285888671875) + position: Offset(224.2857208251953, 519.4285888671875), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692425), pointer: 3, - position: Offset(224.0, 523.4285888671875) + position: Offset(224.0, 523.4285888671875), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692433), pointer: 3, - position: Offset(224.0, 527.1428833007812) + position: Offset(224.0, 527.1428833007812), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692441), pointer: 3, - position: Offset(224.0, 530.5714111328125) + position: Offset(224.0, 530.5714111328125), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692448), pointer: 3, - position: Offset(224.0, 533.1428833007812) + position: Offset(224.0, 533.1428833007812), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692456), pointer: 3, - position: Offset(224.0, 535.4285888671875) + position: Offset(224.0, 535.4285888671875), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692464), pointer: 3, - position: Offset(223.7142791748047, 536.8571166992188) + position: Offset(223.7142791748047, 536.8571166992188), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692472), pointer: 3, - position: Offset(223.7142791748047, 538.2857055664062) + position: Offset(223.7142791748047, 538.2857055664062), ), const PointerUpEvent( timeStamp: Duration(milliseconds: 216692487), pointer: 3, - position: Offset(223.7142791748047, 538.2857055664062) + position: Offset(223.7142791748047, 538.2857055664062), ), const PointerDownEvent( timeStamp: Duration(milliseconds: 216692678), pointer: 4, - position: Offset(221.42857360839844, 526.2857055664062) + position: Offset(221.42857360839844, 526.2857055664062), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692701), pointer: 4, - position: Offset(220.57142639160156, 514.8571166992188) + position: Offset(220.57142639160156, 514.8571166992188), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692708), pointer: 4, - position: Offset(220.2857208251953, 508.0) + position: Offset(220.2857208251953, 508.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692716), pointer: 4, - position: Offset(220.2857208251953, 498.0) + position: Offset(220.2857208251953, 498.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692724), pointer: 4, - position: Offset(221.14285278320312, 484.28570556640625) + position: Offset(221.14285278320312, 484.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692732), pointer: 4, - position: Offset(221.7142791748047, 469.4285583496094) + position: Offset(221.7142791748047, 469.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692740), pointer: 4, - position: Offset(223.42857360839844, 453.1428527832031) + position: Offset(223.42857360839844, 453.1428527832031), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692748), pointer: 4, - position: Offset(225.7142791748047, 436.28570556640625) + position: Offset(225.7142791748047, 436.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692755), pointer: 4, - position: Offset(229.14285278320312, 418.28570556640625) + position: Offset(229.14285278320312, 418.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692763), pointer: 4, - position: Offset(232.85714721679688, 400.28570556640625) + position: Offset(232.85714721679688, 400.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692770), pointer: 4, - position: Offset(236.85714721679688, 382.5714416503906) + position: Offset(236.85714721679688, 382.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692778), pointer: 4, - position: Offset(241.14285278320312, 366.0) + position: Offset(241.14285278320312, 366.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692786), pointer: 4, - position: Offset(244.85714721679688, 350.28570556640625) + position: Offset(244.85714721679688, 350.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216692793), pointer: 4, - position: Offset(249.14285278320312, 335.4285583496094) + position: Offset(249.14285278320312, 335.4285583496094), ), const PointerUpEvent( timeStamp: Duration(milliseconds: 216692809), pointer: 4, - position: Offset(249.14285278320312, 335.4285583496094) + position: Offset(249.14285278320312, 335.4285583496094), ), const PointerDownEvent( timeStamp: Duration(milliseconds: 216693222), pointer: 5, - position: Offset(224.0, 545.4285888671875) + position: Offset(224.0, 545.4285888671875), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216693245), pointer: 5, - position: Offset(224.0, 545.4285888671875) + position: Offset(224.0, 545.4285888671875), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216693275), pointer: 5, - position: Offset(222.85714721679688, 535.1428833007812) + position: Offset(222.85714721679688, 535.1428833007812), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216693284), pointer: 5, - position: Offset(222.85714721679688, 528.8571166992188) + position: Offset(222.85714721679688, 528.8571166992188), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216693291), pointer: 5, - position: Offset(222.2857208251953, 518.5714111328125) + position: Offset(222.2857208251953, 518.5714111328125), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216693299), pointer: 5, - position: Offset(222.0, 503.4285583496094) + position: Offset(222.0, 503.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216693307), pointer: 5, - position: Offset(222.0, 485.4285583496094) + position: Offset(222.0, 485.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216693314), pointer: 5, - position: Offset(221.7142791748047, 464.0) + position: Offset(221.7142791748047, 464.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216693322), pointer: 5, - position: Offset(222.2857208251953, 440.28570556640625) + position: Offset(222.2857208251953, 440.28570556640625), ), const PointerUpEvent( timeStamp: Duration(milliseconds: 216693337), pointer: 5, - position: Offset(222.2857208251953, 440.28570556640625) + position: Offset(222.2857208251953, 440.28570556640625), ), const PointerDownEvent( timeStamp: Duration(milliseconds: 216693985), pointer: 6, - position: Offset(208.0, 544.0) + position: Offset(208.0, 544.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694047), pointer: 6, - position: Offset(208.57142639160156, 532.2857055664062) + position: Offset(208.57142639160156, 532.2857055664062), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694054), pointer: 6, - position: Offset(208.85714721679688, 525.7142944335938) + position: Offset(208.85714721679688, 525.7142944335938), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694062), pointer: 6, - position: Offset(208.85714721679688, 515.1428833007812) + position: Offset(208.85714721679688, 515.1428833007812), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694070), pointer: 6, - position: Offset(208.0, 501.4285583496094) + position: Offset(208.0, 501.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694077), pointer: 6, - position: Offset(207.42857360839844, 487.1428527832031) + position: Offset(207.42857360839844, 487.1428527832031), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694085), pointer: 6, - position: Offset(206.57142639160156, 472.8571472167969) + position: Offset(206.57142639160156, 472.8571472167969), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694092), pointer: 6, - position: Offset(206.57142639160156, 458.8571472167969) + position: Offset(206.57142639160156, 458.8571472167969), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694100), pointer: 6, - position: Offset(206.57142639160156, 446.0) + position: Offset(206.57142639160156, 446.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694108), pointer: 6, - position: Offset(206.57142639160156, 434.28570556640625) + position: Offset(206.57142639160156, 434.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694116), pointer: 6, - position: Offset(207.14285278320312, 423.71429443359375) + position: Offset(207.14285278320312, 423.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694124), pointer: 6, - position: Offset(208.57142639160156, 412.8571472167969) + position: Offset(208.57142639160156, 412.8571472167969), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694131), pointer: 6, - position: Offset(209.7142791748047, 402.28570556640625) + position: Offset(209.7142791748047, 402.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694139), pointer: 6, - position: Offset(211.7142791748047, 393.1428527832031) + position: Offset(211.7142791748047, 393.1428527832031), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694147), pointer: 6, - position: Offset(213.42857360839844, 385.1428527832031) + position: Offset(213.42857360839844, 385.1428527832031), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694154), pointer: 6, - position: Offset(215.42857360839844, 378.28570556640625) + position: Offset(215.42857360839844, 378.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694162), pointer: 6, - position: Offset(217.42857360839844, 371.71429443359375) + position: Offset(217.42857360839844, 371.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694169), pointer: 6, - position: Offset(219.42857360839844, 366.0) + position: Offset(219.42857360839844, 366.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694177), pointer: 6, - position: Offset(221.42857360839844, 360.8571472167969) + position: Offset(221.42857360839844, 360.8571472167969), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694185), pointer: 6, - position: Offset(223.42857360839844, 356.5714416503906) + position: Offset(223.42857360839844, 356.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694193), pointer: 6, - position: Offset(225.14285278320312, 352.28570556640625) + position: Offset(225.14285278320312, 352.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694201), pointer: 6, - position: Offset(226.85714721679688, 348.5714416503906) + position: Offset(226.85714721679688, 348.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694209), pointer: 6, - position: Offset(228.2857208251953, 346.0) + position: Offset(228.2857208251953, 346.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694216), pointer: 6, - position: Offset(229.14285278320312, 343.71429443359375) + position: Offset(229.14285278320312, 343.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694224), pointer: 6, - position: Offset(230.0, 342.0) + position: Offset(230.0, 342.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694232), pointer: 6, - position: Offset(230.57142639160156, 340.5714416503906) + position: Offset(230.57142639160156, 340.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694239), pointer: 6, - position: Offset(230.85714721679688, 339.71429443359375) + position: Offset(230.85714721679688, 339.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694247), pointer: 6, - position: Offset(230.85714721679688, 339.4285583496094) + position: Offset(230.85714721679688, 339.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694262), pointer: 6, - position: Offset(230.2857208251953, 342.0) + position: Offset(230.2857208251953, 342.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694270), pointer: 6, - position: Offset(228.85714721679688, 346.28570556640625) + position: Offset(228.85714721679688, 346.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694278), pointer: 6, - position: Offset(227.14285278320312, 352.5714416503906) + position: Offset(227.14285278320312, 352.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694286), pointer: 6, - position: Offset(225.42857360839844, 359.4285583496094) + position: Offset(225.42857360839844, 359.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694294), pointer: 6, - position: Offset(223.7142791748047, 367.71429443359375) + position: Offset(223.7142791748047, 367.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694301), pointer: 6, - position: Offset(222.57142639160156, 376.0) + position: Offset(222.57142639160156, 376.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694309), pointer: 6, - position: Offset(221.42857360839844, 384.28570556640625) + position: Offset(221.42857360839844, 384.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694317), pointer: 6, - position: Offset(220.85714721679688, 392.28570556640625) + position: Offset(220.85714721679688, 392.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694324), pointer: 6, - position: Offset(220.0, 400.5714416503906) + position: Offset(220.0, 400.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694332), pointer: 6, - position: Offset(219.14285278320312, 409.71429443359375) + position: Offset(219.14285278320312, 409.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694339), pointer: 6, - position: Offset(218.85714721679688, 419.1428527832031) + position: Offset(218.85714721679688, 419.1428527832031), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694348), pointer: 6, - position: Offset(218.2857208251953, 428.8571472167969) + position: Offset(218.2857208251953, 428.8571472167969), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694356), pointer: 6, - position: Offset(218.2857208251953, 438.8571472167969) + position: Offset(218.2857208251953, 438.8571472167969), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694363), pointer: 6, - position: Offset(218.2857208251953, 447.71429443359375) + position: Offset(218.2857208251953, 447.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694371), pointer: 6, - position: Offset(218.2857208251953, 455.71429443359375) + position: Offset(218.2857208251953, 455.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694379), pointer: 6, - position: Offset(219.14285278320312, 462.8571472167969) + position: Offset(219.14285278320312, 462.8571472167969), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694386), pointer: 6, - position: Offset(220.0, 469.4285583496094) + position: Offset(220.0, 469.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694394), pointer: 6, - position: Offset(221.14285278320312, 475.4285583496094) + position: Offset(221.14285278320312, 475.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694401), pointer: 6, - position: Offset(222.0, 480.5714416503906) + position: Offset(222.0, 480.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694409), pointer: 6, - position: Offset(222.85714721679688, 485.4285583496094) + position: Offset(222.85714721679688, 485.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694417), pointer: 6, - position: Offset(224.0, 489.71429443359375) + position: Offset(224.0, 489.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694425), pointer: 6, - position: Offset(224.85714721679688, 492.8571472167969) + position: Offset(224.85714721679688, 492.8571472167969), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694433), pointer: 6, - position: Offset(225.42857360839844, 495.4285583496094) + position: Offset(225.42857360839844, 495.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694440), pointer: 6, - position: Offset(226.0, 497.1428527832031) + position: Offset(226.0, 497.1428527832031), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694448), pointer: 6, - position: Offset(226.2857208251953, 498.28570556640625) + position: Offset(226.2857208251953, 498.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694456), pointer: 6, - position: Offset(226.2857208251953, 498.8571472167969) + position: Offset(226.2857208251953, 498.8571472167969), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694471), pointer: 6, - position: Offset(226.2857208251953, 498.28570556640625) + position: Offset(226.2857208251953, 498.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694479), pointer: 6, - position: Offset(226.2857208251953, 496.5714416503906) + position: Offset(226.2857208251953, 496.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694486), pointer: 6, - position: Offset(226.2857208251953, 493.71429443359375) + position: Offset(226.2857208251953, 493.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694494), pointer: 6, - position: Offset(226.2857208251953, 490.0) + position: Offset(226.2857208251953, 490.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694502), pointer: 6, - position: Offset(226.2857208251953, 486.0) + position: Offset(226.2857208251953, 486.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694510), pointer: 6, - position: Offset(226.2857208251953, 480.5714416503906) + position: Offset(226.2857208251953, 480.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694518), pointer: 6, - position: Offset(226.2857208251953, 475.71429443359375) + position: Offset(226.2857208251953, 475.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694525), pointer: 6, - position: Offset(226.2857208251953, 468.8571472167969) + position: Offset(226.2857208251953, 468.8571472167969), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694533), pointer: 6, - position: Offset(226.2857208251953, 461.4285583496094) + position: Offset(226.2857208251953, 461.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694541), pointer: 6, - position: Offset(226.2857208251953, 452.5714416503906) + position: Offset(226.2857208251953, 452.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694548), pointer: 6, - position: Offset(226.57142639160156, 442.28570556640625) + position: Offset(226.57142639160156, 442.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694556), pointer: 6, - position: Offset(226.57142639160156, 432.28570556640625) + position: Offset(226.57142639160156, 432.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694564), pointer: 6, - position: Offset(226.85714721679688, 423.4285583496094) + position: Offset(226.85714721679688, 423.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694571), pointer: 6, - position: Offset(227.42857360839844, 416.0) + position: Offset(227.42857360839844, 416.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694580), pointer: 6, - position: Offset(227.7142791748047, 410.0) + position: Offset(227.7142791748047, 410.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694587), pointer: 6, - position: Offset(228.2857208251953, 404.28570556640625) + position: Offset(228.2857208251953, 404.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694595), pointer: 6, - position: Offset(228.85714721679688, 399.71429443359375) + position: Offset(228.85714721679688, 399.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694603), pointer: 6, - position: Offset(229.14285278320312, 395.4285583496094) + position: Offset(229.14285278320312, 395.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694610), pointer: 6, - position: Offset(229.42857360839844, 392.28570556640625) + position: Offset(229.42857360839844, 392.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694618), pointer: 6, - position: Offset(229.7142791748047, 390.0) + position: Offset(229.7142791748047, 390.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694625), pointer: 6, - position: Offset(229.7142791748047, 388.0) + position: Offset(229.7142791748047, 388.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694633), pointer: 6, - position: Offset(229.7142791748047, 386.8571472167969) + position: Offset(229.7142791748047, 386.8571472167969), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694641), pointer: 6, - position: Offset(229.7142791748047, 386.28570556640625) + position: Offset(229.7142791748047, 386.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694648), pointer: 6, - position: Offset(229.7142791748047, 386.0) + position: Offset(229.7142791748047, 386.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694657), pointer: 6, - position: Offset(228.85714721679688, 386.0) + position: Offset(228.85714721679688, 386.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694665), pointer: 6, - position: Offset(228.0, 388.0) + position: Offset(228.0, 388.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694672), pointer: 6, - position: Offset(226.0, 392.5714416503906) + position: Offset(226.0, 392.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694680), pointer: 6, - position: Offset(224.0, 397.71429443359375) + position: Offset(224.0, 397.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694688), pointer: 6, - position: Offset(222.0, 404.28570556640625) + position: Offset(222.0, 404.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694695), pointer: 6, - position: Offset(219.7142791748047, 411.1428527832031) + position: Offset(219.7142791748047, 411.1428527832031), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694703), pointer: 6, - position: Offset(218.2857208251953, 418.0) + position: Offset(218.2857208251953, 418.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694710), pointer: 6, - position: Offset(217.14285278320312, 425.4285583496094) + position: Offset(217.14285278320312, 425.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694718), pointer: 6, - position: Offset(215.7142791748047, 433.4285583496094) + position: Offset(215.7142791748047, 433.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694726), pointer: 6, - position: Offset(214.85714721679688, 442.28570556640625) + position: Offset(214.85714721679688, 442.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694734), pointer: 6, - position: Offset(214.0, 454.0) + position: Offset(214.0, 454.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694742), pointer: 6, - position: Offset(214.0, 469.4285583496094) + position: Offset(214.0, 469.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694749), pointer: 6, - position: Offset(215.42857360839844, 485.4285583496094) + position: Offset(215.42857360839844, 485.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694757), pointer: 6, - position: Offset(217.7142791748047, 502.8571472167969) + position: Offset(217.7142791748047, 502.8571472167969), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694765), pointer: 6, - position: Offset(221.14285278320312, 521.4285888671875) + position: Offset(221.14285278320312, 521.4285888671875), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694772), pointer: 6, - position: Offset(224.57142639160156, 541.1428833007812) + position: Offset(224.57142639160156, 541.1428833007812), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694780), pointer: 6, - position: Offset(229.14285278320312, 561.1428833007812) + position: Offset(229.14285278320312, 561.1428833007812), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216694788), pointer: 6, - position: Offset(233.42857360839844, 578.8571166992188) + position: Offset(233.42857360839844, 578.8571166992188), ), const PointerUpEvent( timeStamp: Duration(milliseconds: 216694802), pointer: 6, - position: Offset(233.42857360839844, 578.8571166992188) + position: Offset(233.42857360839844, 578.8571166992188), ), const PointerDownEvent( timeStamp: Duration(milliseconds: 216695344), pointer: 7, - position: Offset(253.42857360839844, 310.5714416503906) + position: Offset(253.42857360839844, 310.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216695352), pointer: 7, - position: Offset(253.42857360839844, 310.5714416503906) + position: Offset(253.42857360839844, 310.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216695359), pointer: 7, - position: Offset(252.85714721679688, 318.0) + position: Offset(252.85714721679688, 318.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216695367), pointer: 7, - position: Offset(251.14285278320312, 322.0) + position: Offset(251.14285278320312, 322.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216695375), pointer: 7, - position: Offset(248.85714721679688, 327.1428527832031) + position: Offset(248.85714721679688, 327.1428527832031), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216695382), pointer: 7, - position: Offset(246.0, 334.8571472167969) + position: Offset(246.0, 334.8571472167969), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216695390), pointer: 7, - position: Offset(242.57142639160156, 344.5714416503906) + position: Offset(242.57142639160156, 344.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216695397), pointer: 7, - position: Offset(238.85714721679688, 357.4285583496094) + position: Offset(238.85714721679688, 357.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216695406), pointer: 7, - position: Offset(235.7142791748047, 371.71429443359375) + position: Offset(235.7142791748047, 371.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216695414), pointer: 7, - position: Offset(232.2857208251953, 386.8571472167969) + position: Offset(232.2857208251953, 386.8571472167969), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216695421), pointer: 7, - position: Offset(229.42857360839844, 402.0) + position: Offset(229.42857360839844, 402.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216695429), pointer: 7, - position: Offset(227.42857360839844, 416.8571472167969) + position: Offset(227.42857360839844, 416.8571472167969), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216695437), pointer: 7, - position: Offset(226.2857208251953, 431.4285583496094) + position: Offset(226.2857208251953, 431.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216695444), pointer: 7, - position: Offset(226.2857208251953, 446.0) + position: Offset(226.2857208251953, 446.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216695452), pointer: 7, - position: Offset(227.7142791748047, 460.28570556640625) + position: Offset(227.7142791748047, 460.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216695459), pointer: 7, - position: Offset(230.0, 475.1428527832031) + position: Offset(230.0, 475.1428527832031), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216695467), pointer: 7, - position: Offset(232.2857208251953, 489.71429443359375) + position: Offset(232.2857208251953, 489.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216695475), pointer: 7, - position: Offset(235.7142791748047, 504.0) + position: Offset(235.7142791748047, 504.0), ), const PointerUpEvent( timeStamp: Duration(milliseconds: 216695490), pointer: 7, - position: Offset(235.7142791748047, 504.0) + position: Offset(235.7142791748047, 504.0), ), const PointerDownEvent( timeStamp: Duration(milliseconds: 216695885), pointer: 8, - position: Offset(238.85714721679688, 524.0) + position: Offset(238.85714721679688, 524.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216695908), pointer: 8, - position: Offset(236.2857208251953, 515.7142944335938) + position: Offset(236.2857208251953, 515.7142944335938), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216695916), pointer: 8, - position: Offset(234.85714721679688, 509.1428527832031) + position: Offset(234.85714721679688, 509.1428527832031), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216695924), pointer: 8, - position: Offset(232.57142639160156, 498.5714416503906) + position: Offset(232.57142639160156, 498.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216695931), pointer: 8, - position: Offset(230.57142639160156, 483.71429443359375) + position: Offset(230.57142639160156, 483.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216695939), pointer: 8, - position: Offset(229.14285278320312, 466.5714416503906) + position: Offset(229.14285278320312, 466.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216695947), pointer: 8, - position: Offset(229.14285278320312, 446.5714416503906) + position: Offset(229.14285278320312, 446.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216695955), pointer: 8, - position: Offset(230.57142639160156, 424.8571472167969) + position: Offset(230.57142639160156, 424.8571472167969), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216695963), pointer: 8, - position: Offset(232.57142639160156, 402.28570556640625) + position: Offset(232.57142639160156, 402.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216695970), pointer: 8, - position: Offset(235.14285278320312, 380.0) + position: Offset(235.14285278320312, 380.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216695978), pointer: 8, - position: Offset(238.57142639160156, 359.4285583496094) + position: Offset(238.57142639160156, 359.4285583496094), ), const PointerUpEvent( timeStamp: Duration(milliseconds: 216695993), pointer: 8, - position: Offset(238.57142639160156, 359.4285583496094) + position: Offset(238.57142639160156, 359.4285583496094), ), const PointerDownEvent( timeStamp: Duration(milliseconds: 216696429), pointer: 9, - position: Offset(238.2857208251953, 568.5714111328125) + position: Offset(238.2857208251953, 568.5714111328125), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216696459), pointer: 9, - position: Offset(234.0, 560.0) + position: Offset(234.0, 560.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216696467), pointer: 9, - position: Offset(231.42857360839844, 553.1428833007812) + position: Offset(231.42857360839844, 553.1428833007812), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216696475), pointer: 9, - position: Offset(228.2857208251953, 543.1428833007812) + position: Offset(228.2857208251953, 543.1428833007812), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216696483), pointer: 9, - position: Offset(225.42857360839844, 528.8571166992188) + position: Offset(225.42857360839844, 528.8571166992188), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216696491), pointer: 9, - position: Offset(223.14285278320312, 512.2857055664062) + position: Offset(223.14285278320312, 512.2857055664062), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216696498), pointer: 9, - position: Offset(222.0, 495.4285583496094) + position: Offset(222.0, 495.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216696506), pointer: 9, - position: Offset(221.7142791748047, 477.4285583496094) + position: Offset(221.7142791748047, 477.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216696514), pointer: 9, - position: Offset(221.7142791748047, 458.28570556640625) + position: Offset(221.7142791748047, 458.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216696521), pointer: 9, - position: Offset(223.14285278320312, 438.0) + position: Offset(223.14285278320312, 438.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216696529), pointer: 9, - position: Offset(224.2857208251953, 416.28570556640625) + position: Offset(224.2857208251953, 416.28570556640625), ), const PointerUpEvent( timeStamp: Duration(milliseconds: 216696544), pointer: 9, - position: Offset(224.2857208251953, 416.28570556640625) + position: Offset(224.2857208251953, 416.28570556640625), ), const PointerDownEvent( timeStamp: Duration(milliseconds: 216696974), pointer: 10, - position: Offset(218.57142639160156, 530.5714111328125) + position: Offset(218.57142639160156, 530.5714111328125), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216697012), pointer: 10, - position: Offset(220.2857208251953, 522.0) + position: Offset(220.2857208251953, 522.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216697020), pointer: 10, - position: Offset(221.14285278320312, 517.7142944335938) + position: Offset(221.14285278320312, 517.7142944335938), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216697028), pointer: 10, - position: Offset(222.2857208251953, 511.71429443359375) + position: Offset(222.2857208251953, 511.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216697036), pointer: 10, - position: Offset(224.0, 504.28570556640625) + position: Offset(224.0, 504.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216697044), pointer: 10, - position: Offset(227.14285278320312, 490.5714416503906) + position: Offset(227.14285278320312, 490.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216697052), pointer: 10, - position: Offset(229.42857360839844, 474.0) + position: Offset(229.42857360839844, 474.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216697059), pointer: 10, - position: Offset(231.42857360839844, 454.5714416503906) + position: Offset(231.42857360839844, 454.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216697067), pointer: 10, - position: Offset(233.7142791748047, 431.1428527832031) + position: Offset(233.7142791748047, 431.1428527832031), ), const PointerUpEvent( timeStamp: Duration(milliseconds: 216697082), pointer: 10, - position: Offset(233.7142791748047, 431.1428527832031) + position: Offset(233.7142791748047, 431.1428527832031), ), const PointerDownEvent( timeStamp: Duration(milliseconds: 216697435), pointer: 11, - position: Offset(257.1428527832031, 285.1428527832031) + position: Offset(257.1428527832031, 285.1428527832031), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216697465), pointer: 11, - position: Offset(251.7142791748047, 296.8571472167969) + position: Offset(251.7142791748047, 296.8571472167969), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216697473), pointer: 11, - position: Offset(248.2857208251953, 304.0) + position: Offset(248.2857208251953, 304.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216697481), pointer: 11, - position: Offset(244.57142639160156, 314.8571472167969) + position: Offset(244.57142639160156, 314.8571472167969), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216697489), pointer: 11, - position: Offset(240.2857208251953, 329.1428527832031) + position: Offset(240.2857208251953, 329.1428527832031), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216697497), pointer: 11, - position: Offset(236.85714721679688, 345.1428527832031) + position: Offset(236.85714721679688, 345.1428527832031), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216697505), pointer: 11, - position: Offset(233.7142791748047, 361.4285583496094) + position: Offset(233.7142791748047, 361.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216697512), pointer: 11, - position: Offset(231.14285278320312, 378.28570556640625) + position: Offset(231.14285278320312, 378.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216697520), pointer: 11, - position: Offset(229.42857360839844, 395.4285583496094) + position: Offset(229.42857360839844, 395.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216697528), pointer: 11, - position: Offset(229.42857360839844, 412.8571472167969) + position: Offset(229.42857360839844, 412.8571472167969), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216697535), pointer: 11, - position: Offset(230.85714721679688, 430.8571472167969) + position: Offset(230.85714721679688, 430.8571472167969), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216697543), pointer: 11, - position: Offset(233.42857360839844, 449.71429443359375) + position: Offset(233.42857360839844, 449.71429443359375), ), const PointerUpEvent( timeStamp: Duration(milliseconds: 216697558), pointer: 11, - position: Offset(233.42857360839844, 449.71429443359375) + position: Offset(233.42857360839844, 449.71429443359375), ), const PointerDownEvent( timeStamp: Duration(milliseconds: 216697749), pointer: 12, - position: Offset(246.0, 311.4285583496094) + position: Offset(246.0, 311.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216697780), pointer: 12, - position: Offset(244.57142639160156, 318.28570556640625) + position: Offset(244.57142639160156, 318.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216697787), pointer: 12, - position: Offset(243.14285278320312, 325.4285583496094) + position: Offset(243.14285278320312, 325.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216697795), pointer: 12, - position: Offset(241.42857360839844, 336.0) + position: Offset(241.42857360839844, 336.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216697803), pointer: 12, - position: Offset(239.7142791748047, 351.1428527832031) + position: Offset(239.7142791748047, 351.1428527832031), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216697811), pointer: 12, - position: Offset(238.2857208251953, 368.5714416503906) + position: Offset(238.2857208251953, 368.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216697819), pointer: 12, - position: Offset(238.0, 389.4285583496094) + position: Offset(238.0, 389.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216697826), pointer: 12, - position: Offset(239.14285278320312, 412.0) + position: Offset(239.14285278320312, 412.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216697834), pointer: 12, - position: Offset(242.2857208251953, 438.0) + position: Offset(242.2857208251953, 438.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216697842), pointer: 12, - position: Offset(247.42857360839844, 466.8571472167969) + position: Offset(247.42857360839844, 466.8571472167969), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216697849), pointer: 12, - position: Offset(254.2857208251953, 497.71429443359375) + position: Offset(254.2857208251953, 497.71429443359375), ), const PointerUpEvent( timeStamp: Duration(milliseconds: 216697864), pointer: 12, - position: Offset(254.2857208251953, 497.71429443359375) + position: Offset(254.2857208251953, 497.71429443359375), ), const PointerDownEvent( timeStamp: Duration(milliseconds: 216698321), pointer: 13, - position: Offset(250.0, 306.0) + position: Offset(250.0, 306.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216698328), pointer: 13, - position: Offset(250.0, 306.0) + position: Offset(250.0, 306.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216698344), pointer: 13, - position: Offset(249.14285278320312, 314.0) + position: Offset(249.14285278320312, 314.0), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216698351), pointer: 13, - position: Offset(247.42857360839844, 319.4285583496094) + position: Offset(247.42857360839844, 319.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216698359), pointer: 13, - position: Offset(245.14285278320312, 326.8571472167969) + position: Offset(245.14285278320312, 326.8571472167969), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216698366), pointer: 13, - position: Offset(241.7142791748047, 339.4285583496094) + position: Offset(241.7142791748047, 339.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216698374), pointer: 13, - position: Offset(238.57142639160156, 355.71429443359375) + position: Offset(238.57142639160156, 355.71429443359375), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216698382), pointer: 13, - position: Offset(236.2857208251953, 374.28570556640625) + position: Offset(236.2857208251953, 374.28570556640625), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216698390), pointer: 13, - position: Offset(235.14285278320312, 396.5714416503906) + position: Offset(235.14285278320312, 396.5714416503906), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216698398), pointer: 13, - position: Offset(236.57142639160156, 421.4285583496094) + position: Offset(236.57142639160156, 421.4285583496094), ), const PointerMoveEvent( timeStamp: Duration(milliseconds: 216698406), pointer: 13, - position: Offset(241.14285278320312, 451.4285583496094) + position: Offset(241.14285278320312, 451.4285583496094), ), const PointerUpEvent( timeStamp: Duration(milliseconds: 216698421), pointer: 13, - position: Offset(241.14285278320312, 451.4285583496094) + position: Offset(241.14285278320312, 451.4285583496094), ), ]; diff --git a/dev/benchmarks/microbenchmarks/pubspec.yaml b/dev/benchmarks/microbenchmarks/pubspec.yaml index b6e576fcd6..a0a646e60f 100644 --- a/dev/benchmarks/microbenchmarks/pubspec.yaml +++ b/dev/benchmarks/microbenchmarks/pubspec.yaml @@ -15,7 +15,7 @@ dependencies: path: ../../../examples/stocks test: 1.5.3 - analyzer: 0.35.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + analyzer: 0.35.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" args: 1.5.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" async: 2.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -25,9 +25,9 @@ dependencies: crypto: 2.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.14.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dart_style: 1.2.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - front_end: 0.1.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + front_end: 0.1.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" glob: 1.1.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - html: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + html: 0.13.4+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http: 0.12.0+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_multi_server: 2.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_parser: 3.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -37,17 +37,17 @@ dependencies: isolate: 2.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" js: 0.6.1+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" json_rpc_2: 2.0.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - kernel: 0.3.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + kernel: 0.3.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" logging: 0.11.3+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" matcher: 0.12.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" mime: 0.9.6+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" multi_server_socket: 1.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" node_preamble: 1.4.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" package_config: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - package_resolver: 1.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + package_resolver: 1.0.10 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path: 1.6.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - pedantic: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - petitparser: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + pedantic: 1.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + petitparser: 2.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" plugin: 0.2.0+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pool: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pub_semver: 1.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -58,7 +58,7 @@ dependencies: shelf_web_socket: 0.2.2+4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" source_map_stack_trace: 1.1.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" source_maps: 0.10.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - source_span: 1.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + source_span: 1.5.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 1.6.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" string_scanner: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -76,4 +76,4 @@ dependencies: flutter: uses-material-design: true -# PUBSPEC CHECKSUM: 7d7d +# PUBSPEC CHECKSUM: a9b0 diff --git a/dev/bots/README.md b/dev/bots/README.md index 5301644320..a3423a8c88 100644 --- a/dev/bots/README.md +++ b/dev/bots/README.md @@ -5,41 +5,37 @@ This directory exists to support building Flutter on our build infrastructure. The results of such builds are viewable at: * https://cirrus-ci.com/github/flutter/flutter/master - Testing done on PRs and submitted changes on GitHub. -* https://build.chromium.org/p/client.flutter/console +* https://ci.chromium.org/p/flutter/ - Additional testing and processing done after changes are submitted. -The Chromium infra bots do not allow forcing new builds from outside -the Google network. Contact @eseidelGoogle or another Google member of -the Flutter team if you need to do that. +The LUCI infra requires permissions to retrigger or schedule builds. Contact +@kf6gpe or another Google member of the Flutter team if you need to do that. -The [Cirrus](https://cirrus-ci.org)-based bots run the -[`test.dart`](test.dart) script for each PR and submission. This does -testing for the tools, for the framework, and (for submitted changes -only) rebuilds and updates the master branch API docs -[staging site](https://master-docs-flutter-io.firebaseapp.com). -For tagged dev and beta builds, it also builds and deploys the gallery -app to the app stores. It is configured by the -[.cirrus.yml](/.cirrus.yml). +The [Cirrus](https://cirrus-ci.org)-based bots run the [`test.dart`](test.dart) +script for each PR and submission. This does testing for the tools, for the +framework, and (for submitted changes only) rebuilds and updates the master +branch API docs [staging site](https://master-docs.flutter.dev/). +For tagged dev and beta builds, it also builds and deploys the gallery app to +the app stores. It is configured by the [.cirrus.yml](/.cirrus.yml). -We also have post-commit testing with actual devices, in what we call -our [devicelab](../dev/devicelab/README.md). +We also have post-commit testing with actual devices, in what we call our +[devicelab](../devicelab/README.md). -## Chromium infra bots +## LUCI (Layered Universal Continuous Intergration) -This part of our infrastructure is broken into two parts. A buildbot -master specified by our -[builders.pyl](https://chromium.googlesource.com/chromium/tools/build.git/+/master/masters/master.client.flutter/builders.pyl) -file, and a [set of -recipes](https://chromium.googlesource.com/chromium/tools/build.git/+/master/scripts/slave/recipes/flutter) -which we run on that master. Both of these technologies are highly -specific to Google's Chromium project. We're just borrowing some of -their infrastructure. +A [set of recipes](https://chromium.googlesource.com/chromium/tools/build.git/+/master/scripts/slave/recipes/flutter) +are run on Windows, Linux, and Mac machines. The configuration for how many +machines and what kind are managed internally by Google. Contact @kf6gpe or +another Google member of the Flutter team if you suspect changes are needed +there. Both of these technologies are highly specific to the [LUCI](https://github.com/luci) +project, which is the successor to Chromium's infra. We're just borrowing some +of their infrastructure. ### Prerequisites To work on this infrastructure you will need: -- [depot_tools](http://www.chromium.org/developers/how-tos/install-depot-tools) +- [depot_tools](https://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/depot_tools_tutorial.html#_setting_up) - Python package installer: `sudo apt-get install python-pip` - Python coverage package (only needed for `training_simulation`): `sudo pip install coverage` @@ -48,8 +44,7 @@ To run prepare_package.dart locally: - Make sure the depot_tools is in your PATH. If you're on Windows, you also need an environment variable called DEPOT_TOOLS with the path to depot_tools as value. - Run `gsutil.py config` (or `python %DEPOT_TOOLS%\gsutil.py` on Windows) to - authenticate with your auth token. When asked, the GCP project ID is - `turquoise-dev`. + authenticate with your auth token. - Create a local temp directory. `cd` into it. - Run `dart [path to your normal Flutter repo]/dev/bots/prepare_package.dart --temp_dir=. --revision=[revision to package] --branch=[branch to deploy to] @@ -59,7 +54,8 @@ To run prepare_package.dart locally: ### Getting the code -The following will get way more than just recipe code, but it _will_ get the recipe code: +The following will get way more than just recipe code, but it _will_ get the +recipe code: ```bash mkdir chrome_infra @@ -83,7 +79,7 @@ and - build/scripts/slave/recipes/flutter/flutter.py - build/scripts/slave/recipes/flutter/engine.py -Recipes are just Python. They are +Recipes are just Python with some limitations on what can be imported. They are [documented](https://github.com/luci/recipes-py/blob/master/doc/user_guide.md) by the [luci/recipes-py github project](https://github.com/luci/recipes-py). @@ -91,33 +87,27 @@ The typical cycle for editing a recipe is: 1. Make your edits (probably to files in `//chrome_infra/build/scripts/slave/recipes/flutter`). -1. Update the tests. Run `build/scripts/slave/recipes.py test train` to update +2. Update the tests. Run `build/scripts/slave/recipes.py test train` to update existing expected output to match the new output. Verify completely new test - cases by altering the `GenTests` method of the recipe. - The recipe is required to have 100% test coverage. -1. Run `build/scripts/slave/recipes.py run flutter/ slavename= - mastername=client.flutter buildername= buildnumber=1234` where `` is one - of `flutter` or `engine`, and `slavename` and `buildername` can be looked up - from the *Build Properties* section of a [recent - build](https://build.chromium.org/p/client.flutter/one_line_per_build). -1. To submit a CL, you need a local branch first (`git checkout -b [some branch name]`). -1. Upload the patch (`git commit`, `git cl upload`) and send it to someone in + cases by altering the `GenTests` method of the recipe. The recipe is required + to have 100% test coverage. +3. Run `led get-builder 'luci.flutter.prod:BUILDER_NAME' | led edit -p 'revision="GIT_HASH"' | led edit-recipe-bundle | led launch`, where `BUILDER_NAME` is the builder name (e.g. `Linux Engine`), and + `GIT_HASH` is the hash to build (which is important for the engine but not + for the framework). +4. To submit a CL, you need a local branch first (`git checkout -b [some branch name]`). +5. Upload the patch (`git commit`, `git cl upload`) and send it to someone in the `recipes/flutter/OWNERS` file for review. -### Editing the client.flutter buildbot master +### The infra config repository -Flutter uses Chromium's fancy -[builders.pyl](https://chromium.googlesource.com/infra/infra/+/master/doc/users/services/buildbot/builders.pyl.md) -master generation system. Chromium hosts 100s (if not 1000s) of buildbot -masters and thus has lots of infrastructure for turning them up and down. -Eventually all of buildbot is planned to be replaced by other infrastructure, -but for now flutter has its own client.flutter master. +The [flutter/infra](https://github.com/flutter/infra) repository contains +configuration files for the dashboard, builder groups, scheduling, and +individual builders. Edits to this may require changes other internal Google +repositories - e.g., to change the operating system or number of machines. If +you want to do that, reach out to @kf6gpe or another member of the Google team. -You would need to edit client.flutter's master in order to add slaves (talk to -@eseidelGoogle), add builder groups, or to change the html layout of -https://build.chromium.org/p/client.flutter. Carefully follow the [builders.pyl -docs](https://chromium.googlesource.com/infra/infra/+/master/doc/users/services/buildbot/builders.pyl.md) -to do so. +Each configuration file in that repository has a link in the top comments to a +schema that describes available properties. ### Future Directions @@ -131,11 +121,13 @@ tried, but it's not quite ready. ### Android Tools -The Android SDK and NDK used by Flutter's Chrome infra bots are stored in Google Cloud. During the build a bot runs the -`download_android_tools.py` script that downloads the required version of the Android SDK into `dev/bots/android_tools`. +The Android SDK and NDK used by Flutter's Chrome infra bots are stored in Google +Cloud. During the build a bot runs the `download_android_tools.py` script that +downloads the required version of the Android SDK into `dev/bots/android_tools`. -To check which components are currently installed, download the current SDK stored in Google Cloud using the -`download_android_tools.py` script, then `dev/bots/android_tools/sdk/tools/bin/sdkmanager --list`. If you find that some +To check which components are currently installed, download the current SDK +stored in Google Cloud using the `download_android_tools.py` script, then +`dev/bots/android_tools/sdk/tools/bin/sdkmanager --list`. If you find that some components need to be updated or installed, follow the steps below: #### How to update Android SDK on Google Cloud Storage @@ -146,13 +138,17 @@ components need to be updated or installed, follow the steps below: 2. Use the UI to choose the packages you want to install and/or update. -3. Run `dev/bots/android_tools/sdk/tools/bin/sdkmanager --update`. On Windows, run `sdkmanager.bat` instead. If the - process fails with an error saying that it is unable to move files (Windows makes files and directories read-only - when another process is holding them open), make a copy of the `dev/bots/android_tools/sdk/tools` directory, run - the `sdkmanager.bat` from the copy, and use the `--sdk_root` option pointing at `dev/bots/android_tools/sdk`. +3. Run `dev/bots/android_tools/sdk/tools/bin/sdkmanager --update`. On Windows, + run `sdkmanager.bat` instead. If the process fails with an error saying that + it is unable to move files (Windows makes files and directories read-only + when another process is holding them open), make a copy of the + `dev/bots/android_tools/sdk/tools` directory, run the `sdkmanager.bat` from + the copy, and use the `--sdk_root` option pointing at + `dev/bots/android_tools/sdk`. -4. Run `dev/bots/android_tools/sdk/tools/bin/sdkmanager --licenses` and accept the licenses for the newly installed - components. It also helps to run this command a second time and make sure that it prints "All SDK package licenses +4. Run `dev/bots/android_tools/sdk/tools/bin/sdkmanager --licenses` and accept + the licenses for the newly installed components. It also helps to run this + command a second time and make sure that it prints "All SDK package licenses accepted". 5. Run upload_android_tools.py -t sdk diff --git a/dev/bots/analyze-sample-code.dart b/dev/bots/analyze-sample-code.dart index a749dd2c71..6af14703f9 100644 --- a/dev/bots/analyze-sample-code.dart +++ b/dev/bots/analyze-sample-code.dart @@ -87,12 +87,42 @@ void main(List arguments) { Directory tempDirectory; if (parsedArguments.wasParsed('temp')) { - tempDirectory = Directory(parsedArguments['temp']); - if (!tempDirectory.existsSync()) { - tempDirectory.createSync(recursive: true); + tempDirectory = Directory(path.join(Directory.systemTemp.absolute.path, path.basename(parsedArguments['temp']))); + if (path.basename(parsedArguments['temp']) != parsedArguments['temp']) { + stderr.writeln('Supplied temporary directory name should be a name, not a path. Using ${tempDirectory.absolute.path} instead.'); + } + print('Leaving temporary output in ${tempDirectory.absolute.path}.'); + // Make sure that any directory left around from a previous run is cleared + // out. + if (tempDirectory.existsSync()) { + tempDirectory.deleteSync(recursive: true); + } + tempDirectory.createSync(); + } + try { + exitCode = SampleChecker(flutterPackage, tempDirectory: tempDirectory).checkSamples(); + } on SampleCheckerException catch (e) { + stderr.write(e); + exit(1); + } +} + +class SampleCheckerException implements Exception { + SampleCheckerException(this.message, {this.file, this.line}); + final String message; + final String file; + final int line; + + @override + String toString() { + if (file != null || line != null) { + final String fileStr = file == null ? '' : '$file:'; + final String lineStr = line == null ? '' : '$line:'; + return '$fileStr$lineStr Error: $message'; + } else { + return 'Error: $message'; } } - exitCode = SampleChecker(flutterPackage, tempDirectory: tempDirectory).checkSamples(); } /// Checks samples and code snippets for analysis errors. @@ -129,10 +159,10 @@ class SampleChecker { static final RegExp _dartDocSampleEndRegex = RegExp(r'{@end-tool}'); /// A RegExp that matches the start of a code block within dartdoc. - static final RegExp _codeBlockStartRegex = RegExp(r'/// ```dart.*$'); + static final RegExp _codeBlockStartRegex = RegExp(r'///\s+```dart.*$'); /// A RegExp that matches the end of a code block within dartdoc. - static final RegExp _codeBlockEndRegex = RegExp(r'/// ```\s*$'); + static final RegExp _codeBlockEndRegex = RegExp(r'///\s+```\s*$'); /// A RegExp that matches a Dart constructor. static final RegExp _constructorRegExp = RegExp(r'[A-Z][a-zA-Z0-9<>.]*\('); @@ -173,10 +203,7 @@ class SampleChecker { } static List _listDartFiles(Directory directory, {bool recursive = false}) { - return directory.listSync(recursive: recursive, followLinks: false) - .whereType() - .where((File file) => path.extension(file.path) == '.dart') - .toList(); + return directory.listSync(recursive: recursive, followLinks: false).whereType().where((File file) => path.extension(file.path) == '.dart').toList(); } /// Computes the headers needed for each sample file. @@ -218,14 +245,14 @@ class SampleChecker { } stderr.writeln('\nFound ${errors.length} sample code errors.'); } - if (!_keepTmp) { + if (_keepTmp) { + print('Leaving temporary directory ${_tempDirectory.path} around for your perusal.'); + } else { try { _tempDirectory.deleteSync(recursive: true); } on FileSystemException catch (e) { stderr.writeln('Failed to delete ${_tempDirectory.path}: $e'); } - } else { - print('Leaving temporary directory ${_tempDirectory.path} around for your perusal.'); } // If we made a snapshot, remove it (so as not to clutter up the tree). if (_snippetsSnapshotPath != null) { @@ -288,8 +315,12 @@ class SampleChecker { print('Generating snippet for ${snippet.start?.filename}:${snippet.start?.line}'); final ProcessResult process = _runSnippetsScript(args); if (process.exitCode != 0) { - throw 'Unable to create snippet for ${snippet.start.filename}:${snippet.start.line} ' - '(using input from ${inputFile.path}):\n${process.stdout}\n${process.stderr}'; + throw SampleCheckerException( + 'Unable to create snippet for ${snippet.start.filename}:${snippet.start.line} ' + '(using input from ${inputFile.path}):\n${process.stdout}\n${process.stderr}', + file: snippet.start.filename, + line: snippet.start.line, + ); } return outputFile; } @@ -304,11 +335,14 @@ class SampleChecker { final String relativeFilePath = path.relative(file.path, from: _flutterPackage.path); final List sampleLines = file.readAsLinesSync(); final List
preambleSections =
[]; + // Whether or not we're in the file-wide preamble section ("Examples can assume"). bool inPreamble = false; + // Whether or not we're in a code sample bool inSampleSection = false; + // Whether or not we're in a snippet code sample (with template) specifically. bool inSnippet = false; + // Whether or not we're in a '```dart' segment. bool inDart = false; - bool foundDart = false; int lineNumber = 0; final List block = []; List snippetArgs = []; @@ -318,7 +352,7 @@ class SampleChecker { final String trimmedLine = line.trim(); if (inSnippet) { if (!trimmedLine.startsWith(_dartDocPrefix)) { - throw '$relativeFilePath:$lineNumber: Snippet section unterminated.'; + throw SampleCheckerException('Snippet section unterminated.', file: relativeFilePath, line: lineNumber); } if (_dartDocSampleEndRegex.hasMatch(trimmedLine)) { snippets.add( @@ -342,53 +376,51 @@ class SampleChecker { preambleSections.add(_processBlock(startLine, block)); block.clear(); } else if (!line.startsWith('// ')) { - throw '$relativeFilePath:$lineNumber: Unexpected content in sample code preamble.'; + throw SampleCheckerException('Unexpected content in sample code preamble.', file: relativeFilePath, line: lineNumber); } else { block.add(line.substring(3)); } } else if (inSampleSection) { - if (!trimmedLine.startsWith(_dartDocPrefix) || trimmedLine.startsWith('$_dartDocPrefix ## ')) { + if (_dartDocSampleEndRegex.hasMatch(trimmedLine)) { if (inDart) { - throw '$relativeFilePath:$lineNumber: Dart section inexplicably unterminated.'; - } - if (!foundDart) { - throw '$relativeFilePath:$lineNumber: No dart block found in sample code section'; + throw SampleCheckerException("Dart section didn't terminate before end of sample", file: relativeFilePath, line: lineNumber); } inSampleSection = false; - } else { - if (inDart) { - if (_codeBlockEndRegex.hasMatch(trimmedLine)) { - inDart = false; - final Section processed = _processBlock(startLine, block); - if (preambleSections.isEmpty) { - sections.add(processed); - } else { - sections.add(Section.combine(preambleSections - ..toList() - ..add(processed))); - } - block.clear(); - } else if (trimmedLine == _dartDocPrefix) { - block.add(''); + } + if (inDart) { + if (_codeBlockEndRegex.hasMatch(trimmedLine)) { + inDart = false; + final Section processed = _processBlock(startLine, block); + if (preambleSections.isEmpty) { + sections.add(processed); } else { - final int index = line.indexOf(_dartDocPrefixWithSpace); - if (index < 0) { - throw '$relativeFilePath:$lineNumber: Dart section inexplicably did not ' - 'contain "$_dartDocPrefixWithSpace" prefix.'; - } - block.add(line.substring(index + 4)); + sections.add(Section.combine(preambleSections + ..toList() + ..add(processed))); } - } else if (_codeBlockStartRegex.hasMatch(trimmedLine)) { - assert(block.isEmpty); - startLine = Line( - '', - filename: relativeFilePath, - line: lineNumber + 1, - indent: line.indexOf(_dartDocPrefixWithSpace) + _dartDocPrefixWithSpace.length, - ); - inDart = true; - foundDart = true; + block.clear(); + } else if (trimmedLine == _dartDocPrefix) { + block.add(''); + } else { + final int index = line.indexOf(_dartDocPrefixWithSpace); + if (index < 0) { + throw SampleCheckerException( + 'Dart section inexplicably did not contain "$_dartDocPrefixWithSpace" prefix.', + file: relativeFilePath, + line: lineNumber, + ); + } + block.add(line.substring(index + 4)); } + } else if (_codeBlockStartRegex.hasMatch(trimmedLine)) { + assert(block.isEmpty); + startLine = Line( + '', + filename: relativeFilePath, + line: lineNumber + 1, + indent: line.indexOf(_dartDocPrefixWithSpace) + _dartDocPrefixWithSpace.length, + ); + inDart = true; } } if (!inSampleSection) { @@ -397,11 +429,7 @@ class SampleChecker { assert(block.isEmpty); startLine = Line('', filename: relativeFilePath, line: lineNumber + 1, indent: 3); inPreamble = true; - } else if (trimmedLine == '/// ## Sample code' || - trimmedLine.startsWith('/// ## Sample code:') || - trimmedLine == '/// ### Sample code' || - trimmedLine.startsWith('/// ### Sample code:') || - sampleMatch != null) { + } else if (sampleMatch != null) { inSnippet = sampleMatch != null ? sampleMatch[1] == 'snippet' : false; if (inSnippet) { startLine = Line( @@ -418,7 +446,12 @@ class SampleChecker { } } inSampleSection = !inSnippet; - foundDart = false; + } else if (RegExp(r'///\s*#+\s+[Ss]ample\s+[Cc]ode:?$').hasMatch(trimmedLine)) { + throw SampleCheckerException( + "Found deprecated '## Sample code' section: use {@tool sample}...{@end-tool} instead.", + file: relativeFilePath, + line: lineNumber, + ); } } } @@ -598,14 +631,17 @@ linter: ), ), ); - throw 'Cannot analyze dartdocs; analysis errors exist in ${file.path}: $error'; + throw SampleCheckerException( + 'Cannot analyze dartdocs; analysis errors exist: $error', + file: file.path, + line: lineNumber, + ); } if (errorCode == 'unused_element' || errorCode == 'unused_local_variable') { // We don't really care if sample code isn't used! continue; } - if (isSnippet) { addAnalysisError( file, @@ -630,14 +666,20 @@ linter: Line('', filename: file.path, line: lineNumber), ), ); - throw 'Failed to parse error message (read line number as $lineNumber; ' - 'total number of lines is ${fileContents.length}): $error'; + throw SampleCheckerException('Failed to parse error message: $error', file: file.path, line: lineNumber); } final Section actualSection = sections[file.path]; + if (actualSection == null) { + throw SampleCheckerException( + "Unknown section for ${file.path}. Maybe the temporary directory wasn't empty?", + file: file.path, + line: lineNumber, + ); + } final Line actualLine = actualSection.code[lineNumber - 1]; - if (actualLine.filename == null) { + if (actualLine?.filename == null) { if (errorCode == 'missing_identifier' && lineNumber > 1) { if (fileContents[lineNumber - 2].endsWith(',')) { final Line actualLine = sections[file.path].code[lineNumber - 2]; @@ -698,7 +740,7 @@ linter: /// into valid Dart code. Section _processBlock(Line line, List block) { if (block.isEmpty) { - throw '$line: Empty ```dart block in sample code.'; + throw SampleCheckerException('$line: Empty ```dart block in sample code.'); } if (block.first.startsWith('new ') || block.first.startsWith('const ') || block.first.startsWith(_constructorRegExp)) { _expressionId += 1; @@ -721,8 +763,8 @@ linter: // treated as a separate code block. if (block[index] == '' || block[index] == '// ...') { if (subline == null) - throw '${Line('', filename: line.filename, line: line.line + index, indent: line.indent)}: ' - 'Unexpected blank line or "// ..." line near start of subblock in sample code.'; + throw SampleCheckerException('${Line('', filename: line.filename, line: line.line + index, indent: line.indent)}: ' + 'Unexpected blank line or "// ..." line near start of subblock in sample code.'); subblocks += 1; subsections.add(_processBlock(subline, buffer)); buffer.clear(); diff --git a/dev/bots/analyze.dart b/dev/bots/analyze.dart index 448ae55c27..b6c4ab1784 100644 --- a/dev/bots/analyze.dart +++ b/dev/bots/analyze.dart @@ -30,6 +30,7 @@ Future main(List args) async { print('The analyze.dart script must be run with --enable-asserts.'); exit(1); } + await _verifyNoMissingLicense(flutterRoot); await _verifyNoTestImports(flutterRoot); await _verifyNoTestPackageImports(flutterRoot); await _verifyGeneratedPluginRegistrants(flutterRoot); @@ -235,7 +236,7 @@ Future _evalCommand(String executable, List arguments, { } Future _runFlutterAnalyze(String workingDirectory, { - List options = const [] + List options = const [], }) { return runCommand(flutter, ['analyze', '--dartdocs']..addAll(options), workingDirectory: workingDirectory, @@ -400,7 +401,7 @@ Set _findFlutterDependencies(String srcPath, List errors, { bool return Directory(srcPath).listSync(recursive: true).where((FileSystemEntity entity) { return entity is File && path.extension(entity.path) == '.dart'; }).map>((FileSystemEntity entity) { - final Set result = Set(); + final Set result = {}; final File file = entity; for (String line in file.readAsLinesSync()) { Match match = _importPattern.firstMatch(line); @@ -418,7 +419,7 @@ Set _findFlutterDependencies(String srcPath, List errors, { bool } return result; }).reduce((Set value, Set element) { - value ??= Set(); + value ??= {}; value.addAll(element); return value; }); @@ -433,7 +434,7 @@ List _deepSearch(Map> map, T start, [ Set seen ]) { final List result = _deepSearch( map, key, - (seen == null ? Set.from([start]) : Set.from(seen))..add(key), + (seen == null ? {start} : Set.from(seen))..add(key), ); if (result != null) { result.insert(0, start); @@ -472,6 +473,30 @@ Future _verifyNoBadImportsInFlutterTools(String workingDirectory) async { } } +Future _verifyNoMissingLicense(String workingDirectory) async { + final List errors = []; + for (FileSystemEntity entity in Directory(path.join(workingDirectory, 'packages')) + .listSync(recursive: true) + .where((FileSystemEntity entity) => entity is File && path.extension(entity.path) == '.dart')) { + final File file = entity; + bool hasLicense = false; + final List lines = file.readAsLinesSync(); + if (lines.isNotEmpty) + hasLicense = lines.first.startsWith(RegExp(r'// Copyright \d{4}')); + if (!hasLicense) + errors.add(file.path); + } + // Fail if any errors + if (errors.isNotEmpty) { + print('$redLine'); + final String s = errors.length == 1 ? '' : 's'; + print('${bold}License headers cannot be found at the beginning of the following file$s.$reset\n'); + print(errors.join('\n')); + print('$redLine\n'); + exit(1); + } +} + final RegExp _testImportPattern = RegExp(r'''import (['"])([^'"]+_test\.dart)\1'''); const Set _exemptTestImports = { 'package:flutter_test/flutter_test.dart', @@ -518,7 +543,7 @@ Future _verifyGeneratedPluginRegistrants(String flutterRoot) async { } } - final Set outOfDate = Set(); + final Set outOfDate = {}; for (String package in packageToRegistrants.keys) { final Map fileToContent = {}; diff --git a/dev/bots/docs.sh b/dev/bots/docs.sh index 3ae9cf48a4..05ee7ae8ae 100755 --- a/dev/bots/docs.sh +++ b/dev/bots/docs.sh @@ -62,9 +62,9 @@ function move_offline_into_place() { mv flutter.docs.zip doc/offline/flutter.docs.zip du -sh doc/offline/flutter.docs.zip if [[ "$CIRRUS_BRANCH" == "stable" ]]; then - echo -e "\n ${FLUTTER_VERSION}\n https://docs.flutter.io/offline/flutter.docset.tar.gz\n" > doc/offline/flutter.xml + echo -e "\n ${FLUTTER_VERSION}\n https://api.flutter.dev/offline/flutter.docset.tar.gz\n" > doc/offline/flutter.xml else - echo -e "\n ${FLUTTER_VERSION}\n https://master-docs.flutter.io/offline/flutter.docset.tar.gz\n" > doc/offline/flutter.xml + echo -e "\n ${FLUTTER_VERSION}\n https://master-api.flutter.dev/offline/flutter.docset.tar.gz\n" > doc/offline/flutter.xml fi mv flutter.docset.tar.gz doc/offline/flutter.docset.tar.gz du -sh doc/offline/flutter.docset.tar.gz @@ -104,7 +104,7 @@ if [[ -d "$FLUTTER_PUB_CACHE" ]]; then fi # Install and activate dartdoc. -"$PUB" global activate dartdoc 0.28.1+2 +"$PUB" global activate dartdoc 0.28.2 # This script generates a unified doc set, and creates # a custom index.html, placing everything into dev/docs/doc. @@ -125,21 +125,21 @@ cp "$FLUTTER_ROOT/dev/docs/google2ed1af765c529f57.html" "$FLUTTER_ROOT/dev/docs/ if [[ -n "$CIRRUS_CI" && -z "$CIRRUS_PR" ]]; then echo "This is not a pull request; considering whether to upload docs... (branch=$CIRRUS_BRANCH)" if [[ "$CIRRUS_BRANCH" == "master" ]]; then - echo "Updating $CIRRUS_BRANCH docs: https://master-docs.flutter.io/" + echo "Updating $CIRRUS_BRANCH docs: https://master-api.flutter.dev/" # Disable search indexing on the master staging site so searches get only # the stable site. echo -e "User-agent: *\nDisallow: /" > "$FLUTTER_ROOT/dev/docs/doc/robots.txt" export FIREBASE_TOKEN="$FIREBASE_MASTER_TOKEN" - deploy 5 master-docs-flutter-io + deploy 5 master-docs-flutter-dev fi if [[ "$CIRRUS_BRANCH" == "stable" ]]; then # Enable search indexing on the master staging site so searches get only # the stable site. - echo "Updating $CIRRUS_BRANCH docs: https://docs.flutter.io/" + echo "Updating $CIRRUS_BRANCH docs: https://api.flutter.dev/" echo -e "# All robots welcome!" > "$FLUTTER_ROOT/dev/docs/doc/robots.txt" export FIREBASE_TOKEN="$FIREBASE_PUBLIC_TOKEN" - deploy 5 docs-flutter-io + deploy 5 docs-flutter-dev fi fi diff --git a/dev/bots/download_android_sdk.sh b/dev/bots/download_android_sdk.sh new file mode 100755 index 0000000000..cafa3f42f1 --- /dev/null +++ b/dev/bots/download_android_sdk.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +set -e + +if [[ -z $ANDROID_SDK_TOOLS_URL || -z $ANDROID_HOME || -z $ANDROID_SDK_ROOT ]]; then + exit 0 +fi + +curl -L $ANDROID_SDK_TOOLS_URL --output android_sdk_tools.zip + +mkdir -p $ANDROID_SDK_ROOT +unzip android_sdk_tools.zip -d $ANDROID_SDK_ROOT +rm android_sdk_tools.zip + +yes | $ANDROID_SDK_ROOT/tools/bin/sdkmanager --licenses +$ANDROID_SDK_ROOT/tools/bin/sdkmanager tools +$ANDROID_SDK_ROOT/tools/bin/sdkmanager platform-tools +# this is large and we don't need it just yet +# $ANDROID_SDK_ROOT/tools/bin/sdkmanager emulator +$ANDROID_SDK_ROOT/tools/bin/sdkmanager "platforms;android-28" \ + "build-tools;28.0.3" \ + "platforms;android-27" \ + "build-tools;27.0.3" \ + "extras;google;m2repository" \ + "extras;android;m2repository" + + diff --git a/dev/bots/download_open_jdk.sh b/dev/bots/download_open_jdk.sh new file mode 100755 index 0000000000..313ce059f0 --- /dev/null +++ b/dev/bots/download_open_jdk.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + +if [[ -z $OPEN_JDK_URL ]]; then + exit 0 +fi + +mkdir -p $HOME/Java +pushd $HOME/Java +curl -L $OPEN_JDK_URL --output open_jdk.tar.gz +tar -xvf open_jdk.tar.gz +rm open_jdk.tar.gz +popd diff --git a/dev/bots/flutter_compact_formatter.dart b/dev/bots/flutter_compact_formatter.dart new file mode 100644 index 0000000000..6433ab7270 --- /dev/null +++ b/dev/bots/flutter_compact_formatter.dart @@ -0,0 +1,270 @@ +// Copyright 2019 The Flutter 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 'dart:convert'; +import 'dart:io'; + +import 'package:meta/meta.dart'; + +final Stopwatch _stopwatch = Stopwatch(); + +/// A wrapper around package:test's JSON reporter. +/// +/// This class behaves similarly to the compact reporter, but supresses all +/// output except for progress until the end of testing. In other words, errors, +/// [print] calls, and skipped test messages will not be printed during the run +/// of the suite. +/// +/// It also processes the JSON data into a collection of [TestResult]s for any +/// other post processing needs, e.g. sending data to analytics. +class FlutterCompactFormatter { + FlutterCompactFormatter() { + _stopwatch.start(); + } + + /// Whether to use color escape codes in writing to stdout. + final bool useColor = stdout.supportsAnsiEscapes; + + /// The terminal escape for green text, or the empty string if this is Windows + /// or not outputting to a terminal. + String get _green => useColor ? '\u001b[32m' : ''; + + /// The terminal escape for red text, or the empty string if this is Windows + /// or not outputting to a terminal. + String get _red => useColor ? '\u001b[31m' : ''; + + /// The terminal escape for yellow text, or the empty string if this is + /// Windows or not outputting to a terminal. + String get _yellow => useColor ? '\u001b[33m' : ''; + + /// The terminal escape for gray text, or the empty string if this is + /// Windows or not outputting to a terminal. + String get _gray => useColor ? '\u001b[1;30m' : ''; + + /// The terminal escape for bold text, or the empty string if this is + /// Windows or not outputting to a terminal. + String get _bold => useColor ? '\u001b[1m' : ''; + + /// The terminal escape for removing test coloring, or the empty string if + /// this is Windows or not outputting to a terminal. + String get _noColor => useColor ? '\u001b[0m' : ''; + + /// The termianl escape for clearing the line, or a carriage return if + /// this is Windows or not outputting to a termianl. + String get _clearLine => useColor ? '\x1b[2K\r' : '\r'; + + final Map _tests = {}; + + /// The test results from this run. + Iterable get tests => _tests.values; + + /// The number of tests that were started. + int started = 0; + + /// The number of test failures. + int failures = 0; + + /// The number of skipped tests. + int skips = 0; + + /// The number of successful tests. + int successes = 0; + + /// Process a single line of JSON output from the JSON test reporter. + /// + /// Callers are responsible for splitting multiple lines before calling this + /// method. + TestResult processRawOutput(String raw) { + assert(raw != null); + // We might be getting messages from Flutter Tool about updating/building. + if (!raw.startsWith('{')) { + print(raw); + return null; + } + final Map decoded = json.decode(raw); + final TestResult originalResult = _tests[decoded['testID']]; + switch (decoded['type']) { + case 'done': + stdout.write(_clearLine); + stdout.write('$_bold${_stopwatch.elapsed}$_noColor '); + stdout.writeln( + '$_green+$successes $_yellow~$skips $_red-$failures:$_bold$_gray Done.$_noColor'); + break; + case 'testStart': + final Map testData = decoded['test']; + if (testData['url'] == null) { + started += 1; + stdout.write(_clearLine); + stdout.write('$_bold${_stopwatch.elapsed}$_noColor '); + stdout.write( + '$_green+$successes $_yellow~$skips $_red-$failures: $_gray${testData['name']}$_noColor'); + break; + } + _tests[testData['id']] = TestResult( + id: testData['id'], + name: testData['name'], + line: testData['root_line'] ?? testData['line'], + column: testData['root_column'] ?? testData['column'], + path: testData['root_url'] ?? testData['url'], + startTime: decoded['time'], + ); + break; + case 'testDone': + if (originalResult == null) { + break; + } + originalResult.endTime = decoded['time']; + if (decoded['skipped'] == true) { + skips += 1; + originalResult.status = TestStatus.skipped; + } else { + if (decoded['result'] == 'success') { + originalResult.status =TestStatus.succeeded; + successes += 1; + } else { + originalResult.status = TestStatus.failed; + failures += 1; + } + } + break; + case 'error': + final String error = decoded['error']; + final String stackTrace = decoded['stackTrace']; + if (originalResult != null) { + originalResult.errorMessage = error; + originalResult.stackTrace = stackTrace; + } else { + if (error != null) + stderr.writeln(error); + if (stackTrace != null) + stderr.writeln(stackTrace); + } + break; + case 'print': + if (originalResult != null) { + originalResult.messages.add(decoded['message']); + } + break; + case 'group': + case 'allSuites': + case 'start': + case 'suite': + default: + break; + } + return originalResult; + } + + /// Print summary of test results. + void finish() { + final List skipped = []; + final List failed = []; + for (TestResult result in _tests.values) { + switch (result.status) { + case TestStatus.started: + failed.add('${_red}Unexpectedly failed to complete a test!'); + failed.add(result.toString() + _noColor); + break; + case TestStatus.skipped: + skipped.add( + '${_yellow}Skipped ${result.name} (${result.pathLineColumn}).$_noColor'); + break; + case TestStatus.failed: + failed.addAll([ + '$_bold${_red}Failed ${result.name} (${result.pathLineColumn}):', + result.errorMessage, + _noColor + _red, + result.stackTrace, + ]); + failed.addAll(result.messages); + failed.add(_noColor); + break; + case TestStatus.succeeded: + break; + } + } + skipped.forEach(print); + failed.forEach(print); + if (failed.isEmpty) { + print('${_green}Completed, $successes test(s) passing ($skips skipped).$_noColor'); + } else { + print('$_gray$failures test(s) failed.$_noColor'); + } + } +} + +/// The state of a test received from the JSON reporter. +enum TestStatus { + /// Test execution has started. + started, + /// Test completed successfully. + succeeded, + /// Test failed. + failed, + /// Test was skipped. + skipped, +} + +/// The detailed status of a test run. +class TestResult { + TestResult({ + @required this.id, + @required this.name, + @required this.line, + @required this.column, + @required this.path, + @required this.startTime, + this.status = TestStatus.started, + }) : assert(id != null), + assert(name != null), + assert(line != null), + assert(column != null), + assert(path != null), + assert(startTime != null), + assert(status != null), + messages = []; + + /// The state of the test. + TestStatus status; + + /// The internal ID of the test used by the JSON reporter. + final int id; + + /// The name of the test, specified via the `test` method. + final String name; + + /// The line number from the original file. + final int line; + + /// The column from the original file. + final int column; + + /// The path of the original test file. + final String path; + + /// A friendly print out of the [path], [line], and [column] of the test. + String get pathLineColumn => '$path:$line:$column'; + + /// The start time of the test, in milliseconds relative to suite startup. + final int startTime; + + /// The stdout of the test. + final List messages; + + /// The error message from the test, from an `expect`, an [Exception] or + /// [Error]. + String errorMessage; + + /// The stacktrace from a test failure. + String stackTrace; + + /// The time, in milliseconds relative to suite startup, that the test ended. + int endTime; + + /// The total time, in milliseconds, that the test took. + int get totalTime => (endTime ?? _stopwatch.elapsedMilliseconds) - startTime; + + @override + String toString() => '{$runtimeType: {$id, $name, ${totalTime}ms, $pathLineColumn}}'; +} diff --git a/dev/bots/prepare_package.dart b/dev/bots/prepare_package.dart index 67636764be..cd4993999c 100644 --- a/dev/bots/prepare_package.dart +++ b/dev/bots/prepare_package.dart @@ -8,10 +8,12 @@ import 'dart:io' hide Platform; import 'dart:typed_data'; import 'package:args/args.dart'; +import 'package:crypto/crypto.dart'; +import 'package:crypto/src/digest_sink.dart'; import 'package:http/http.dart' as http; import 'package:path/path.dart' as path; -import 'package:process/process.dart'; import 'package:platform/platform.dart' show Platform, LocalPlatform; +import 'package:process/process.dart'; const String chromiumRepo = 'https://chromium.googlesource.com/external/github.com/flutter/flutter'; const String githubRepo = 'https://github.com/flutter/flutter.git'; @@ -24,8 +26,8 @@ const String baseUrl = 'https://storage.googleapis.com/flutter_infra'; /// Exception class for when a process fails to run, so we can catch /// it and provide something more readable than a stack trace. -class ProcessRunnerException implements Exception { - ProcessRunnerException(this.message, [this.result]); +class PreparePackageException implements Exception { + PreparePackageException(this.message, [this.result]); final String message; final ProcessResult result; @@ -156,17 +158,17 @@ class ProcessRunner { } on ProcessException catch (e) { final String message = 'Running "${commandLine.join(' ')}" in ${workingDirectory.path} ' 'failed with:\n${e.toString()}'; - throw ProcessRunnerException(message); + throw PreparePackageException(message); } on ArgumentError catch (e) { final String message = 'Running "${commandLine.join(' ')}" in ${workingDirectory.path} ' 'failed with:\n${e.toString()}'; - throw ProcessRunnerException(message); + throw PreparePackageException(message); } final int exitCode = await allComplete(); if (exitCode != 0 && !failOk) { final String message = 'Running "${commandLine.join(' ')}" in ${workingDirectory.path} failed'; - throw ProcessRunnerException( + throw PreparePackageException( message, ProcessResult(0, exitCode, null, 'returned $exitCode'), ); @@ -192,18 +194,19 @@ class ArchiveCreator { this.outputDir, this.revision, this.branch, { + this.strict = true, ProcessManager processManager, bool subprocessOutput = true, this.platform = const LocalPlatform(), HttpReader httpReader, - }) : assert(revision.length == 40), - flutterRoot = Directory(path.join(tempDir.path, 'flutter')), - httpReader = httpReader ?? http.readBytes, - _processRunner = ProcessRunner( - processManager: processManager, - subprocessOutput: subprocessOutput, - platform: platform, - ) { + }) : assert(revision.length == 40), + flutterRoot = Directory(path.join(tempDir.path, 'flutter')), + httpReader = httpReader ?? http.readBytes, + _processRunner = ProcessRunner( + processManager: processManager, + subprocessOutput: subprocessOutput, + platform: platform, + ) { _flutter = path.join( flutterRoot.absolute.path, 'bin', @@ -234,6 +237,11 @@ class ArchiveCreator { /// The directory to write the output file to. final Directory outputDir; + /// True if the creator should be strict about checking requirements or not. + /// + /// In strict mode, will insist that the [revision] be a tagged revision. + final bool strict; + final Uri _minGitUri = Uri.parse(mingitForWindowsUrl); final ProcessRunner _processRunner; @@ -283,10 +291,29 @@ class ArchiveCreator { return _outputFile; } - /// Returns the version number of this release, according the to tags in - /// the repo. + /// Returns the version number of this release, according the to tags in the + /// repo. + /// + /// This looks for the tag attached to [revision] and, if it doesn't find one, + /// git will give an error. + /// + /// If [strict] is true, the exact [revision] must be tagged to return the + /// version. If [strict] is not true, will look backwards in time starting at + /// [revision] to find the most recent version tag. Future _getVersion() async { - return _runGit(['describe', '--tags', '--abbrev=0']); + if (strict) { + try { + return _runGit(['describe', '--tags', '--exact-match', revision]); + } on PreparePackageException catch (exception) { + throw PreparePackageException( + 'Git error when checking for a version tag attached to revision $revision.\n' + 'Perhaps there is no tag at that revision?:\n' + '$exception' + ); + } + } else { + return _runGit(['describe', '--tags', '--abbrev=0', revision]); + } } /// Clone the Flutter repo and make sure that the git environment is sane @@ -311,8 +338,7 @@ class ArchiveCreator { final File gitFile = File(path.join(tempDir.absolute.path, 'mingit.zip')); await gitFile.writeAsBytes(data, flush: true); - final Directory minGitPath = - Directory(path.join(flutterRoot.absolute.path, 'bin', 'mingit')); + final Directory minGitPath = Directory(path.join(flutterRoot.absolute.path, 'bin', 'mingit')); await minGitPath.create(recursive: true); await _unzipArchive(gitFile, workingDirectory: minGitPath); } @@ -435,13 +461,13 @@ class ArchivePublisher { ProcessManager processManager, bool subprocessOutput = true, this.platform = const LocalPlatform(), - }) : assert(revision.length == 40), - platformName = platform.operatingSystem.toLowerCase(), - metadataGsPath = '$gsReleaseFolder/${getMetadataFilename(platform)}', - _processRunner = ProcessRunner( - processManager: processManager, - subprocessOutput: subprocessOutput, - ); + }) : assert(revision.length == 40), + platformName = platform.operatingSystem.toLowerCase(), + metadataGsPath = '$gsReleaseFolder/${getMetadataFilename(platform)}', + _processRunner = ProcessRunner( + processManager: processManager, + subprocessOutput: subprocessOutput, + ); final Platform platform; final String platformName; @@ -456,6 +482,18 @@ class ArchivePublisher { String get destinationArchivePath => '$branchName/$platformName/${path.basename(outputFile.path)}'; static String getMetadataFilename(Platform platform) => 'releases_${platform.operatingSystem.toLowerCase()}.json'; + Future _getChecksum(File archiveFile) async { + final DigestSink digestSink = DigestSink(); + final ByteConversionSink sink = sha256.startChunkedConversion(digestSink); + + final Stream> stream = archiveFile.openRead(); + await stream.forEach((List chunk) { + sink.add(chunk); + }); + sink.close(); + return digestSink.value.toString(); + } + /// Publish the archive to Google Storage. Future publishArchive() async { final String destGsPath = '$gsReleaseFolder/$destinationArchivePath'; @@ -464,7 +502,7 @@ class ArchivePublisher { await _updateMetadata(); } - Map _addRelease(Map jsonData) { + Future> _addRelease(Map jsonData) async { jsonData['base_url'] = '$baseUrl$releaseFolder'; if (!jsonData.containsKey('current_release')) { jsonData['current_release'] = {}; @@ -480,6 +518,7 @@ class ArchivePublisher { newEntry['version'] = version; newEntry['release_date'] = DateTime.now().toUtc().toIso8601String(); newEntry['archive'] = destinationArchivePath; + newEntry['sha256'] = await _getChecksum(outputFile); // Search for any entries with the same hash and channel and remove them. final List releases = jsonData['releases']; @@ -511,17 +550,17 @@ class ArchivePublisher { await _runGsUtil(['cp', metadataGsPath, metadataFile.absolute.path]); final String currentMetadata = metadataFile.readAsStringSync(); if (currentMetadata.isEmpty) { - throw ProcessRunnerException('Empty metadata received from server'); + throw PreparePackageException('Empty metadata received from server'); } Map jsonData; try { jsonData = json.decode(currentMetadata); } on FormatException catch (e) { - throw ProcessRunnerException('Unable to parse JSON metadata received from cloud: $e'); + throw PreparePackageException('Unable to parse JSON metadata received from cloud: $e'); } - jsonData = _addRelease(jsonData); + jsonData = await _addRelease(jsonData); const JsonEncoder encoder = JsonEncoder.withIndent(' '); metadataFile.writeAsStringSync(encoder.convert(jsonData)); @@ -671,7 +710,7 @@ Future main(List rawArguments) async { } final Branch branch = fromBranchName(parsedArguments['branch']); - final ArchiveCreator creator = ArchiveCreator(tempDir, outputDir, revision, branch); + final ArchiveCreator creator = ArchiveCreator(tempDir, outputDir, revision, branch, strict: parsedArguments['publish']); int exitCode = 0; String message; try { @@ -687,7 +726,7 @@ Future main(List rawArguments) async { ); await publisher.publishArchive(); } - } on ProcessRunnerException catch (e) { + } on PreparePackageException catch (e) { exitCode = e.exitCode; message = e.message; } catch (e) { diff --git a/dev/bots/pubspec.yaml b/dev/bots/pubspec.yaml index 33320148bc..f4710b6fb0 100644 --- a/dev/bots/pubspec.yaml +++ b/dev/bots/pubspec.yaml @@ -3,7 +3,7 @@ description: Scripts which run on bots. environment: # The pub client defaults to an <2.0.0 sdk constraint which we need to explicitly overwrite. - sdk: ">=2.0.0-dev.68.0 <3.0.0" + sdk: ">=2.2.0 <3.0.0" dependencies: path: 1.6.2 @@ -14,8 +14,11 @@ dependencies: http: 0.12.0+1 http_parser: 3.1.3 test: 1.5.3 + googleapis: 0.53.0 + googleapis_auth: 0.2.7 - analyzer: 0.35.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + _discoveryapis_commons: 0.1.8+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + analyzer: 0.35.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" async: 2.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -24,23 +27,23 @@ dependencies: crypto: 2.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.14.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" file: 5.0.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - front_end: 0.1.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + front_end: 0.1.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" glob: 1.1.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - html: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + html: 0.13.4+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_multi_server: 2.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" intl: 0.15.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" io: 0.3.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" js: 0.6.1+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" json_rpc_2: 2.0.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - kernel: 0.3.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + kernel: 0.3.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" logging: 0.11.3+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" matcher: 0.12.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" mime: 0.9.6+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" multi_server_socket: 1.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" node_preamble: 1.4.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" package_config: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - package_resolver: 1.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - pedantic: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + package_resolver: 1.0.10 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + pedantic: 1.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" plugin: 0.2.0+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pool: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pub_semver: 1.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -50,7 +53,7 @@ dependencies: shelf_web_socket: 0.2.2+4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" source_map_stack_trace: 1.1.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" source_maps: 0.10.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - source_span: 1.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + source_span: 1.5.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 1.6.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" string_scanner: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -67,4 +70,5 @@ dev_dependencies: mockito: 4.0.0 test_api: 0.2.2 -# PUBSPEC CHECKSUM: 7bc7 + +# PUBSPEC CHECKSUM: 422e diff --git a/dev/bots/run_command.dart b/dev/bots/run_command.dart index c996aae31f..8cf8322ed4 100644 --- a/dev/bots/run_command.dart +++ b/dev/bots/run_command.dart @@ -30,6 +30,53 @@ void printProgress(String action, String workingDir, String command) { print('$arrow $action: cd $cyan$workingDir$reset; $yellow$command$reset'); } +Stream runAndGetStdout(String executable, List arguments, { + String workingDirectory, + Map environment, + bool expectNonZeroExit = false, + int expectedExitCode, + String failureMessage, + Duration timeout = _kLongTimeout, + Function beforeExit, +}) async* { + final String commandDescription = '${path.relative(executable, from: workingDirectory)} ${arguments.join(' ')}'; + final String relativeWorkingDir = path.relative(workingDirectory); + + printProgress('RUNNING', relativeWorkingDir, commandDescription); + + final DateTime start = DateTime.now(); + final Process process = await Process.start(executable, arguments, + workingDirectory: workingDirectory, + environment: environment, + ); + + stderr.addStream(process.stderr); + final Stream lines = process.stdout.transform(utf8.decoder).transform(const LineSplitter()); + await for (String line in lines) { + yield line; + } + + final int exitCode = await process.exitCode.timeout(timeout, onTimeout: () { + stderr.writeln('Process timed out after $timeout'); + return expectNonZeroExit ? 0 : 1; + }); + print('$clock ELAPSED TIME: $bold${elapsedTime(start)}$reset for $commandDescription in $relativeWorkingDir: '); + if ((exitCode == 0) == expectNonZeroExit || (expectedExitCode != null && exitCode != expectedExitCode)) { + if (failureMessage != null) { + print(failureMessage); + } + print( + '$redLine\n' + '${bold}ERROR:$red Last command exited with $exitCode (expected: ${expectNonZeroExit ? (expectedExitCode ?? 'non-zero') : 'zero'}).$reset\n' + '${bold}Command:$cyan $commandDescription$reset\n' + '${bold}Relative working directory:$red $relativeWorkingDir$reset\n' + '$redLine' + ); + beforeExit?.call(); + exit(1); + } +} + Future runCommand(String executable, List arguments, { String workingDirectory, Map environment, @@ -58,7 +105,7 @@ Future runCommand(String executable, List arguments, { if (printOutput) { await Future.wait(>[ stdout.addStream(process.stdout), - stderr.addStream(process.stderr) + stderr.addStream(process.stderr), ]); } else { savedStdout = process.stdout.toList(); diff --git a/dev/bots/serviceaccount.enc b/dev/bots/serviceaccount.enc new file mode 100644 index 0000000000..b9972711e7 Binary files /dev/null and b/dev/bots/serviceaccount.enc differ diff --git a/dev/bots/test.dart b/dev/bots/test.dart index 41dd11ebe9..60a54b8b86 100644 --- a/dev/bots/test.dart +++ b/dev/bots/test.dart @@ -5,8 +5,12 @@ import 'dart:async'; import 'dart:io'; +import 'package:googleapis/bigquery/v2.dart' as bq; +import 'package:googleapis_auth/auth_io.dart' as auth; +import 'package:http/http.dart' as http; import 'package:path/path.dart' as path; +import 'flutter_compact_formatter.dart'; import 'run_command.dart'; typedef ShardRunner = Future Function(); @@ -18,11 +22,18 @@ final String pub = path.join(flutterRoot, 'bin', 'cache', 'dart-sdk', 'bin', Pla final String pubCache = path.join(flutterRoot, '.pub-cache'); final List flutterTestArgs = []; + +final bool useFlutterTestFormatter = Platform.environment['FLUTTER_TEST_FORMATTER'] == 'true'; + +final bool noUseBuildRunner = Platform.environment['FLUTTER_TEST_NO_BUILD_RUNNER'] == 'true'; + const Map _kShards = { 'tests': _runTests, 'tool_tests': _runToolTests, 'build_tests': _runBuildTests, 'coverage': _runCoverage, + 'integration_tests': _runIntegrationTests, + 'add2app_test': _runAdd2AppTest, }; const Duration _kLongTimeout = Duration(minutes: 45); @@ -139,13 +150,48 @@ Future _runSmokeTests() async { await _verifyVersion(path.join(flutterRoot, 'version')); } +Future _getBigqueryApi() async { + if (!useFlutterTestFormatter) { + return null; + } + // TODO(dnfield): How will we do this on LUCI? + final String privateKey = Platform.environment['GCLOUD_SERVICE_ACCOUNT_KEY']; + // If we're on Cirrus and a non-collaborator is doing this, we can't get the key. + if (privateKey == null || privateKey.isEmpty || privateKey.startsWith('ENCRYPTED[')) { + return null; + } + try { + final auth.ServiceAccountCredentials accountCredentials = auth.ServiceAccountCredentials( + 'flutter-ci-test-reporter@flutter-infra.iam.gserviceaccount.com', + auth.ClientId.serviceAccount('114390419920880060881.apps.googleusercontent.com'), + '-----BEGIN PRIVATE KEY-----\n$privateKey\n-----END PRIVATE KEY-----\n', + ); + final List scopes = [bq.BigqueryApi.BigqueryInsertdataScope]; + final http.Client client = await auth.clientViaServiceAccount(accountCredentials, scopes); + return bq.BigqueryApi(client); + } catch (e) { + print('Failed to get BigQuery API client.'); + print(e); + return null; + } +} + Future _runToolTests() async { + final bq.BigqueryApi bigqueryApi = await _getBigqueryApi(); await _runSmokeTests(); - await _pubRunTest( - path.join(flutterRoot, 'packages', 'flutter_tools'), - enableFlutterToolAsserts: true, - ); + if (noUseBuildRunner) { + await _pubRunTest( + path.join(flutterRoot, 'packages', 'flutter_tools'), + tableData: bigqueryApi?.tabledata, + ); + } else { + await _buildRunnerTest( + path.join(flutterRoot, 'packages', 'flutter_tools'), + flutterRoot, + tableData: bigqueryApi?.tabledata, + ); + } print('${bold}DONE: All tests successful.$reset'); } @@ -167,10 +213,22 @@ Future _runBuildTests() async { await _flutterBuildApk(path); await _flutterBuildIpa(path); } + await _flutterBuildDart2js(path.join('dev', 'integration_tests', 'web')); print('${bold}DONE: All build tests successful.$reset'); } +Future _flutterBuildDart2js(String relativePathToApplication) async { + print('Running Dart2JS build tests...'); + await runCommand(flutter, + ['build', 'web', '-v'], + workingDirectory: path.join(flutterRoot, relativePathToApplication), + expectNonZeroExit: false, + timeout: _kShortTimeout, + ); + print('Done.'); +} + Future _flutterBuildAot(String relativePathToApplication) async { print('Running AOT build tests...'); await runCommand(flutter, @@ -183,7 +241,6 @@ Future _flutterBuildAot(String relativePathToApplication) async { } Future _flutterBuildApk(String relativePathToApplication) async { - // TODO(dnfield): See if we can get Android SDK on all Cirrus platforms. if ( (Platform.environment['ANDROID_HOME']?.isEmpty ?? true) && (Platform.environment['ANDROID_SDK_ROOT']?.isEmpty ?? true)) { @@ -224,33 +281,53 @@ Future _flutterBuildIpa(String relativePathToApplication) async { print('Done.'); } +Future _runAdd2AppTest() async { + if (!Platform.isMacOS) { + return; + } + print('Running Add2App iOS integration tests...'); + final String add2AppDir = path.join(flutterRoot, 'dev', 'integration_tests', 'ios_add2app'); + await runCommand('./build_and_test.sh', + [], + workingDirectory: add2AppDir, + expectNonZeroExit: false, + timeout: _kShortTimeout, + ); + print('Done.'); +} + Future _runTests() async { + final bq.BigqueryApi bigqueryApi = await _getBigqueryApi(); await _runSmokeTests(); - await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter')); + await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter'), tableData: bigqueryApi?.tabledata); // Only packages/flutter/test/widgets/widget_inspector_test.dart really // needs to be run with --track-widget-creation but it is nice to run // all of the tests in package:flutter with the flag to ensure that // the Dart kernel transformer triggered by the flag does not break anything. - await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter'), options: ['--track-widget-creation']); - await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_localizations')); - await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_driver')); - await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_test')); - await _runFlutterTest(path.join(flutterRoot, 'packages', 'fuchsia_remote_debug_protocol')); - await _pubRunTest(path.join(flutterRoot, 'dev', 'bots')); - await _pubRunTest(path.join(flutterRoot, 'dev', 'devicelab')); - await _pubRunTest(path.join(flutterRoot, 'dev', 'snippets')); - await _runFlutterTest(path.join(flutterRoot, 'dev', 'integration_tests', 'android_semantics_testing')); - await _runFlutterTest(path.join(flutterRoot, 'dev', 'manual_tests')); - await _runFlutterTest(path.join(flutterRoot, 'dev', 'tools', 'vitool')); - await _runFlutterTest(path.join(flutterRoot, 'examples', 'hello_world')); - await _runFlutterTest(path.join(flutterRoot, 'examples', 'layers')); - await _runFlutterTest(path.join(flutterRoot, 'examples', 'stocks')); - await _runFlutterTest(path.join(flutterRoot, 'examples', 'flutter_gallery')); + await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter'), options: ['--track-widget-creation'], tableData: bigqueryApi?.tabledata); + await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_localizations'), tableData: bigqueryApi?.tabledata); + await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_driver'), tableData: bigqueryApi?.tabledata); + await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_test'), tableData: bigqueryApi?.tabledata); + await _runFlutterTest(path.join(flutterRoot, 'packages', 'fuchsia_remote_debug_protocol'), tableData: bigqueryApi?.tabledata); + await _pubRunTest(path.join(flutterRoot, 'dev', 'bots'), tableData: bigqueryApi?.tabledata); + await _pubRunTest(path.join(flutterRoot, 'dev', 'devicelab'), tableData: bigqueryApi?.tabledata); + await _pubRunTest(path.join(flutterRoot, 'dev', 'snippets'), tableData: bigqueryApi?.tabledata); + await _runFlutterTest(path.join(flutterRoot, 'dev', 'integration_tests', 'android_semantics_testing'), tableData: bigqueryApi?.tabledata); + await _runFlutterTest(path.join(flutterRoot, 'dev', 'manual_tests'), tableData: bigqueryApi?.tabledata); + await _runFlutterTest(path.join(flutterRoot, 'dev', 'tools', 'vitool'), tableData: bigqueryApi?.tabledata); + await _runFlutterTest(path.join(flutterRoot, 'examples', 'hello_world'), tableData: bigqueryApi?.tabledata); + await _runFlutterTest(path.join(flutterRoot, 'examples', 'layers'), tableData: bigqueryApi?.tabledata); + await _runFlutterTest(path.join(flutterRoot, 'examples', 'stocks'), tableData: bigqueryApi?.tabledata); + await _runFlutterTest(path.join(flutterRoot, 'examples', 'flutter_gallery'), tableData: bigqueryApi?.tabledata); // Regression test to ensure that code outside of package:flutter can run // with --track-widget-creation. - await _runFlutterTest(path.join(flutterRoot, 'examples', 'flutter_gallery'), options: ['--track-widget-creation']); - await _runFlutterTest(path.join(flutterRoot, 'examples', 'catalog')); + await _runFlutterTest(path.join(flutterRoot, 'examples', 'flutter_gallery'), options: ['--track-widget-creation'], tableData: bigqueryApi?.tabledata); + await _runFlutterTest(path.join(flutterRoot, 'examples', 'catalog'), tableData: bigqueryApi?.tabledata); + // Smoke test for code generation. + await _runFlutterTest(path.join(flutterRoot, 'dev', 'integration_tests', 'codegen'), tableData: bigqueryApi?.tabledata, environment: { + 'FLUTTER_EXPERIMENTAL_BUILD': 'true', + }); print('${bold}DONE: All tests successful.$reset'); } @@ -277,12 +354,62 @@ Future _runCoverage() async { print('${bold}DONE: Coverage collection successful.$reset'); } +Future _buildRunnerTest( + String workingDirectory, + String flutterRoot, { + String testPath, + bool enableFlutterToolAsserts = false, + bq.TabledataResourceApi tableData, +}) async { + final List args = ['run', 'build_runner', 'test', '--', useFlutterTestFormatter ? '-rjson' : '-rcompact', '-j1']; + if (!hasColor) { + args.add('--no-color'); + } + if (testPath != null) { + args.add(testPath); + } + final Map pubEnvironment = { + 'FLUTTER_ROOT': flutterRoot, + }; + if (Directory(pubCache).existsSync()) { + pubEnvironment['PUB_CACHE'] = pubCache; + } + if (enableFlutterToolAsserts) { + // If an existing env variable exists append to it, but only if + // it doesn't appear to already include enable-asserts. + String toolsArgs = Platform.environment['FLUTTER_TOOL_ARGS'] ?? ''; + if (!toolsArgs.contains('--enable-asserts')) + toolsArgs += ' --enable-asserts'; + pubEnvironment['FLUTTER_TOOL_ARGS'] = toolsArgs.trim(); + } + + if (useFlutterTestFormatter) { + final FlutterCompactFormatter formatter = FlutterCompactFormatter(); + final Stream testOutput = runAndGetStdout( + pub, + args, + workingDirectory: workingDirectory, + environment: pubEnvironment, + beforeExit: formatter.finish + ); + await _processTestOutput(formatter, testOutput, tableData); + } else { + await runCommand( + pub, + args, + workingDirectory:workingDirectory, + environment:pubEnvironment, + ); + } +} + Future _pubRunTest( String workingDirectory, { String testPath, - bool enableFlutterToolAsserts = false -}) { - final List args = ['run', 'test', '-rcompact', '-j1']; + bool enableFlutterToolAsserts = false, + bq.TabledataResourceApi tableData, +}) async { + final List args = ['run', 'test', useFlutterTestFormatter ? '-rjson' : '-rcompact', '-j1']; if (!hasColor) args.add('--no-color'); if (testPath != null) @@ -299,11 +426,150 @@ Future _pubRunTest( toolsArgs += ' --enable-asserts'; pubEnvironment['FLUTTER_TOOL_ARGS'] = toolsArgs.trim(); } - return runCommand( - pub, args, - workingDirectory: workingDirectory, - environment: pubEnvironment, + if (useFlutterTestFormatter) { + final FlutterCompactFormatter formatter = FlutterCompactFormatter(); + final Stream testOutput = runAndGetStdout( + pub, + args, + workingDirectory: workingDirectory, + beforeExit: formatter.finish, + ); + await _processTestOutput(formatter, testOutput, tableData); + } else { + await runCommand( + pub, + args, + workingDirectory:workingDirectory, + ); + } +} + +enum CiProviders { + cirrus, + luci, +} + +CiProviders _getCiProvider() { + if (Platform.environment['CIRRUS_CI'] == 'true') { + return CiProviders.cirrus; + } + if (Platform.environment['LUCI_CONTEXT'] != null) { + return CiProviders.luci; + } + return null; +} + +String _getCiProviderName() { + switch(_getCiProvider()) { + case CiProviders.cirrus: + return 'cirrusci'; + case CiProviders.luci: + return 'luci'; + } + return 'unknown'; +} + +int _getPrNumber() { + switch(_getCiProvider()) { + case CiProviders.cirrus: + return Platform.environment['CIRRUS_PR'] == null + ? -1 + : int.tryParse(Platform.environment['CIRRUS_PR']); + case CiProviders.luci: + return -1; // LUCI doesn't know about this. + } + return -1; +} + +Future _getAuthors() async { + final String exe = Platform.isWindows ? '.exe' : ''; + final String author = await runAndGetStdout( + 'git$exe', ['log', _getGitHash(), '--pretty="%an <%ae>"'], + workingDirectory: flutterRoot, + ).first; + return author; +} + +String _getCiUrl() { + switch(_getCiProvider()) { + case CiProviders.cirrus: + return 'https://cirrus-ci.com/task/${Platform.environment['CIRRUS_TASK_ID']}'; + case CiProviders.luci: + return 'https://ci.chromium.org/p/flutter/g/framework/console'; // TODO(dnfield): can we get a direct link to the actual build? + } + return ''; +} + +String _getGitHash() { + switch(_getCiProvider()) { + case CiProviders.cirrus: + return Platform.environment['CIRRUS_CHANGE_IN_REPO']; + case CiProviders.luci: + return 'HEAD'; // TODO(dnfield): Set this in the env for LUCI. + } + return ''; +} + +Future _processTestOutput( + FlutterCompactFormatter formatter, + Stream testOutput, + bq.TabledataResourceApi tableData, +) async { + final Timer heartbeat = Timer.periodic(const Duration(seconds: 30), (Timer timer) { + print('Processing...'); + }); + + await testOutput.forEach(formatter.processRawOutput); + heartbeat.cancel(); + formatter.finish(); + if (tableData == null || formatter.tests.isEmpty) { + return; + } + final bq.TableDataInsertAllRequest request = bq.TableDataInsertAllRequest(); + final String authors = await _getAuthors(); + request.rows = List.from( + formatter.tests.map((TestResult result) => + bq.TableDataInsertAllRequestRows.fromJson( { + 'json': { + 'source': { + 'provider': _getCiProviderName(), + 'url': _getCiUrl(), + 'platform': { + 'os': Platform.operatingSystem, + 'version': Platform.operatingSystemVersion, + }, + }, + 'test': { + 'name': result.name, + 'result': result.status.toString(), + 'file': result.path, + 'line': result.line, + 'column': result.column, + 'time': result.totalTime, + }, + 'git': { + 'author': authors, + 'pull_request': _getPrNumber(), + 'commit': _getGitHash(), + 'organization': 'flutter', + 'repository': 'flutter', + }, + 'error': result.status != TestStatus.failed ? null : { + 'message': result.errorMessage, + 'stack_trace': result.stackTrace, + }, + 'information': result.messages, + }, + }), + ), + growable: false, ); + final bq.TableDataInsertAllResponse response = await tableData.insertAll(request, 'flutter-infra', 'tests', 'ci'); + if (response.insertErrors != null && response.insertErrors.isNotEmpty) { + print('${red}BigQuery insert errors:'); + print(response.toJson()); + print(reset); + } } class EvalResult { @@ -325,10 +591,18 @@ Future _runFlutterTest(String workingDirectory, { List options = const [], bool skip = false, Duration timeout = _kLongTimeout, -}) { + bq.TabledataResourceApi tableData, + Map environment, +}) async { final List args = ['test']..addAll(options); if (flutterTestArgs != null && flutterTestArgs.isNotEmpty) args.addAll(flutterTestArgs); + + final bool shouldProcessOutput = useFlutterTestFormatter && !expectFailure && !options.contains('--coverage'); + if (shouldProcessOutput) { + args.add('--machine'); + } + if (script != null) { final String fullScriptPath = path.join(workingDirectory, script); if (!FileSystemEntity.isFileSync(fullScriptPath)) { @@ -343,13 +617,38 @@ Future _runFlutterTest(String workingDirectory, { } args.add(script); } - return runCommand(flutter, args, + if (!shouldProcessOutput) { + return runCommand(flutter, args, + workingDirectory: workingDirectory, + expectNonZeroExit: expectFailure, + printOutput: printOutput, + skip: skip, + timeout: timeout, + environment: environment, + ); + } + + if (useFlutterTestFormatter) { + final FlutterCompactFormatter formatter = FlutterCompactFormatter(); + final Stream testOutput = runAndGetStdout( + flutter, + args, workingDirectory: workingDirectory, expectNonZeroExit: expectFailure, - printOutput: printOutput, - skip: skip, timeout: timeout, + beforeExit: formatter.finish, + environment: environment, ); + await _processTestOutput(formatter, testOutput, tableData); + } else { + await runCommand( + flutter, + args, + workingDirectory: workingDirectory, + expectNonZeroExit: expectFailure, + timeout: timeout, + ); + } } Future _verifyVersion(String filename) async { @@ -374,3 +673,51 @@ Future _verifyVersion(String filename) async { exit(1); } } + +Future _runIntegrationTests() async { + print('Platform env vars:'); + + await _runDevicelabTest('dartdocs'); + + if (Platform.isLinux) { + await _runDevicelabTest('flutter_create_offline_test_linux'); + } else if (Platform.isWindows) { + await _runDevicelabTest('flutter_create_offline_test_windows'); + } else if (Platform.isMacOS) { + await _runDevicelabTest('flutter_create_offline_test_mac'); + await _runDevicelabTest('module_test_ios'); + } + await _integrationTestsAndroidSdk(); +} + +Future _runDevicelabTest(String testName, {Map env}) async { + await runCommand( + dart, + ['bin/run.dart', '-t', testName], + workingDirectory: path.join(flutterRoot, 'dev', 'devicelab'), + environment: env, + ); +} + +Future _integrationTestsAndroidSdk() async { + final String androidSdkRoot = (Platform.environment['ANDROID_HOME']?.isEmpty ?? true) + ? Platform.environment['ANDROID_SDK_ROOT'] + : Platform.environment['ANDROID_HOME']; + if (androidSdkRoot == null || androidSdkRoot.isEmpty) { + print('No Android SDK detected, skipping Android Integration Tests'); + return; + } + + final Map env = { + 'ANDROID_HOME': androidSdkRoot, + 'ANDROID_SDK_ROOT': androidSdkRoot, + }; + + // TODO(dnfield): gradlew is crashing on the cirrus image and it's not clear why. + if (!Platform.isWindows) { + await _runDevicelabTest('gradle_plugin_test', env: env); + await _runDevicelabTest('module_test', env: env); + } + // note: this also covers plugin_test_win as long as Windows has an Android SDK available. + await _runDevicelabTest('plugin_test', env: env); +} diff --git a/dev/bots/test/analyze-sample-code-test-input/known_broken_documentation.dart b/dev/bots/test/analyze-sample-code-test-input/known_broken_documentation.dart index e624931f1e..6a00c15f9a 100644 --- a/dev/bots/test/analyze-sample-code-test-input/known_broken_documentation.dart +++ b/dev/bots/test/analyze-sample-code-test-input/known_broken_documentation.dart @@ -18,8 +18,7 @@ /// blabla 0.0, the penzance blabla is blabla not blabla at all. Bla the blabla /// 1.0, the blabla is blabla blabla blabla an blabla blabla. /// -/// ### Sample code -/// +/// {@tool sample} /// Bla blabla blabla some [Text] when the `_blabla` blabla blabla is true, and /// blabla it when it is blabla: /// @@ -29,9 +28,9 @@ /// child: const Text('Poor wandering ones!'), /// ) /// ``` +/// {@end-tool} /// -/// ## Sample code -/// +/// {@tool sample} /// Bla blabla blabla some [Text] when the `_blabla` blabla blabla is true, and /// blabla finale blabla: /// @@ -41,3 +40,4 @@ /// child: const Text('Poor wandering ones!'), /// ) /// ``` +/// {@end-tool} diff --git a/dev/bots/test/analyze-sample-code_test.dart b/dev/bots/test/analyze-sample-code_test.dart index 8d3d883cc9..0d46585a6d 100644 --- a/dev/bots/test/analyze-sample-code_test.dart +++ b/dev/bots/test/analyze-sample-code_test.dart @@ -17,9 +17,9 @@ void main() { ..removeWhere((String line) => line.startsWith('Analyzer output:')); expect(process.exitCode, isNot(equals(0))); expect(stderrLines, [ - 'known_broken_documentation.dart:27:9: new Opacity(', + 'known_broken_documentation.dart:26:9: new Opacity(', '>>> Unnecessary new keyword (unnecessary_new)', - 'known_broken_documentation.dart:39:9: new Opacity(', + 'known_broken_documentation.dart:38:9: new Opacity(', '>>> Unnecessary new keyword (unnecessary_new)', '', 'Found 1 sample code errors.', diff --git a/dev/bots/test/fake_process_manager.dart b/dev/bots/test/fake_process_manager.dart index 35f024b4dc..6a4136cedc 100644 --- a/dev/bots/test/fake_process_manager.dart +++ b/dev/bots/test/fake_process_manager.dart @@ -103,7 +103,7 @@ class FakeProcessManager extends Mock implements ProcessManager { when(runSync( any, environment: anyNamed('environment'), - workingDirectory: anyNamed('workingDirectory') + workingDirectory: anyNamed('workingDirectory'), )).thenAnswer(_nextResultSync); when(runSync(any)).thenAnswer(_nextResultSync); diff --git a/dev/bots/test/fake_process_manager_test.dart b/dev/bots/test/fake_process_manager_test.dart index 8dd8bd979e..54472144e0 100644 --- a/dev/bots/test/fake_process_manager_test.dart +++ b/dev/bots/test/fake_process_manager_test.dart @@ -27,10 +27,10 @@ void main() { test('start works', () async { final Map> calls = >{ 'gsutil acl get gs://flutter_infra/releases/releases.json': [ - ProcessResult(0, 0, 'output1', '') + ProcessResult(0, 0, 'output1', ''), ], 'gsutil cat gs://flutter_infra/releases/releases.json': [ - ProcessResult(0, 0, 'output2', '') + ProcessResult(0, 0, 'output2', ''), ], }; processManager.fakeResults = calls; @@ -49,10 +49,10 @@ void main() { test('run works', () async { final Map> calls = >{ 'gsutil acl get gs://flutter_infra/releases/releases.json': [ - ProcessResult(0, 0, 'output1', '') + ProcessResult(0, 0, 'output1', ''), ], 'gsutil cat gs://flutter_infra/releases/releases.json': [ - ProcessResult(0, 0, 'output2', '') + ProcessResult(0, 0, 'output2', ''), ], }; processManager.fakeResults = calls; @@ -66,10 +66,10 @@ void main() { test('runSync works', () async { final Map> calls = >{ 'gsutil acl get gs://flutter_infra/releases/releases.json': [ - ProcessResult(0, 0, 'output1', '') + ProcessResult(0, 0, 'output1', ''), ], 'gsutil cat gs://flutter_infra/releases/releases.json': [ - ProcessResult(0, 0, 'output2', '') + ProcessResult(0, 0, 'output2', ''), ], }; processManager.fakeResults = calls; @@ -83,10 +83,10 @@ void main() { test('captures stdin', () async { final Map> calls = >{ 'gsutil acl get gs://flutter_infra/releases/releases.json': [ - ProcessResult(0, 0, 'output1', '') + ProcessResult(0, 0, 'output1', ''), ], 'gsutil cat gs://flutter_infra/releases/releases.json': [ - ProcessResult(0, 0, 'output2', '') + ProcessResult(0, 0, 'output2', ''), ], }; processManager.fakeResults = calls; diff --git a/dev/bots/test/prepare_package_test.dart b/dev/bots/test/prepare_package_test.dart index a153078fbc..4fcf50c7ac 100644 --- a/dev/bots/test/prepare_package_test.dart +++ b/dev/bots/test/prepare_package_test.dart @@ -25,10 +25,10 @@ void main() { expectAsync1((List commandLine) async { return processRunner.runProcess(commandLine); })(['this_executable_better_not_exist_2857632534321']), - throwsA(isInstanceOf())); + throwsA(isInstanceOf())); try { await processRunner.runProcess(['this_executable_better_not_exist_2857632534321']); - } on ProcessRunnerException catch (e) { + } on PreparePackageException catch (e) { expect( e.message, contains('Invalid argument(s): Cannot find executable for this_executable_better_not_exist_2857632534321.'), @@ -64,7 +64,7 @@ void main() { expectAsync1((List commandLine) async { return processRunner.runProcess(commandLine); })(['echo', 'test']), - throwsA(isInstanceOf())); + throwsA(isInstanceOf())); }); }); group('ArchiveCreator for $platformName', () { @@ -110,7 +110,7 @@ void main() { 'git clone -b dev https://chromium.googlesource.com/external/github.com/flutter/flutter': null, 'git reset --hard $testRef': null, 'git remote set-url origin https://github.com/flutter/flutter.git': null, - 'git describe --tags --abbrev=0': [ProcessResult(0, 0, 'v1.2.3', '')], + 'git describe --tags --exact-match $testRef': [ProcessResult(0, 0, 'v1.2.3', '')], }; if (platform.isWindows) { calls['7za x ${path.join(tempDir.path, 'mingit.zip')}'] = null; @@ -153,7 +153,7 @@ void main() { 'git clone -b dev https://chromium.googlesource.com/external/github.com/flutter/flutter': null, 'git reset --hard $testRef': null, 'git remote set-url origin https://github.com/flutter/flutter.git': null, - 'git describe --tags --abbrev=0': [ProcessResult(0, 0, 'v1.2.3', '')], + 'git describe --tags --exact-match $testRef': [ProcessResult(0, 0, 'v1.2.3', '')], }; if (platform.isWindows) { calls['7za x ${path.join(tempDir.path, 'mingit.zip')}'] = null; @@ -201,7 +201,54 @@ void main() { }; processManager.fakeResults = calls; expect(expectAsync0(creator.initializeRepo), - throwsA(isInstanceOf())); + throwsA(isInstanceOf())); + }); + + test('non-strict mode calls the right commands', () async { + final String createBase = path.join(tempDir.absolute.path, 'create_'); + final Map> calls = >{ + 'git clone -b dev https://chromium.googlesource.com/external/github.com/flutter/flutter': null, + 'git reset --hard $testRef': null, + 'git remote set-url origin https://github.com/flutter/flutter.git': null, + 'git describe --tags --abbrev=0 $testRef': [ProcessResult(0, 0, 'v1.2.3', '')], + }; + if (platform.isWindows) { + calls['7za x ${path.join(tempDir.path, 'mingit.zip')}'] = null; + } + calls.addAll(>{ + '$flutter doctor': null, + '$flutter update-packages': null, + '$flutter precache': null, + '$flutter ide-config': null, + '$flutter create --template=app ${createBase}app': null, + '$flutter create --template=package ${createBase}package': null, + '$flutter create --template=plugin ${createBase}plugin': null, + 'git clean -f -X **/.packages': null, + }); + final String archiveName = path.join(tempDir.absolute.path, + 'flutter_${platformName}_v1.2.3-dev${platform.isLinux ? '.tar.xz' : '.zip'}'); + if (platform.isWindows) { + calls['7za a -tzip -mx=9 $archiveName flutter'] = null; + } else if (platform.isMacOS) { + calls['zip -r -9 $archiveName flutter'] = null; + } else if (platform.isLinux) { + calls['tar cJf $archiveName flutter'] = null; + } + processManager.fakeResults = calls; + creator = ArchiveCreator( + tempDir, + tempDir, + testRef, + Branch.dev, + strict: false, + processManager: processManager, + subprocessOutput: false, + platform: platform, + httpReader: fakeHttpReader, + ); + await creator.initializeRepo(); + await creator.createArchive(); + processManager.verifyCalls(calls.keys.toList()); }); }); @@ -238,26 +285,30 @@ void main() { "channel": "dev", "version": "v0.2.3", "release_date": "2018-03-20T01:47:02.851729Z", - "archive": "dev/$platformName/flutter_${platformName}_v0.2.3-dev.zip" + "archive": "dev/$platformName/flutter_${platformName}_v0.2.3-dev.zip", + "sha256": "4fe85a822093e81cb5a66c7fc263f68de39b5797b294191b6d75e7afcc86aff8" }, { "hash": "b9bd51cc36b706215915711e580851901faebb40", "channel": "beta", "version": "v0.2.2", "release_date": "2018-03-16T18:48:13.375013Z", - "archive": "dev/$platformName/flutter_${platformName}_v0.2.2-dev.zip" + "archive": "dev/$platformName/flutter_${platformName}_v0.2.2-dev.zip", + "sha256": "6073331168cdb37a4637a5dc073d6a7ef4e466321effa2c529fa27d2253a4d4b" }, { "hash": "$testRef", "channel": "stable", "version": "v0.0.0", "release_date": "2018-03-20T01:47:02.851729Z", - "archive": "stable/$platformName/flutter_${platformName}_v0.0.0-dev.zip" + "archive": "stable/$platformName/flutter_${platformName}_v0.0.0-dev.zip", + "sha256": "5dd34873b3a3e214a32fd30c2c319a0f46e608afb72f0d450b2d621a6d02aebd" } ] } '''; File(jsonPath).writeAsStringSync(releasesJson); + File(archivePath).writeAsStringSync('archive contents'); final String gsutilCall = platform.isWindows ? 'python ${path.join("D:", "depot_tools", "gsutil.py")}' : 'gsutil.py'; @@ -291,6 +342,7 @@ void main() { expect(contents, contains('"hash": "$testRef"')); expect(contents, contains('"channel": "stable"')); expect(contents, contains('"archive": "stable/$platformName/$archiveName"')); + expect(contents, contains('"sha256": "f69f4865f861193a91d1c5544a894167a7137b788d10bac8edbf5d095f45cb4d"')); // Make sure existing entries are preserved. expect(contents, contains('"hash": "5a58b36e36b8d7aace89d3950e6deb307956a6a0"')); expect(contents, contains('"hash": "b9bd51cc36b706215915711e580851901faebb40"')); diff --git a/dev/devicelab/bin/tasks/codegen_integration_linux.dart b/dev/devicelab/bin/tasks/codegen_integration_linux.dart new file mode 100644 index 0000000000..2074b422d4 --- /dev/null +++ b/dev/devicelab/bin/tasks/codegen_integration_linux.dart @@ -0,0 +1,20 @@ +// 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 'dart:async'; +import 'dart:io'; + +import 'package:path/path.dart' as path; + +import 'package:flutter_devicelab/framework/adb.dart'; +import 'package:flutter_devicelab/framework/framework.dart'; +import 'package:flutter_devicelab/framework/utils.dart'; +import 'package:flutter_devicelab/tasks/integration_tests.dart'; + +final Directory codegenAppPath = dir(path.join(flutterDirectory.path, 'dev/integration_tests/codegen')); + +Future main() async { + deviceOperatingSystem = DeviceOperatingSystem.android; + await task(createCodegenerationIntegrationTest()); +} diff --git a/dev/devicelab/bin/tasks/codegen_integration_mac.dart b/dev/devicelab/bin/tasks/codegen_integration_mac.dart new file mode 100644 index 0000000000..cdeaea7c24 --- /dev/null +++ b/dev/devicelab/bin/tasks/codegen_integration_mac.dart @@ -0,0 +1,20 @@ +// 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 'dart:async'; +import 'dart:io'; + +import 'package:path/path.dart' as path; + +import 'package:flutter_devicelab/framework/adb.dart'; +import 'package:flutter_devicelab/framework/framework.dart'; +import 'package:flutter_devicelab/framework/utils.dart'; +import 'package:flutter_devicelab/tasks/integration_tests.dart'; + +final Directory codegenAppPath = dir(path.join(flutterDirectory.path, 'dev/integration_tests/codegen')); + +Future main() async { + deviceOperatingSystem = DeviceOperatingSystem.ios; + await task(createCodegenerationIntegrationTest()); +} diff --git a/dev/devicelab/bin/tasks/codegen_integration_win.dart b/dev/devicelab/bin/tasks/codegen_integration_win.dart new file mode 100644 index 0000000000..2074b422d4 --- /dev/null +++ b/dev/devicelab/bin/tasks/codegen_integration_win.dart @@ -0,0 +1,20 @@ +// 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 'dart:async'; +import 'dart:io'; + +import 'package:path/path.dart' as path; + +import 'package:flutter_devicelab/framework/adb.dart'; +import 'package:flutter_devicelab/framework/framework.dart'; +import 'package:flutter_devicelab/framework/utils.dart'; +import 'package:flutter_devicelab/tasks/integration_tests.dart'; + +final Directory codegenAppPath = dir(path.join(flutterDirectory.path, 'dev/integration_tests/codegen')); + +Future main() async { + deviceOperatingSystem = DeviceOperatingSystem.android; + await task(createCodegenerationIntegrationTest()); +} diff --git a/dev/devicelab/bin/tasks/cubic_bezier_perf__timeline_summary.dart b/dev/devicelab/bin/tasks/cubic_bezier_perf__timeline_summary.dart new file mode 100644 index 0000000000..92e42cc5a9 --- /dev/null +++ b/dev/devicelab/bin/tasks/cubic_bezier_perf__timeline_summary.dart @@ -0,0 +1,14 @@ +// 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 'dart:async'; + +import 'package:flutter_devicelab/tasks/perf_tests.dart'; +import 'package:flutter_devicelab/framework/adb.dart'; +import 'package:flutter_devicelab/framework/framework.dart'; + +Future main() async { + deviceOperatingSystem = DeviceOperatingSystem.android; + await task(createCubicBezierPerfTest()); +} diff --git a/dev/devicelab/bin/tasks/flutter_run_test.dart b/dev/devicelab/bin/tasks/flutter_run_test.dart index bc76e627e8..940e05b88c 100644 --- a/dev/devicelab/bin/tasks/flutter_run_test.dart +++ b/dev/devicelab/bin/tasks/flutter_run_test.dart @@ -41,7 +41,7 @@ Future createFlutterRunTask() async { startProcess( path.join(flutterDirectory.path, 'bin', 'flutter'), ['run']..addAll(options), - environment: null + environment: null, ); final Completer finished = Completer(); final StreamSubscription subscription = device.logcat.listen((String line) { diff --git a/dev/devicelab/bin/tasks/gradle_plugin_test.dart b/dev/devicelab/bin/tasks/gradle_plugin_test.dart index bbb1db016b..c46c32705e 100644 --- a/dev/devicelab/bin/tasks/gradle_plugin_test.dart +++ b/dev/devicelab/bin/tasks/gradle_plugin_test.dart @@ -272,11 +272,14 @@ Future _resultOfGradleTask({String workingDirectory, String task, if (options != null) { args.addAll(options); } + final String gradle = Platform.isWindows ? 'gradlew.bat' : './gradlew'; + print('Running Gradle: ${path.join(workingDirectory, gradle)} ${args.join(' ')}'); + print(File(path.join(workingDirectory, gradle)).readAsStringSync()); return Process.run( - './gradlew', + gradle, args, workingDirectory: workingDirectory, - environment: { 'JAVA_HOME': javaHome } + environment: { 'JAVA_HOME': javaHome }, ); } diff --git a/dev/devicelab/bin/tasks/module_test.dart b/dev/devicelab/bin/tasks/module_test.dart index 54356fd7b7..0eb67c34b7 100644 --- a/dev/devicelab/bin/tasks/module_test.dart +++ b/dev/devicelab/bin/tasks/module_test.dart @@ -9,6 +9,9 @@ import 'package:flutter_devicelab/framework/framework.dart'; import 'package:flutter_devicelab/framework/utils.dart'; import 'package:path/path.dart' as path; +final String gradlew = Platform.isWindows ? 'gradlew.bat' : 'gradlew'; +final String gradlewExecutable = Platform.isWindows ? gradlew : './$gradlew'; + /// Tests that the Flutter module project template works and supports /// adding Flutter to an existing Android app. Future main() async { @@ -53,7 +56,7 @@ Future main() async { await inDirectory(Directory(path.join(projectDir.path, '.android')), () async { await exec( - './gradlew', + gradlewExecutable, ['flutter:assembleDebug'], environment: { 'JAVA_HOME': javaHome }, ); @@ -143,7 +146,7 @@ Future main() async { hostApp, ); copy( - File(path.join(projectDir.path, '.android', 'gradlew')), + File(path.join(projectDir.path, '.android', gradlew)), hostApp, ); copy( @@ -152,8 +155,10 @@ Future main() async { ); await inDirectory(hostApp, () async { - await exec('chmod', ['+x', 'gradlew']); - await exec('./gradlew', + if (!Platform.isWindows) { + await exec('chmod', ['+x', 'gradlew']); + } + await exec(gradlewExecutable, ['app:assembleDebug'], environment: { 'JAVA_HOME': javaHome }, ); diff --git a/dev/devicelab/bin/tasks/module_test_ios.dart b/dev/devicelab/bin/tasks/module_test_ios.dart index d78840fcaf..d24359e359 100644 --- a/dev/devicelab/bin/tasks/module_test_ios.dart +++ b/dev/devicelab/bin/tasks/module_test_ios.dart @@ -26,7 +26,7 @@ Future main() async { '--org', 'io.flutter.devicelab', '--template=module', - 'hello' + 'hello', ], ); }); @@ -37,7 +37,7 @@ Future main() async { await inDirectory(projectDir, () async { await flutter( 'build', - options: ['ios'], + options: ['ios', '--no-codesign'], ); }); @@ -80,7 +80,7 @@ Future main() async { await inDirectory(projectDir, () async { await flutter( 'build', - options: ['ios'], + options: ['ios', '--no-codesign'], ); }); @@ -116,7 +116,7 @@ Future main() async { await inDirectory(projectDir, () async { await flutter( 'build', - options: ['ios'], + options: ['ios', '--no-codesign'], ); }); diff --git a/dev/devicelab/bin/tasks/run_machine_concurrent_hot_reload.dart b/dev/devicelab/bin/tasks/run_machine_concurrent_hot_reload.dart index ee8c86c3ae..817fbad007 100644 --- a/dev/devicelab/bin/tasks/run_machine_concurrent_hot_reload.dart +++ b/dev/devicelab/bin/tasks/run_machine_concurrent_hot_reload.dart @@ -100,7 +100,7 @@ void main() { final Map req = { 'id': requestId, 'method': method, - 'params': params + 'params': params, }; final String jsonEncoded = json.encode(>[req]); print('run:stdin: $jsonEncoded'); diff --git a/dev/devicelab/bin/tasks/run_without_leak_linux.dart b/dev/devicelab/bin/tasks/run_without_leak_linux.dart new file mode 100644 index 0000000000..614ea70229 --- /dev/null +++ b/dev/devicelab/bin/tasks/run_without_leak_linux.dart @@ -0,0 +1,14 @@ +// Copyright (c) 2019 The Flutter 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 'dart:async'; + +import 'package:flutter_devicelab/framework/utils.dart'; +import 'package:flutter_devicelab/tasks/run_without_leak.dart'; +import 'package:flutter_devicelab/framework/framework.dart'; +import 'package:path/path.dart' as path; + +Future main() async { + await task(createRunWithoutLeakTest(path.join(flutterDirectory.path, 'examples', 'hello_world'))); +} diff --git a/dev/devicelab/bin/tasks/run_without_leak_mac.dart b/dev/devicelab/bin/tasks/run_without_leak_mac.dart new file mode 100644 index 0000000000..614ea70229 --- /dev/null +++ b/dev/devicelab/bin/tasks/run_without_leak_mac.dart @@ -0,0 +1,14 @@ +// Copyright (c) 2019 The Flutter 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 'dart:async'; + +import 'package:flutter_devicelab/framework/utils.dart'; +import 'package:flutter_devicelab/tasks/run_without_leak.dart'; +import 'package:flutter_devicelab/framework/framework.dart'; +import 'package:path/path.dart' as path; + +Future main() async { + await task(createRunWithoutLeakTest(path.join(flutterDirectory.path, 'examples', 'hello_world'))); +} diff --git a/dev/devicelab/bin/tasks/run_without_leak_win.dart b/dev/devicelab/bin/tasks/run_without_leak_win.dart new file mode 100644 index 0000000000..614ea70229 --- /dev/null +++ b/dev/devicelab/bin/tasks/run_without_leak_win.dart @@ -0,0 +1,14 @@ +// Copyright (c) 2019 The Flutter 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 'dart:async'; + +import 'package:flutter_devicelab/framework/utils.dart'; +import 'package:flutter_devicelab/tasks/run_without_leak.dart'; +import 'package:flutter_devicelab/framework/framework.dart'; +import 'package:path/path.dart' as path; + +Future main() async { + await task(createRunWithoutLeakTest(path.join(flutterDirectory.path, 'examples', 'hello_world'))); +} diff --git a/dev/devicelab/lib/framework/adb.dart b/dev/devicelab/lib/framework/adb.dart index 86aa04965c..3f0bbded58 100644 --- a/dev/devicelab/lib/framework/adb.dart +++ b/dev/devicelab/lib/framework/adb.dart @@ -296,7 +296,16 @@ class AndroidDevice implements Device { stream = StreamController( onListen: () async { await adb(['logcat', '--clear']); - final Process process = await startProcess(adbPath, ['-s', deviceId, 'logcat']); + final Process process = await startProcess( + adbPath, + // Make logcat less chatty by filtering down to just ActivityManager + // (to let us know when app starts), flutter (needed by tests to see + // log output), and fatal messages (hopefully catches tombstones). + // For local testing, this can just be: + // ['-s', deviceId, 'logcat'] + // to view the whole log, or just run logcat alongside this. + ['-s', deviceId, 'logcat', 'ActivityManager:I', 'flutter:V', '*:F'], + ); process.stdout .transform(utf8.decoder) .transform(const LineSplitter()) diff --git a/dev/devicelab/lib/framework/framework.dart b/dev/devicelab/lib/framework/framework.dart index b3063a54e6..34d2f6469a 100644 --- a/dev/devicelab/lib/framework/framework.dart +++ b/dev/devicelab/lib/framework/framework.dart @@ -11,6 +11,7 @@ import 'dart:isolate'; import 'package:logging/logging.dart'; import 'package:stack_trace/stack_trace.dart'; +import 'running_processes.dart'; import 'utils.dart'; /// Maximum amount of time a single task is allowed to take to run. @@ -82,7 +83,35 @@ class _TaskRunner { try { _taskStarted = true; print('Running task.'); - final TaskResult result = await _performTask().timeout(taskTimeout); + final String exe = Platform.isWindows ? '.exe' : ''; + section('Checking running Dart$exe processes'); + final Set beforeRunningDartInstances = await getRunningProcesses( + processName: 'dart$exe', + ).toSet(); + beforeRunningDartInstances.forEach(print); + + TaskResult result = await _performTask().timeout(taskTimeout); + + section('Checking running Dart$exe processes after task...'); + final List afterRunningDartInstances = await getRunningProcesses( + processName: 'dart$exe', + ).toList(); + for (final RunningProcessInfo info in afterRunningDartInstances) { + if (!beforeRunningDartInstances.contains(info)) { + print('$info was leaked by this test.'); + // TODO(dnfield): remove this special casing after https://github.com/flutter/flutter/issues/29141 is resolved. + if (result is TaskResultCheckProcesses) { + result = TaskResult.failure('This test leaked dart processes'); + } + final bool killed = await killProcess(info.pid); + if (!killed) { + print('Failed to kill process ${info.pid}.'); + } else { + print('Killed process id ${info.pid}.'); + } + } + } + _completer.complete(result); return result; } on TimeoutException catch (_) { @@ -231,3 +260,7 @@ class TaskResult { return json; } } + +class TaskResultCheckProcesses extends TaskResult { + TaskResultCheckProcesses() : super.success(null); +} diff --git a/dev/devicelab/lib/framework/ios.dart b/dev/devicelab/lib/framework/ios.dart index 2211cd385d..bb1c63560f 100644 --- a/dev/devicelab/lib/framework/ios.dart +++ b/dev/devicelab/lib/framework/ios.dart @@ -40,7 +40,7 @@ Future _patchXcconfigFilesIfNotPatched(String flutterProjectPath) async { final List xcconfigFiles = [ _fs.file(path.join(flutterProjectPath, 'ios/Flutter/Flutter.xcconfig')), _fs.file(path.join(flutterProjectPath, 'ios/Flutter/Debug.xcconfig')), - _fs.file(path.join(flutterProjectPath, 'ios/Flutter/Release.xcconfig')) + _fs.file(path.join(flutterProjectPath, 'ios/Flutter/Release.xcconfig')), ]; bool xcconfigFileExists = false; diff --git a/dev/devicelab/lib/framework/running_processes.dart b/dev/devicelab/lib/framework/running_processes.dart new file mode 100644 index 0000000000..0efb77c4a4 --- /dev/null +++ b/dev/devicelab/lib/framework/running_processes.dart @@ -0,0 +1,261 @@ +// Copyright 2019 The Flutter 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 'dart:io'; + +import 'package:meta/meta.dart'; +import 'package:process/process.dart'; + +@immutable +class RunningProcessInfo { + const RunningProcessInfo(this.pid, this.creationDate, this.commandLine) + : assert(pid != null), + assert(commandLine != null); + + final String commandLine; + final int pid; + final DateTime creationDate; + + @override + bool operator ==(Object other) { + return other is RunningProcessInfo && + other.pid == pid && + other.commandLine == commandLine && + other.creationDate == creationDate; + } + + @override + int get hashCode { + // TODO(dnfield): Replace this when Object.hashValues lands. + int hash = 17; + if (pid != null) { + hash = hash * 23 + pid.hashCode; + } + if (commandLine != null) { + hash = hash * 23 + commandLine.hashCode; + } + if (creationDate != null) { + hash = hash * 23 + creationDate.hashCode; + } + return hash; + } + + @override + String toString() { + return 'RunningProcesses{pid: $pid, commandLine: $commandLine, creationDate: $creationDate}'; + } +} + +Future killProcess(int pid, {ProcessManager processManager}) async { + assert(pid != null, 'Must specify a pid to kill'); + processManager ??= const LocalProcessManager(); + ProcessResult result; + if (Platform.isWindows) { + result = await processManager.run([ + 'taskkill.exe', + '/pid', + pid.toString(), + '/f', + ]); + } else { + result = await processManager.run([ + 'kill', + '-9', + pid.toString(), + ]); + } + return result.exitCode == 0; +} + +Stream getRunningProcesses({ + String processName, + ProcessManager processManager, +}) { + processManager ??= const LocalProcessManager(); + if (Platform.isWindows) { + return windowsRunningProcesses(processName); + } + return posixRunningProcesses(processName, processManager); +} + +@visibleForTesting +Stream windowsRunningProcesses(String processName) async* { + // PowerShell script to get the command line arguments and create time of + // a process. + // See: https://docs.microsoft.com/en-us/windows/desktop/cimwin32prov/win32-process + final String script = processName != null + ? '"Get-CimInstance Win32_Process -Filter \\\"name=\'$processName\'\\\" | Select-Object ProcessId,CreationDate,CommandLine | Format-Table -AutoSize | Out-String -Width 4096"' + : '"Get-CimInstance Win32_Process | Select-Object ProcessId,CreationDate,CommandLine | Format-Table -AutoSize | Out-String -Width 4096"'; + // Unfortunately, there doesn't seem to be a good way to get ProcessManager to + // run this. May be a bug in Dart. + // TODO(dnfield): fix this when https://github.com/dart-lang/sdk/issues/36175 is resolved. + final ProcessResult result = await Process.run( + 'powershell -command $script', + [], + ); + if (result.exitCode != 0) { + print('Could not list processes!'); + print(result.stderr); + print(result.stdout); + return; + } + for (RunningProcessInfo info in processPowershellOutput(result.stdout)) { + yield info; + } +} + +/// Parses the output of the PowerShell script from [windowsRunningProcesses]. +/// +/// E.g.: +/// ProcessId CreationDate CommandLine +/// --------- ------------ ----------- +/// 2904 3/11/2019 11:01:54 AM "C:\Program Files\Android\Android Studio\jre\bin\java.exe" -Xmx1536M -Dfile.encoding=windows-1252 -Duser.country=US -Duser.language=en -Duser.variant -cp C:\Users\win1\.gradle\wrapper\dists\gradle-4.10.2-all\9fahxiiecdb76a5g3aw9oi8rv\gradle-4.10.2\lib\gradle-launcher-4.10.2.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 4.10.2 +@visibleForTesting +Iterable processPowershellOutput(String output) sync* { + if (output == null) { + return; + } + + const int processIdHeaderSize = 'ProcessId'.length; + const int creationDateHeaderStart = processIdHeaderSize + 1; + int creationDateHeaderEnd; + int commandLineHeaderStart; + bool inTableBody = false; + for (String line in output.split('\n')) { + if (line.startsWith('ProcessId')) { + commandLineHeaderStart = line.indexOf('CommandLine'); + creationDateHeaderEnd = commandLineHeaderStart - 1; + } + if (line.startsWith('--------- ------------')) { + inTableBody = true; + continue; + } + if (!inTableBody || line.isEmpty) { + continue; + } + if (line.length < commandLineHeaderStart) { + continue; + } + + // 3/11/2019 11:01:54 AM + // 12/11/2019 11:01:54 AM + String rawTime = line.substring( + creationDateHeaderStart, + creationDateHeaderEnd, + ).trim(); + + if (rawTime[1] == '/') { + rawTime = '0$rawTime'; + } + if (rawTime[4] == '/') { + rawTime = rawTime.substring(0, 3) + '0' + rawTime.substring(3); + } + final String year = rawTime.substring(6, 10); + final String month = rawTime.substring(3, 5); + final String day = rawTime.substring(0, 2); + String time = rawTime.substring(11, 19); + if (time[7] == ' ') { + time = '0$time'.trim(); + } + if (rawTime.endsWith('PM')) { + final int hours = int.parse(time.substring(0, 2)); + time = '${hours + 12}${time.substring(2)}'; + } + + final int pid = int.parse(line.substring(0, processIdHeaderSize).trim()); + final DateTime creationDate = DateTime.parse('$year-$month-${day}T$time'); + final String commandLine = line.substring(commandLineHeaderStart).trim(); + yield RunningProcessInfo(pid, creationDate, commandLine); + } +} + +@visibleForTesting +Stream posixRunningProcesses( + String processName, + ProcessManager processManager, +) async* { + // Cirrus is missing this in Linux for some reason. + if (!processManager.canRun('ps')) { + print('Cannot list processes on this system: `ps` not available.'); + return; + } + final ProcessResult result = await processManager.run([ + 'ps', + '-eo', + 'lstart,pid,command', + ]); + if (result.exitCode != 0) { + print('Could not list processes!'); + print(result.stderr); + print(result.stdout); + return; + } + for (RunningProcessInfo info in processPsOutput(result.stdout, processName)) { + yield info; + } +} + +/// Parses the output of the command in [posixRunningProcesses]. +/// +/// E.g.: +/// +/// STARTED PID COMMAND +/// Sat Mar 9 20:12:47 2019 1 /sbin/launchd +/// Sat Mar 9 20:13:00 2019 49 /usr/sbin/syslogd +@visibleForTesting +Iterable processPsOutput( + String output, + String processName, +) sync* { + if (output == null) { + return; + } + bool inTableBody = false; + for (String line in output.split('\n')) { + if (line.trim().startsWith('STARTED')) { + inTableBody = true; + continue; + } + if (!inTableBody || line.isEmpty) { + continue; + } + + if (processName != null && !line.contains(processName)) { + continue; + } + if (line.length < 25) { + continue; + } + + // 'Sat Feb 16 02:29:55 2019' + // 'Sat Mar 9 20:12:47 2019' + const Map months = { + 'Jan': '01', + 'Feb': '02', + 'Mar': '03', + 'Apr': '04', + 'May': '05', + 'Jun': '06', + 'Jul': '07', + 'Aug': '08', + 'Sep': '09', + 'Oct': '10', + 'Nov': '11', + 'Dec': '12', + }; + final String rawTime = line.substring(0, 24); + + final String year = rawTime.substring(20, 24); + final String month = months[rawTime.substring(4, 7)]; + final String day = rawTime.substring(8, 10).replaceFirst(' ', '0'); + final String time = rawTime.substring(11, 19); + + final DateTime creationDate = DateTime.parse('$year-$month-${day}T$time'); + line = line.substring(24).trim(); + final int nextSpace = line.indexOf(' '); + final int pid = int.parse(line.substring(0, nextSpace)); + final String commandLine = line.substring(nextSpace + 1); + yield RunningProcessInfo(pid, creationDate, commandLine); + } +} diff --git a/dev/devicelab/lib/tasks/hot_mode_tests.dart b/dev/devicelab/lib/tasks/hot_mode_tests.dart index 8980128275..10fa92488e 100644 --- a/dev/devicelab/lib/tasks/hot_mode_tests.dart +++ b/dev/devicelab/lib/tasks/hot_mode_tests.dart @@ -23,7 +23,7 @@ TaskFunction createHotModeTest() { final File benchmarkFile = file(path.join(_editedFlutterGalleryDir.path, 'hot_benchmark.json')); rm(benchmarkFile); final List options = [ - '--hot', '-d', device.deviceId, '--benchmark', '--verbose', '--resident' + '--hot', '-d', device.deviceId, '--benchmark', '--verbose', '--resident', ]; setLocalEngineOptionIfNecessary(options); int hotReloadCount = 0; @@ -40,7 +40,7 @@ TaskFunction createHotModeTest() { final Process process = await startProcess( path.join(flutterDirectory.path, 'bin', 'flutter'), ['run']..addAll(options), - environment: null + environment: null, ); final Completer stdoutDone = Completer(); @@ -53,11 +53,11 @@ TaskFunction createHotModeTest() { if (hotReloadCount == 0) { // Update the file and reload again. final File appDartSource = file(path.join( - _editedFlutterGalleryDir.path, 'lib/gallery/app.dart' + _editedFlutterGalleryDir.path, 'lib/gallery/app.dart', )); appDartSource.writeAsStringSync( appDartSource.readAsStringSync().replaceFirst( - "'Flutter Gallery'", "'Updated Flutter Gallery'" + "'Flutter Gallery'", "'Updated Flutter Gallery'", ) ); process.stdin.writeln('r'); @@ -94,7 +94,7 @@ TaskFunction createHotModeTest() { final Process process = await startProcess( path.join(flutterDirectory.path, 'bin', 'flutter'), ['run']..addAll(options), - environment: null + environment: null, ); final Completer stdoutDone = Completer(); final Completer stderrDone = Completer(); @@ -156,7 +156,7 @@ TaskFunction createHotModeTest() { 'hotReloadFlutterReassembleMillisecondsAfterChange', 'hotReloadVMReloadMillisecondsAfterChange', 'hotReloadInitialDevFSSyncAfterRelaunchMilliseconds', - ] + ], ); }; } diff --git a/dev/devicelab/lib/tasks/integration_tests.dart b/dev/devicelab/lib/tasks/integration_tests.dart index e38f4a2284..e59337bc1e 100644 --- a/dev/devicelab/lib/tasks/integration_tests.dart +++ b/dev/devicelab/lib/tasks/integration_tests.dart @@ -29,7 +29,7 @@ TaskFunction createFlavorsTest() { return DriverTest( '${flutterDirectory.path}/dev/integration_tests/flavors', 'lib/main.dart', - extraOptions: ['--flavor', 'paid'] + extraOptions: ['--flavor', 'paid'], ); } @@ -61,6 +61,16 @@ TaskFunction createAndroidSemanticsIntegrationTest() { ); } +TaskFunction createCodegenerationIntegrationTest() { + return DriverTest( + '${flutterDirectory.path}/dev/integration_tests/codegen', + 'lib/main.dart', + environment: { + 'FLUTTER_EXPERIMENTAL_BUILD': 'true', + }, + ); +} + TaskFunction createFlutterCreateOfflineTest() { return () async { final Directory tempDir = Directory.systemTemp.createTempSync('flutter_create_test.'); @@ -83,12 +93,14 @@ class DriverTest { this.testDirectory, this.testTarget, { this.extraOptions = const [], + this.environment = const {}, } ); final String testDirectory; final String testTarget; final List extraOptions; + final Map environment; Future call() { return inDirectory(testDirectory, () async { @@ -107,7 +119,7 @@ class DriverTest { deviceId, ]; options.addAll(extraOptions); - await flutter('drive', options: options); + await flutter('drive', options: options, environment: Map.from(environment)); return TaskResult.success(null); }); diff --git a/dev/devicelab/lib/tasks/perf_tests.dart b/dev/devicelab/lib/tasks/perf_tests.dart index 2132132fb5..515d122636 100644 --- a/dev/devicelab/lib/tasks/perf_tests.dart +++ b/dev/devicelab/lib/tasks/perf_tests.dart @@ -46,6 +46,14 @@ TaskFunction createCullOpacityPerfTest() { ).run; } +TaskFunction createCubicBezierPerfTest() { + return PerfTest( + '${flutterDirectory.path}/dev/benchmarks/macrobenchmarks', + 'test_driver/cubic_bezier_perf.dart', + 'cubic_bezier_perf', + ).run; +} + TaskFunction createFlutterGalleryStartupTest() { return StartupTest( '${flutterDirectory.path}/examples/flutter_gallery', @@ -412,7 +420,7 @@ class MemoryTest { _receivedNextMessage = Completer(); } - int get iterationCount => 15; + int get iterationCount => 10; Device get device => _device; Device _device; diff --git a/dev/devicelab/lib/tasks/plugin_tests.dart b/dev/devicelab/lib/tasks/plugin_tests.dart index 6c2789b9cf..cc9e7b2849 100644 --- a/dev/devicelab/lib/tasks/plugin_tests.dart +++ b/dev/devicelab/lib/tasks/plugin_tests.dart @@ -65,7 +65,7 @@ class FlutterProject { await inDirectory(directory, () async { await flutter( 'create', - options: ['--template=app', '--org', 'io.flutter.devicelab']..addAll(options)..add('plugintest') + options: ['--template=app', '--org', 'io.flutter.devicelab']..addAll(options)..add('plugintest'), ); }); return FlutterProject(directory, 'plugintest'); diff --git a/dev/devicelab/lib/tasks/run_without_leak.dart b/dev/devicelab/lib/tasks/run_without_leak.dart new file mode 100644 index 0000000000..eb9ff50115 --- /dev/null +++ b/dev/devicelab/lib/tasks/run_without_leak.dart @@ -0,0 +1,61 @@ +// Copyright 2019 The Flutter 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 'dart:async'; +import 'dart:convert'; +import 'dart:io'; + +import 'package:path/path.dart' as path; + +import '../framework/adb.dart'; +import '../framework/framework.dart'; +import '../framework/utils.dart'; + +TaskFunction createRunWithoutLeakTest(dynamic dir) { + return () async { + final Device device = await devices.workingDevice; + await device.unlock(); + final List options = [ + '-d', device.deviceId, '--verbose', + ]; + setLocalEngineOptionIfNecessary(options); + int exitCode; + await inDirectory(dir, () async { + final Process process = await startProcess( + path.join(flutterDirectory.path, 'bin', 'flutter'), + ['run']..addAll(options), + environment: null, + ); + final Completer stdoutDone = Completer(); + final Completer stderrDone = Completer(); + process.stdout + .transform(utf8.decoder) + .transform(const LineSplitter()) + .listen((String line) { + if (line.contains('\] For a more detailed help message, press "h". To detach, press "d"; to quit, press "q"')) { + process.stdin.writeln('q'); + } + print('stdout: $line'); + }, onDone: () { + stdoutDone.complete(); + }); + process.stderr + .transform(utf8.decoder) + .transform(const LineSplitter()) + .listen((String line) { + print('stderr: $line'); + }, onDone: () { + stderrDone.complete(); + }); + + await Future.wait( + >[stdoutDone.future, stderrDone.future]); + exitCode = await process.exitCode; + }); + + return exitCode == 0 + ? TaskResultCheckProcesses() + : TaskResult.failure('Failed to run $dir'); + }; +} diff --git a/dev/devicelab/manifest.yaml b/dev/devicelab/manifest.yaml index 861d0637a9..a5db41a1a1 100644 --- a/dev/devicelab/manifest.yaml +++ b/dev/devicelab/manifest.yaml @@ -76,6 +76,27 @@ tasks: stage: devicelab_win required_agent_capabilities: ["windows/android"] + codegen_integration_win: + description: > + Runs codegeneration and verifies that it can execute + correctly. + stage: devicelab_win + required_agent_capabilities: ["windows/android"] + + codegen_integration_mac: + description: > + Runs codegeneration and verifies that it can execute + correctly. + stage: devicelab_ios + required_agent_capabilities: ["mac/ios"] + + codegen_integration_linux: + description: > + Runs codegeneration and verifies that it can execute + correctly. + stage: devicelab + required_agent_capabilities: ["linux/android"] + flutter_gallery_android__compile: description: > Collects various performance metrics of compiling the Flutter @@ -118,7 +139,6 @@ tasks: flutter_gallery app on Android. stage: devicelab required_agent_capabilities: ["mac/android"] - flaky: true cull_opacity_perf__timeline_summary: description: > @@ -126,6 +146,13 @@ tasks: stage: devicelab required_agent_capabilities: ["mac/android"] + cubic_bezier_perf__timeline_summary: + description: > + Measures the runtime performance of cubic bezier animations on Android. + stage: devicelab + required_agent_capabilities: ["mac/android"] + flaky: true + flavors_test: description: > Checks that flavored builds work on Android. @@ -265,23 +292,24 @@ tasks: stage: devicelab required_agent_capabilities: ["linux/android"] - gradle_plugin_test: - description: > - Verifies that the Flutter Gradle plugin supports standard and custom Android build types. - stage: devicelab - required_agent_capabilities: ["linux/android"] + # TODO(dnfield): Remove these once we're confident it's all working on cirrus + # gradle_plugin_test: + # description: > + # Verifies that the Flutter Gradle plugin supports standard and custom Android build types. + # stage: devicelab + # required_agent_capabilities: ["linux/android"] - plugin_test: - description: > - Checks that the project template works and supports plugins. - stage: devicelab - required_agent_capabilities: ["linux/android"] + # plugin_test: + # description: > + # Checks that the project template works and supports plugins. + # stage: devicelab + # required_agent_capabilities: ["linux/android"] - module_test: - description: > - Checks that the module project template works and supports add2app on Android. - stage: devicelab - required_agent_capabilities: ["linux/android"] + # module_test: + # description: > + # Checks that the module project template works and supports add2app on Android. + # stage: devicelab + # required_agent_capabilities: ["linux/android"] flutter_gallery_instrumentation_test: description: > @@ -303,23 +331,24 @@ tasks: stage: devicelab required_agent_capabilities: ["linux/android"] - flutter_create_offline_test_linux: - description: > - Tests the `flutter create --offline` command. - stage: devicelab - required_agent_capabilities: ["linux/android"] + # TODO(dnfield): Remove these once we're confident it's all working on cirrus + # flutter_create_offline_test_linux: + # description: > + # Tests the `flutter create --offline` command. + # stage: devicelab + # required_agent_capabilities: ["linux/android"] - flutter_create_offline_test_windows: - description: > - Tests the `flutter create --offline` command. - stage: devicelab - required_agent_capabilities: ["windows/android"] + # flutter_create_offline_test_windows: + # description: > + # Tests the `flutter create --offline` command. + # stage: devicelab + # required_agent_capabilities: ["windows/android"] - flutter_create_offline_test_mac: - description: > - Tests the `flutter create --offline` command. - stage: devicelab - required_agent_capabilities: ["mac/android"] + # flutter_create_offline_test_mac: + # description: > + # Tests the `flutter create --offline` command. + # stage: devicelab + # required_agent_capabilities: ["mac/android"] # iOS on-device tests @@ -329,17 +358,18 @@ tasks: stage: devicelab_ios required_agent_capabilities: ["mac/ios"] - plugin_test_ios: - description: > - Checks that the project template works and supports plugins on iOS. - stage: devicelab_ios - required_agent_capabilities: ["mac/ios"] + # TODO(dnfield): Remove these once we're confident it's all working on cirrus + # plugin_test_ios: + # description: > + # Checks that the project template works and supports plugins on iOS. + # stage: devicelab_ios + # required_agent_capabilities: ["mac/ios"] - module_test_ios: - description: > - Checks that the module project template works and supports add2app on iOS. - stage: devicelab - required_agent_capabilities: ["mac/ios"] + # module_test_ios: + # description: > + # Checks that the module project template works and supports add2app on iOS. + # stage: devicelab + # required_agent_capabilities: ["mac/ios"] external_ui_integration_test_ios: description: > @@ -456,6 +486,13 @@ tasks: stage: devicelab_win required_agent_capabilities: ["windows/android"] + run_without_leak_win: + description: > + Checks that `flutter run` does not leak dart.exe on Windows. + stage: devicelab_win + required_agent_capabilities: ["windows/android"] + flaky: true + # Tests running on Linux hosts hot_mode_dev_cycle_linux__benchmark: @@ -464,11 +501,12 @@ tasks: stage: devicelab required_agent_capabilities: ["linux/android"] - dartdocs: - description: > - Tracks how many members are still lacking documentation. - stage: devicelab - required_agent_capabilities: ["linux/android"] + # TODO(dnfield): Remove these once we're confident it's all working on cirrus + # dartdocs: + # description: > + # Tracks how many members are still lacking documentation. + # stage: devicelab + # required_agent_capabilities: ["linux/android"] flutter_test_performance: description: > @@ -520,6 +558,13 @@ tasks: stage: devicelab required_agent_capabilities: ["linux/android"] + run_without_leak_linux: + description: > + Checks that `flutter run` does not leak dart on Linux. + stage: devicelab + required_agent_capabilities: ["linux/android"] + flaky: true + flutter_gallery_ios32__start_up: description: > Measures the startup time of the Flutter Gallery app on 32-bit iOS. @@ -532,3 +577,10 @@ tasks: 32-bit iOS. stage: devicelab_ios required_agent_capabilities: ["mac/ios32"] + + run_without_leak_mac: + description: > + Checks that `flutter run` does not leak dart on macOS. + stage: devicelab + required_agent_capabilities: ["mac/android"] + flaky: true diff --git a/dev/devicelab/pubspec.yaml b/dev/devicelab/pubspec.yaml index 994fa85f99..bc79d221b5 100644 --- a/dev/devicelab/pubspec.yaml +++ b/dev/devicelab/pubspec.yaml @@ -26,39 +26,39 @@ dependencies: crypto: 2.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" intl: 0.15.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" json_rpc_2: 2.0.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - petitparser: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + petitparser: 2.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pub_semver: 1.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - source_span: 1.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + source_span: 1.5.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 1.6.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" term_glyph: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 1.0.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - xml: 3.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + xml: 3.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: # See packages/flutter_test/pubspec.yaml for why we're pinning this version. test: 1.5.3 - analyzer: 0.35.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + analyzer: 0.35.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.14.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - front_end: 0.1.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + front_end: 0.1.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" glob: 1.1.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - html: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + html: 0.13.4+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http: 0.12.0+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_multi_server: 2.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_parser: 3.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" io: 0.3.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" js: 0.6.1+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - kernel: 0.3.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + kernel: 0.3.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" logging: 0.11.3+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" matcher: 0.12.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" mime: 0.9.6+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" multi_server_socket: 1.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" node_preamble: 1.4.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" package_config: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - package_resolver: 1.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - pedantic: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + package_resolver: 1.0.10 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + pedantic: 1.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" plugin: 0.2.0+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pool: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" shelf: 0.7.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -74,4 +74,4 @@ dev_dependencies: watcher: 0.9.7+10 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 2.1.15 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" -# PUBSPEC CHECKSUM: 2bb2 +# PUBSPEC CHECKSUM: d7e6 diff --git a/dev/devicelab/test/manifest_test.dart b/dev/devicelab/test/manifest_test.dart index 4fad8a7fe1..c26a9a6927 100644 --- a/dev/devicelab/test/manifest_test.dart +++ b/dev/devicelab/test/manifest_test.dart @@ -80,7 +80,7 @@ tasks: tasks: - a - b - ''' + ''', ); testManifestError( @@ -89,7 +89,7 @@ tasks: ''' tasks: 1: 2 - ''' + ''', ); testManifestError( @@ -98,7 +98,7 @@ tasks: ''' tasks: foo: 2 - ''' + ''', ); testManifestError( @@ -108,7 +108,7 @@ tasks: tasks: foo: bar: 2 - ''' + ''', ); testManifestError( @@ -118,7 +118,7 @@ tasks: tasks: foo: required_agent_capabilities: 1 - ''' + ''', ); testManifestError( @@ -128,7 +128,7 @@ tasks: tasks: foo: required_agent_capabilities: [1] - ''' + ''', ); testManifestError( @@ -138,7 +138,7 @@ tasks: tasks: foo: required_agent_capabilities: ["a"] - ''' + ''', ); testManifestError( @@ -149,7 +149,7 @@ tasks: foo: description: b required_agent_capabilities: ["a"] - ''' + ''', ); testManifestError( @@ -161,7 +161,7 @@ tasks: description: b stage: c required_agent_capabilities: [] - ''' + ''', ); testManifestError( @@ -174,7 +174,7 @@ tasks: stage: c required_agent_capabilities: ["a"] flaky: not-a-boolean - ''' + ''', ); test('accepts boolean flaky option', () { diff --git a/dev/devicelab/test/running_processes_test.dart b/dev/devicelab/test/running_processes_test.dart new file mode 100644 index 0000000000..395ada4673 --- /dev/null +++ b/dev/devicelab/test/running_processes_test.dart @@ -0,0 +1,68 @@ +// Copyright 2018 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 'package:flutter_devicelab/framework/running_processes.dart'; +import 'common.dart'; + +void main() { + test('Parse PowerShell result', () { + const String powershellOutput = r''' + +ProcessId CreationDate CommandLine +--------- ------------ ----------- + 6552 3/7/2019 5:00:27 PM "C:\tools\dart-sdk\bin\dart.exe" .\bin\agent.dart ci + 6553 3/7/2019 10:00:27 PM "C:\tools\dart-sdk1\bin\dart.exe" .\bin\agent.dart ci + 6554 3/7/2019 11:00:27 AM "C:\tools\dart-sdk2\bin\dart.exe" .\bin\agent.dart ci + + +'''; + final List results = + processPowershellOutput(powershellOutput).toList(); + expect(results.length, 3); + expect( + results, + equals([ + RunningProcessInfo( + 6552, + DateTime(2019, 7, 3, 17, 0, 27), + r'"C:\tools\dart-sdk\bin\dart.exe" .\bin\agent.dart ci', + ), + RunningProcessInfo( + 6553, + DateTime(2019, 7, 3, 22, 0, 27), + r'"C:\tools\dart-sdk1\bin\dart.exe" .\bin\agent.dart ci', + ), + RunningProcessInfo( + 6554, + DateTime(2019, 7, 3, 11, 0, 27), + r'"C:\tools\dart-sdk2\bin\dart.exe" .\bin\agent.dart ci', + ), + ])); + }); + + test('Parse Posix output', () { + const String psOutput = r'''STARTED PID COMMAND +Sat Mar 9 20:12:47 2019 1 /sbin/launchd +Sat Mar 9 20:13:00 2019 49 /usr/sbin/syslogd +'''; + + final List results = + processPsOutput(psOutput, null).toList(); + expect(results.length, 2); + expect( + results, + equals([ + RunningProcessInfo( + 1, + DateTime(2019, 3, 9, 20, 12, 47), + '/sbin/launchd', + ), + RunningProcessInfo( + 49, + DateTime(2019, 3, 9, 20, 13, 00), + '/usr/sbin/syslogd', + ), + ])); + }); +} diff --git a/dev/docs/README.md b/dev/docs/README.md index 1e8eac97c7..70d36a05ba 100644 --- a/dev/docs/README.md +++ b/dev/docs/README.md @@ -13,9 +13,9 @@ SDK. This site hosts Flutter's API documentation. Other documentation can be found at the following locations: -* [flutter.io](https://flutter.io/) (main site) -* [Installation](https://flutter.io/docs/get-started/install) -* [Codelabs](https://flutter.io/docs/codelabs) +* [flutter.dev](https://flutter.dev) (main site) +* [Installation](https://flutter.dev/docs/get-started/install) +* [Codelabs](https://flutter.dev/docs/codelabs) * [Contributing to Flutter](https://github.com/flutter/flutter/blob/master/CONTRIBUTING.md) ### Importing a Library diff --git a/dev/docs/assets/api_survey.js b/dev/docs/assets/api_survey.js new file mode 100644 index 0000000000..98e094e90b --- /dev/null +++ b/dev/docs/assets/api_survey.js @@ -0,0 +1,25 @@ +window.ApiSurveyDocs = function(apiPages) { + var url = window.location.href; + var fragments = url.split('/'); + if (fragments == null || fragments.length == 0) { + return; + } + var classFragment = fragments[fragments.length -1]; + if (classFragment == null) { + return; + } + var apiDocClassFragments = classFragment.split('-'); + if (apiDocClassFragments.length != 2) { + return; + } + var apiDocClass = apiDocClassFragments[0]; + if (url == null || apiPages.indexOf(apiDocClass) == -1) { + return; + } + scriptElement = document.createElement('script'); + scriptElement.setAttribute('src', 'https://www.google.com/insights/consumersurveys/async_survey?site=sygvgfetfwmwm7isniaym3m6f4'); + document.head.appendChild(scriptElement); +} +scriptElement = document.createElement('script'); +scriptElement.setAttribute('src', 'https://storage.googleapis.com/flutter-dashboard.appspot.com/api_survey/api_survey_docs.html'); +document.head.appendChild(scriptElement); diff --git a/dev/docs/assets/snippets.css b/dev/docs/assets/snippets.css index 65a7d338cb..4fb200addb 100644 --- a/dev/docs/assets/snippets.css +++ b/dev/docs/assets/snippets.css @@ -1,6 +1,6 @@ /* Styles for handling custom code snippets */ .snippet-container { - background-color: #45aae8; + background-color: #2372a3; padding: 10px; overflow: auto; } @@ -30,8 +30,21 @@ color: white; } +.snippet-description a:link { + color: #c7fcf4; +} +.snippet-description a:visited { + color: #c7dbfc; +} +.snippet-description a:hover { + color: white; +} +.snippet-description a:active { + color: #80b0fc; +} + .snippet-buttons button { - background-color: #45aae8; + background-color: #2372a3; border-style: none; color: white; padding: 10px 24px; @@ -82,7 +95,7 @@ height: 28px; width: 28px; transition: .3s ease; - background-color: #45aae8; + background-color: #2372a3; } .copy-button { @@ -102,7 +115,7 @@ .copy-image { opacity: 0.65; - color: #45aae8; + color: #2372a3; font-size: 28px; padding-top: 4px; } diff --git a/dev/docs/assets/snippets.js b/dev/docs/assets/snippets.js index b51c96e91c..9d4da921da 100644 --- a/dev/docs/assets/snippets.js +++ b/dev/docs/assets/snippets.js @@ -2,15 +2,10 @@ * Scripting for handling custom code snippets */ -const shortSnippet = 'shortSnippet'; -const longSnippet = 'longSnippet'; -var visibleSnippet = shortSnippet; - /** - * Shows the requested snippet. Values for "name" can be "shortSnippet" or - * "longSnippet". + * Shows the requested snippet, and stores the current state in visibleSnippet. */ -function showSnippet(name) { +function showSnippet(name, visibleSnippet) { if (visibleSnippet == name) return; if (visibleSnippet != null) { var shown = document.getElementById(visibleSnippet); @@ -39,6 +34,7 @@ function showSnippet(name) { if (button != null) { button.setAttributeNode(selectedAttribute); } + return visibleSnippet; } // Finds a sibling to given element with the given id. @@ -64,8 +60,8 @@ function supportsCopying() { // Copies the text inside the currently visible snippet to the clipboard, or the // given element, if any. function copyTextToClipboard(element) { - if (element == null) { - var elementSelector = '#' + visibleSnippet + ' .language-dart'; + if (typeof element === 'string') { + var elementSelector = '#' + element + ' .language-dart'; element = document.querySelector(elementSelector); if (element == null) { console.log( diff --git a/dev/docs/dashing.json b/dev/docs/dashing.json index 87bda93e16..4076446758 100644 --- a/dev/docs/dashing.json +++ b/dev/docs/dashing.json @@ -10,83 +10,52 @@ "allowJS": true, "ExternalURL": "https://docs.flutter.io", "selectors": { - "#exceptions span.name a": { "type": "Exception" }, - "body > main > div.col-xs-12.col-sm-9.col-md-8.main-content > h1": { - "requiretext": " library", - "type": "Library", - "regexp": " library", - "replacement": "" + "h1 > span.kind-library": { + "type": "Library" }, - "body > main > div.col-xs-12.col-sm-9.main-content > h1": { - "requiretext": " class", - "type": "Class", - "regexp": " class", - "replacement": "" + "h1 > span.kind-class": { + "type": "Class" }, - "body > main > div.col-xs-12.col-md-8.main-content > h1": { - "requiretext": " function", - "type": "Function", - "regexp": " function", - "replacement": "" + "h1 > span.kind-function": { + "type": "Function" }, - "body > main > div.col-sm-9.col-md-8.main-content > h1": { - "requiretext": " typedef", - "type": "Type", - "regexp": " typedef", - "replacement": "" + "h1 > span.kind-typedef": { + "type": "Type" }, - "body > main > .col-xs-12.col-sm-9.col-md-8.main-content > h1": { - "requiretext": " enum", - "type": "Enum", - "regexp": " enum", - "replacement": "" + "h1 > span.kind-enum": { + "type": "Enum" }, - "body > main > .col-md-8.main-content > h1": { - "requiretext": " constant", - "type": "Constant", - "regexp": " constant", - "replacement": "" + "h1 > span.kind-top-level-constant": { + "type": "Constant" }, - "body > main > div.col-xs-12.col-sm-9 > h1": { - "requiretext": " method", - "type": "Method", - "regexp": " method", - "replacement": "" + "h1 > span.kind-constant": { + "type": "Constant" }, - ".callables .callable .name a": { + "h1 > span.kind-method": { "type": "Method" }, - "body > main > .col-xs-12.col-sm-9.col-md-8 > h1": { - "requiretext": " property", - "type": "Property", - "regexp": " property", - "replacement": "" + "h1 > span.kind-property": { + "type": "Property" }, - "body > main > .col-xs-12.col-md-8 > h1": { - "requiretext": " constructor", - "type": "Constructor", - "regexp": " constructor", - "replacement": "" + "h1 > span.kind-top-level-property": { + "type": "Property" }, - "body > main > .col-xs-12.col-sm-9.main-content > h1": { - "requiretext": "operator ", - "type": "Operator", - "regexp": "operator ", - "replacement": "" + "h1 > span.kind-constructor": { + "type": "Constructor" }, ".callables .callable": { @@ -95,8 +64,6 @@ "regexp": "operator ", "replacement": "" } - - }, "ignore": [ "ABOUT" diff --git a/dev/docs/survey.html b/dev/docs/survey.html index 096e19b046..6684c7eaa1 100644 --- a/dev/docs/survey.html +++ b/dev/docs/survey.html @@ -1,3 +1 @@ - + diff --git a/dev/integration_tests/android_semantics_testing/pubspec.yaml b/dev/integration_tests/android_semantics_testing/pubspec.yaml index a8d66f77da..fc34fbbfa4 100644 --- a/dev/integration_tests/android_semantics_testing/pubspec.yaml +++ b/dev/integration_tests/android_semantics_testing/pubspec.yaml @@ -8,7 +8,7 @@ dependencies: sdk: flutter test: 1.5.3 - analyzer: 0.35.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + analyzer: 0.35.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" args: 1.5.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" async: 2.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -18,9 +18,9 @@ dependencies: crypto: 2.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.14.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" file: 5.0.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - front_end: 0.1.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + front_end: 0.1.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" glob: 1.1.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - html: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + html: 0.13.4+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http: 0.12.0+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_multi_server: 2.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_parser: 3.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -28,7 +28,7 @@ dependencies: io: 0.3.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" js: 0.6.1+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" json_rpc_2: 2.0.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - kernel: 0.3.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + kernel: 0.3.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" logging: 0.11.3+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" matcher: 0.12.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -36,9 +36,9 @@ dependencies: multi_server_socket: 1.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" node_preamble: 1.4.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" package_config: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - package_resolver: 1.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + package_resolver: 1.0.10 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path: 1.6.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - pedantic: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + pedantic: 1.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" plugin: 0.2.0+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pool: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pub_semver: 1.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -48,7 +48,7 @@ dependencies: shelf_web_socket: 0.2.2+4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" source_map_stack_trace: 1.1.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" source_maps: 0.10.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - source_span: 1.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + source_span: 1.5.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 1.6.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" string_scanner: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -66,4 +66,4 @@ dependencies: flutter: uses-material-design: true -# PUBSPEC CHECKSUM: c26c +# PUBSPEC CHECKSUM: 2b9e diff --git a/dev/integration_tests/android_views/ios/Podfile b/dev/integration_tests/android_views/ios/Podfile new file mode 100644 index 0000000000..d077b08bd5 --- /dev/null +++ b/dev/integration_tests/android_views/ios/Podfile @@ -0,0 +1,69 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def parse_KV_file(file, separator='=') + file_abs_path = File.expand_path(file) + if !File.exists? file_abs_path + return []; + end + pods_ary = [] + skip_line_start_symbols = ["#", "/"] + File.foreach(file_abs_path) { |line| + next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } + plugin = line.split(pattern=separator) + if plugin.length == 2 + podname = plugin[0].strip() + path = plugin[1].strip() + podpath = File.expand_path("#{path}", file_abs_path) + pods_ary.push({:name => podname, :path => podpath}); + else + puts "Invalid plugin specification: #{line}" + end + } + return pods_ary +end + +target 'Runner' do + # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock + # referring to absolute paths on developers' machines. + system('rm -rf .symlinks') + system('mkdir -p .symlinks/plugins') + + # Flutter Pods + generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig') + if generated_xcode_build_settings.empty? + puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first." + end + generated_xcode_build_settings.map { |p| + if p[:name] == 'FLUTTER_FRAMEWORK_DIR' + symlink = File.join('.symlinks', 'flutter') + File.symlink(File.dirname(p[:path]), symlink) + pod 'Flutter', :path => File.join(symlink, File.basename(p[:path])) + end + } + + # Plugin Pods + plugin_pods = parse_KV_file('../.flutter-plugins') + plugin_pods.map { |p| + symlink = File.join('.symlinks', 'plugins', p[:name]) + File.symlink(p[:path], symlink) + pod p[:name], :path => File.join(symlink, 'ios') + } +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['ENABLE_BITCODE'] = 'NO' + end + end +end diff --git a/dev/integration_tests/android_views/lib/main.dart b/dev/integration_tests/android_views/lib/main.dart index 64250171f0..74b1ea592d 100644 --- a/dev/integration_tests/android_views/lib/main.dart +++ b/dev/integration_tests/android_views/lib/main.dart @@ -109,9 +109,9 @@ class PlatformViewState extends State { key: const ValueKey('play'), child: const Text('PLAY FILE'), onPressed: () { playEventsFile(); }, - ) + ), ], - ) + ), ], ); } diff --git a/dev/integration_tests/android_views/lib/motion_event_diff.dart b/dev/integration_tests/android_views/lib/motion_event_diff.dart index 2c31f859ed..21f2bb54a1 100644 --- a/dev/integration_tests/android_views/lib/motion_event_diff.dart +++ b/dev/integration_tests/android_views/lib/motion_event_diff.dart @@ -10,7 +10,7 @@ const List kPointerActions = [ 0, // DOWN 1, // UP 5, // POINTER_DOWN - 6 // POINTER_UP + 6, // POINTER_UP ]; const double kDoubleErrorMargin = 0.0001; @@ -152,7 +152,7 @@ String getActionName(int actionMasked, int action) { 'HOVER_ENTER', 'HOVER_EXIT', 'BUTTON_PRESS', - 'BUTTON_RELEASE' + 'BUTTON_RELEASE', ]; if (actionMasked < actionNames.length) return '${actionNames[actionMasked]}($action)'; diff --git a/dev/integration_tests/android_views/pubspec.yaml b/dev/integration_tests/android_views/pubspec.yaml index 9b0990fcc7..9325cf43aa 100644 --- a/dev/integration_tests/android_views/pubspec.yaml +++ b/dev/integration_tests/android_views/pubspec.yaml @@ -25,7 +25,7 @@ dependencies: meta: 1.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path: 1.6.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pub_semver: 1.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - source_span: 1.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + source_span: 1.5.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 1.6.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" term_glyph: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -39,27 +39,27 @@ dev_dependencies: sdk: flutter test: 1.5.3 - analyzer: 0.35.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + analyzer: 0.35.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" args: 1.5.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.14.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - front_end: 0.1.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + front_end: 0.1.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" glob: 1.1.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - html: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + html: 0.13.4+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http: 0.12.0+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_multi_server: 2.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_parser: 3.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" io: 0.3.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" js: 0.6.1+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - kernel: 0.3.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + kernel: 0.3.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" logging: 0.11.3+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" matcher: 0.12.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" mime: 0.9.6+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" multi_server_socket: 1.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" node_preamble: 1.4.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" package_config: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - package_resolver: 1.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - pedantic: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + package_resolver: 1.0.10 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + pedantic: 1.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" plugin: 0.2.0+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pool: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" quiver: 2.0.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -79,4 +79,4 @@ dev_dependencies: flutter: uses-material-design: true -# PUBSPEC CHECKSUM: 997a +# PUBSPEC CHECKSUM: 49ac diff --git a/dev/integration_tests/channels/lib/main.dart b/dev/integration_tests/channels/lib/main.dart index 8dd4896e31..c7d0b3e518 100644 --- a/dev/integration_tests/channels/lib/main.dart +++ b/dev/integration_tests/channels/lib/main.dart @@ -31,7 +31,7 @@ class _TestAppState extends State { 0.0, 'hello', [ - {'key': 42} + {'key': 42}, ], ]; static final Map aMap = { @@ -40,7 +40,7 @@ class _TestAppState extends State { 'c': 0.0, 'd': 'hello', 'e': [ - {'key': 42} + {'key': 42}, ], }; static final Uint8List someUint8s = Uint8List.fromList([ diff --git a/dev/integration_tests/channels/pubspec.yaml b/dev/integration_tests/channels/pubspec.yaml index 45c461ae41..39872ef4f6 100644 --- a/dev/integration_tests/channels/pubspec.yaml +++ b/dev/integration_tests/channels/pubspec.yaml @@ -12,7 +12,7 @@ dependencies: sdk: flutter test: 1.5.3 - analyzer: 0.35.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + analyzer: 0.35.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" args: 1.5.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" async: 2.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -22,9 +22,9 @@ dependencies: crypto: 2.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.14.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" file: 5.0.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - front_end: 0.1.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + front_end: 0.1.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" glob: 1.1.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - html: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + html: 0.13.4+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http: 0.12.0+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_multi_server: 2.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_parser: 3.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -32,7 +32,7 @@ dependencies: io: 0.3.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" js: 0.6.1+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" json_rpc_2: 2.0.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - kernel: 0.3.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + kernel: 0.3.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" logging: 0.11.3+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" matcher: 0.12.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -40,9 +40,9 @@ dependencies: multi_server_socket: 1.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" node_preamble: 1.4.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" package_config: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - package_resolver: 1.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + package_resolver: 1.0.10 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path: 1.6.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - pedantic: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + pedantic: 1.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" plugin: 0.2.0+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pool: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pub_semver: 1.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -52,7 +52,7 @@ dependencies: shelf_web_socket: 0.2.2+4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" source_map_stack_trace: 1.1.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" source_maps: 0.10.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - source_span: 1.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + source_span: 1.5.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 1.6.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" string_scanner: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -70,4 +70,4 @@ dependencies: flutter: uses-material-design: true -# PUBSPEC CHECKSUM: c26c +# PUBSPEC CHECKSUM: 2b9e diff --git a/dev/integration_tests/codegen/README.md b/dev/integration_tests/codegen/README.md new file mode 100644 index 0000000000..494dc2bbcc --- /dev/null +++ b/dev/integration_tests/codegen/README.md @@ -0,0 +1,3 @@ +# codegen + +A Flutter project for testing code generation. diff --git a/dev/integration_tests/codegen/android/.project b/dev/integration_tests/codegen/android/.project new file mode 100644 index 0000000000..8b6e7b429f --- /dev/null +++ b/dev/integration_tests/codegen/android/.project @@ -0,0 +1,17 @@ + + + android_____ + Project android_____ created by Buildship. + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/dev/integration_tests/codegen/android/.settings/org.eclipse.buildship.core.prefs b/dev/integration_tests/codegen/android/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 0000000000..e8895216fd --- /dev/null +++ b/dev/integration_tests/codegen/android/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,2 @@ +connection.project.dir= +eclipse.preferences.version=1 diff --git a/dev/integration_tests/codegen/android/app/build.gradle b/dev/integration_tests/codegen/android/app/build.gradle new file mode 100644 index 0000000000..9ebebef363 --- /dev/null +++ b/dev/integration_tests/codegen/android/app/build.gradle @@ -0,0 +1,57 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withInputStream { stream -> + localProperties.load(stream) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + minSdkVersion 16 + targetSdkVersion 28 + versionCode 1 + versionName "0.0.1" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } + + aaptOptions { + // TODO(goderbauer): remove when https://github.com/flutter/flutter/issues/8986 is resolved. + if(System.getenv("FLUTTER_CI_WIN")) { + println "AAPT cruncher disabled when running on Win CI." + cruncherEnabled false + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/dev/integration_tests/codegen/android/app/src/main/AndroidManifest.xml b/dev/integration_tests/codegen/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..6703641433 --- /dev/null +++ b/dev/integration_tests/codegen/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + diff --git a/dev/integration_tests/codegen/android/app/src/main/java/com/yourcompany/platforminteraction/MainActivity.java b/dev/integration_tests/codegen/android/app/src/main/java/com/yourcompany/platforminteraction/MainActivity.java new file mode 100644 index 0000000000..73b7e51bb9 --- /dev/null +++ b/dev/integration_tests/codegen/android/app/src/main/java/com/yourcompany/platforminteraction/MainActivity.java @@ -0,0 +1,17 @@ +// 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. + +package com.yourcompany.platforminteraction; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/dev/integration_tests/codegen/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/dev/integration_tests/codegen/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000..db77bb4b7b Binary files /dev/null and b/dev/integration_tests/codegen/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/dev/integration_tests/codegen/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/dev/integration_tests/codegen/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000000..17987b79bb Binary files /dev/null and b/dev/integration_tests/codegen/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/dev/integration_tests/codegen/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/dev/integration_tests/codegen/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000000..09d4391482 Binary files /dev/null and b/dev/integration_tests/codegen/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/dev/integration_tests/codegen/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/dev/integration_tests/codegen/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000..d5f1c8d34e Binary files /dev/null and b/dev/integration_tests/codegen/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/dev/integration_tests/codegen/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/dev/integration_tests/codegen/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000..4d6372eebd Binary files /dev/null and b/dev/integration_tests/codegen/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/dev/integration_tests/codegen/android/build.gradle b/dev/integration_tests/codegen/android/build.gradle new file mode 100644 index 0000000000..bb8a303898 --- /dev/null +++ b/dev/integration_tests/codegen/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/dev/integration_tests/codegen/android/gradle.properties b/dev/integration_tests/codegen/android/gradle.properties new file mode 100644 index 0000000000..8bd86f6805 --- /dev/null +++ b/dev/integration_tests/codegen/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/dev/integration_tests/codegen/android/gradle/wrapper/gradle-wrapper.properties b/dev/integration_tests/codegen/android/gradle/wrapper/gradle-wrapper.properties new file mode 100755 index 0000000000..2819f022f1 --- /dev/null +++ b/dev/integration_tests/codegen/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/dev/integration_tests/codegen/android/settings.gradle b/dev/integration_tests/codegen/android/settings.gradle new file mode 100644 index 0000000000..115da6cb4f --- /dev/null +++ b/dev/integration_tests/codegen/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withInputStream { stream -> plugins.load(stream) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/dev/integration_tests/codegen/ios/Flutter/AppFrameworkInfo.plist b/dev/integration_tests/codegen/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000000..9367d483e4 --- /dev/null +++ b/dev/integration_tests/codegen/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/dev/integration_tests/codegen/ios/Flutter/Debug.xcconfig b/dev/integration_tests/codegen/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000000..592ceee85b --- /dev/null +++ b/dev/integration_tests/codegen/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/dev/integration_tests/codegen/ios/Flutter/Release.xcconfig b/dev/integration_tests/codegen/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000000..592ceee85b --- /dev/null +++ b/dev/integration_tests/codegen/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/dev/integration_tests/codegen/ios/Runner.xcodeproj/project.pbxproj b/dev/integration_tests/codegen/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..e85f6101b4 --- /dev/null +++ b/dev/integration_tests/codegen/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,506 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.iosExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.iosExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.iosExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/dev/integration_tests/codegen/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/dev/integration_tests/codegen/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000..1d526a16ed --- /dev/null +++ b/dev/integration_tests/codegen/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/dev/integration_tests/codegen/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/dev/integration_tests/codegen/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000000..786d6aad54 --- /dev/null +++ b/dev/integration_tests/codegen/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/integration_tests/codegen/ios/Runner.xcworkspace/contents.xcworkspacedata b/dev/integration_tests/codegen/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000..1d526a16ed --- /dev/null +++ b/dev/integration_tests/codegen/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/dev/integration_tests/codegen/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/dev/integration_tests/codegen/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000000..949b678982 --- /dev/null +++ b/dev/integration_tests/codegen/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + BuildSystemType + Original + + diff --git a/dev/integration_tests/codegen/ios/Runner/AppDelegate.h b/dev/integration_tests/codegen/ios/Runner/AppDelegate.h new file mode 100644 index 0000000000..36e21bbf9c --- /dev/null +++ b/dev/integration_tests/codegen/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/dev/integration_tests/codegen/ios/Runner/AppDelegate.m b/dev/integration_tests/codegen/ios/Runner/AppDelegate.m new file mode 100644 index 0000000000..59a72e90be --- /dev/null +++ b/dev/integration_tests/codegen/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000000..d36b1fab2d --- /dev/null +++ b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000000..3d43d11e66 Binary files /dev/null and b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000000..28c6bf0301 Binary files /dev/null and b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000000..2ccbfd967d Binary files /dev/null and b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000000..f091b6b0bc Binary files /dev/null and b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000000..4cde12118d Binary files /dev/null and b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000000..d0ef06e7ed Binary files /dev/null and b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000000..dcdc2306c2 Binary files /dev/null and b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000000..2ccbfd967d Binary files /dev/null and b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000000..c8f9ed8f5c Binary files /dev/null and b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000000..a6d6b8609d Binary files /dev/null and b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000000..a6d6b8609d Binary files /dev/null and b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000000..75b2d164a5 Binary files /dev/null and b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000000..c4df70d39d Binary files /dev/null and b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000000..6a84f41e14 Binary files /dev/null and b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000000..d0e1f58536 Binary files /dev/null and b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 0000000000..0bedcf2fd4 --- /dev/null +++ b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 0000000000..9da19eacad Binary files /dev/null and b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000000..9da19eacad Binary files /dev/null and b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000000..9da19eacad Binary files /dev/null and b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 0000000000..89c2725b70 --- /dev/null +++ b/dev/integration_tests/codegen/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/dev/integration_tests/codegen/ios/Runner/Base.lproj/LaunchScreen.storyboard b/dev/integration_tests/codegen/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000000..f2e259c7c9 --- /dev/null +++ b/dev/integration_tests/codegen/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/integration_tests/codegen/ios/Runner/Base.lproj/Main.storyboard b/dev/integration_tests/codegen/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000000..f3c28516fb --- /dev/null +++ b/dev/integration_tests/codegen/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/integration_tests/codegen/ios/Runner/Info.plist b/dev/integration_tests/codegen/ios/Runner/Info.plist new file mode 100644 index 0000000000..33d863b44d --- /dev/null +++ b/dev/integration_tests/codegen/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ios_example + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/dev/integration_tests/codegen/ios/Runner/main.m b/dev/integration_tests/codegen/ios/Runner/main.m new file mode 100644 index 0000000000..dff6597e45 --- /dev/null +++ b/dev/integration_tests/codegen/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/dev/integration_tests/codegen/lib/main.dart b/dev/integration_tests/codegen/lib/main.dart new file mode 100644 index 0000000000..556c37d36c --- /dev/null +++ b/dev/integration_tests/codegen/lib/main.dart @@ -0,0 +1,50 @@ +// 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 'package:flutter/material.dart'; +import 'package:flutter_driver/driver_extension.dart'; +import 'message.dart' as generated; // ignore: uri_does_not_exist + +Future main() async { + enableFlutterDriverExtension(); + runApp(ExampleWidget()); +} + +class ExampleWidget extends StatefulWidget { + @override + _ExampleWidgetState createState() => _ExampleWidgetState(); +} + +class _ExampleWidgetState extends State { + bool _pressed = false; + + @override + Widget build(BuildContext context) { + return MaterialApp( + home: Scaffold( + body: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + RaisedButton( + child: const Text('Press Button, Get Coffee'), + onPressed: () async { + setState(() { + _pressed = true; + }); + }, + ), + _pressed ? GeneratedWidget() : const SizedBox(), + ], + ), + ), + ); + } +} + +class GeneratedWidget extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Text(generated.message); + } +} diff --git a/dev/integration_tests/codegen/lib/message.spec b/dev/integration_tests/codegen/lib/message.spec new file mode 100644 index 0000000000..4ec81420e9 --- /dev/null +++ b/dev/integration_tests/codegen/lib/message.spec @@ -0,0 +1 @@ +String get message => 'Thanks for using PourOverSupremeFiesta by Coffee by Flutter Inc.'; diff --git a/dev/integration_tests/codegen/pubspec.yaml b/dev/integration_tests/codegen/pubspec.yaml new file mode 100644 index 0000000000..c3cbf60e54 --- /dev/null +++ b/dev/integration_tests/codegen/pubspec.yaml @@ -0,0 +1,81 @@ +name: codegen +description: A test of Flutter integrating code generation. + +environment: + # The pub client defaults to an <2.0.0 sdk constraint which we need to explicitly overwrite. + sdk: ">=2.0.0-dev.68.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + flutter_driver: + sdk: flutter + + async: 2.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + collection: 1.14.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + convert: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + crypto: 2.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + file: 5.0.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + intl: 0.15.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + json_rpc_2: 2.0.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + meta: 1.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + path: 1.6.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + pub_semver: 1.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + source_span: 1.5.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + stream_channel: 1.6.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + term_glyph: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + typed_data: 1.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + vector_math: 2.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + vm_service_client: 0.2.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web_socket_channel: 1.0.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + +dev_dependencies: + test: 1.5.3 + + analyzer: 0.35.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + args: 1.5.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + boolean_selector: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + csslib: 0.14.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + front_end: 0.1.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + glob: 1.1.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + html: 0.13.4+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + http: 0.12.0+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + http_multi_server: 2.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + http_parser: 3.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + io: 0.3.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + js: 0.6.1+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + kernel: 0.3.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + logging: 0.11.3+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + matcher: 0.12.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + mime: 0.9.6+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + multi_server_socket: 1.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + node_preamble: 1.4.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + package_config: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + package_resolver: 1.0.10 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + pedantic: 1.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + plugin: 0.2.0+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + pool: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + shelf: 0.7.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + shelf_packages_handler: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + shelf_static: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + shelf_web_socket: 0.2.2+4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + source_map_stack_trace: 1.1.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + source_maps: 0.10.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + string_scanner: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + test_api: 0.2.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + test_core: 0.2.1+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + utf: 0.9.0+5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + watcher: 0.9.7+10 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + yaml: 2.1.15 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + +builders: + # Note: path is relative from generated directory + simple_codegen: + path: ../../../simple_codegen + +flutter: + uses-material-design: true + +# PUBSPEC CHECKSUM: 2b9e diff --git a/dev/integration_tests/codegen/test/example_test.dart b/dev/integration_tests/codegen/test/example_test.dart new file mode 100644 index 0000000000..6d687eb92d --- /dev/null +++ b/dev/integration_tests/codegen/test/example_test.dart @@ -0,0 +1,11 @@ +import 'package:codegen/main.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + testWidgets('can reference generated code', (WidgetTester tester) async { + await tester.pumpWidget(MaterialApp(home: GeneratedWidget())); + + expect(find.text('Thanks for using PourOverSupremeFiesta by Coffee by Flutter Inc.'), findsOneWidget); + }); +} diff --git a/dev/integration_tests/codegen/test_driver/main_test.dart b/dev/integration_tests/codegen/test_driver/main_test.dart new file mode 100644 index 0000000000..1ae419a188 --- /dev/null +++ b/dev/integration_tests/codegen/test_driver/main_test.dart @@ -0,0 +1,27 @@ +// 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 'package:flutter_driver/flutter_driver.dart'; +import 'package:test/test.dart' hide TypeMatcher, isInstanceOf; + +void main() { + FlutterDriver driver; + + setUpAll(() async { + driver = await FlutterDriver.connect(); + }); + + tearDownAll(() async { + await driver.close(); + }); + + test('Can execute generated code', () async { + const String button = 'Press Button, Get Coffee'; + await driver.tap(find.text(button)); + + const String message = 'Thanks for using PourOverSupremeFiesta by Coffee by Flutter Inc.'; + final String fullMessage = await driver.getText(find.text(message)); + expect(fullMessage, message); + }); +} diff --git a/dev/integration_tests/external_ui/pubspec.yaml b/dev/integration_tests/external_ui/pubspec.yaml index 0a12a7ec72..6e580305ad 100644 --- a/dev/integration_tests/external_ui/pubspec.yaml +++ b/dev/integration_tests/external_ui/pubspec.yaml @@ -12,7 +12,7 @@ dependencies: sdk: flutter test: 1.5.3 - analyzer: 0.35.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + analyzer: 0.35.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" args: 1.5.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" async: 2.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -22,9 +22,9 @@ dependencies: crypto: 2.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.14.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" file: 5.0.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - front_end: 0.1.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + front_end: 0.1.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" glob: 1.1.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - html: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + html: 0.13.4+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http: 0.12.0+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_multi_server: 2.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_parser: 3.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -32,7 +32,7 @@ dependencies: io: 0.3.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" js: 0.6.1+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" json_rpc_2: 2.0.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - kernel: 0.3.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + kernel: 0.3.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" logging: 0.11.3+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" matcher: 0.12.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -40,9 +40,9 @@ dependencies: multi_server_socket: 1.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" node_preamble: 1.4.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" package_config: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - package_resolver: 1.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + package_resolver: 1.0.10 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path: 1.6.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - pedantic: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + pedantic: 1.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" plugin: 0.2.0+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pool: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pub_semver: 1.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -52,7 +52,7 @@ dependencies: shelf_web_socket: 0.2.2+4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" source_map_stack_trace: 1.1.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" source_maps: 0.10.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - source_span: 1.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + source_span: 1.5.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 1.6.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" string_scanner: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -70,4 +70,4 @@ dependencies: flutter: uses-material-design: true -# PUBSPEC CHECKSUM: c26c +# PUBSPEC CHECKSUM: 2b9e diff --git a/dev/integration_tests/flavors/pubspec.yaml b/dev/integration_tests/flavors/pubspec.yaml index 96208b4766..cade712a20 100644 --- a/dev/integration_tests/flavors/pubspec.yaml +++ b/dev/integration_tests/flavors/pubspec.yaml @@ -12,7 +12,7 @@ dependencies: sdk: flutter test: 1.5.3 - analyzer: 0.35.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + analyzer: 0.35.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" args: 1.5.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" async: 2.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -22,9 +22,9 @@ dependencies: crypto: 2.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.14.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" file: 5.0.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - front_end: 0.1.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + front_end: 0.1.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" glob: 1.1.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - html: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + html: 0.13.4+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http: 0.12.0+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_multi_server: 2.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_parser: 3.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -32,7 +32,7 @@ dependencies: io: 0.3.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" js: 0.6.1+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" json_rpc_2: 2.0.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - kernel: 0.3.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + kernel: 0.3.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" logging: 0.11.3+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" matcher: 0.12.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -40,9 +40,9 @@ dependencies: multi_server_socket: 1.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" node_preamble: 1.4.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" package_config: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - package_resolver: 1.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + package_resolver: 1.0.10 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path: 1.6.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - pedantic: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + pedantic: 1.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" plugin: 0.2.0+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pool: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pub_semver: 1.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -52,7 +52,7 @@ dependencies: shelf_web_socket: 0.2.2+4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" source_map_stack_trace: 1.1.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" source_maps: 0.10.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - source_span: 1.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + source_span: 1.5.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 1.6.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" string_scanner: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -70,4 +70,4 @@ dependencies: flutter: uses-material-design: true -# PUBSPEC CHECKSUM: c26c +# PUBSPEC CHECKSUM: 2b9e diff --git a/dev/integration_tests/ios_add2app/.gitignore b/dev/integration_tests/ios_add2app/.gitignore new file mode 100644 index 0000000000..caceafe4e0 --- /dev/null +++ b/dev/integration_tests/ios_add2app/.gitignore @@ -0,0 +1,68 @@ +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +.DS_Store + +## Build generated +build/ +DerivedData/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xccheckout +*.xcscmblueprint + +## Obj-C/Swift specific +*.hmap +*.ipa +*.dSYM.zip +*.dSYM + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +# Pods/ +# +# Add this line if you want to avoid checking in source code from the Xcode workspace +# *.xcworkspace + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://docs.fastlane.tools/best-practices/source-control/#source-control + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots/**/*.png +fastlane/test_output + +# Code Injection +# +# After new code Injection tools there's a generated folder /iOSInjectionProject +# https://github.com/johnno1962/injectionforxcode + +iOSInjectionProject/ \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/LICENSE b/dev/integration_tests/ios_add2app/LICENSE new file mode 100644 index 0000000000..8211a02c06 --- /dev/null +++ b/dev/integration_tests/ios_add2app/LICENSE @@ -0,0 +1,27 @@ +Copyright 2014 The Chromium Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/dev/integration_tests/ios_add2app/Podfile b/dev/integration_tests/ios_add2app/Podfile new file mode 100644 index 0000000000..3904962da2 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Podfile @@ -0,0 +1,23 @@ +platform :ios, '12.0' + +flutter_application_path = 'flutterapp/' +framework_dir = File.join(flutter_application_path, '.ios', 'Flutter') + +engine_dir = File.join(framework_dir, 'engine') +if !File.exist?(engine_dir) + # Copy the debug engine to have something to link against if the xcode backend script has not run yet. + debug_framework_dir = File.join(flutter_root(flutter_application_path), 'bin', 'cache', 'artifacts', 'engine', 'ios') + FileUtils.mkdir_p(engine_dir) + FileUtils.cp_r(File.join(debug_framework_dir, 'Flutter.framework'), engine_dir) + FileUtils.cp(File.join(debug_framework_dir, 'Flutter.podspec'), engine_dir) +end + +target 'ios_add2app' do + eval(File.read(File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')), binding) +end + +target 'ios_add2appTests' do + pod 'Flutter', :path => engine_dir + inherit! :search_paths + pod 'EarlGrey' +end diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/CHANGELOG.md b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/CHANGELOG.md new file mode 100644 index 0000000000..034f3889bf --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/CHANGELOG.md @@ -0,0 +1,673 @@ +# Change Log + +Details changes in each release of EarlGrey. EarlGrey follows [semantic versioning](http://semver.org/). + +## [1.15.0](https://github.com/google/EarlGrey/tree/1.15.0) (08/03/2018) +``` +Baseline: [59ce3b6c] ++ [59ce3b6c]: Fix default Swift version in EarlGreyExampleSwiftTests xcode project +``` + +### Enhancements +* Added support for accessibility in iOS 12. +* Updated the visibility checker to support keyboards in iOS 12. +* Updated Analytics Configurations. +* Fixed Formatting Issues. +* Updated invalid api and compatibility docs. + +### Compatibility +* EarlGrey has now been tested for working till Xcode version 10.0 beta 2. +* Some of the internal unit tests break on Xcode 9.3+ due to change in exception name thrown by XCTest. Those are still being investigated. + +## [1.14.0](https://github.com/google/EarlGrey/tree/1.14.0) (06/04/2018) +``` +Baseline: [c201f58] ++ [c201f58]: Fix default Swift version in EarlGreyExampleSwiftTests xcode project +``` + +### Enhancements +* Add Swift 4 support in the gem. +* Update block declarations to support strict prototypes. +* Add support for PDF display for `UIWebViewIdlingResource`. +* Remove Swift 2 in the gem since Xcode 7.x is not supported anymore. + +### Bug Fixes +* Fix `FTRLocalUIWebViewTest` by updating `testAJAXLoad` to detect proper web view elements. + +### Compatibility +* EarlGrey has now been tested for working till Xcode version 9.4. Any small test breakages with Xcode 9.4 are being tested. + +### Contributors +Thanks to [adam-b](https://github.com/adam-b) and [keefertaylor](https://github.com/keefertaylor)! + +## [1.13.0](https://github.com/google/EarlGrey/tree/1.13.0) (04/03/2018) +``` +Baseline: [2b3939a] ++ [2b3939a]: Fix Swift file issues with the updated EarlGrey code for release 1.13.0. +``` + +### Enhancements +* Add nullability to EarlGrey Headers. [Issue #449](https://github.com/google/EarlGrey/issues/449) +* Remove `notNil` method and add explicit check in the matcher itself. +* Update the Swift wrapper to use refined methods to prevent discardable result warnings. +* Update EarlGrey assert(with:) calls to assert(_:). +* Move the GREYRunLoopSpinner to spin on the thread passed to it instead of the main thread. +* Add tests for disabled buttons, fix visibility test and add iOS 11 support to tests. +* Move `EarlGreyImpl` interface out of EarlGrey.h. +* Add shake motion support to EarlGrey. + +### Bug Fixes +* Use `TIPreferencesController` to change the keyboard settings so it will not load `TIUserWordsManager`, which can cause occasional crashes on iOS 11.0+. +* Tell the preferences not to show keyboard tutorial as it interferes with typing. +* Close MVC unconditionally to prevent erroneous scenarios where it fails to execute the completion block, leaving it resident on the screen forever. + +### Compatibility +* EarlGrey has now been tested for working till Xcode version 9.3. Any small test breakages with Xcode 9.3 are being tested. + +## [1.12.1](https://github.com/google/EarlGrey/tree/1.12.1) (09/01/2017) +``` +Baseline: [405008e] ++ [405008e]: Release 1.12.1 to fix incorrect podspec release in 1.12.0. +``` + +### Bug Fixes +* Correct podspec to point to the version 1.12.1 + +## [1.12.0](https://github.com/google/EarlGrey/tree/1.12.0) (08/22/2017) +``` +Baseline: [ae61a45] ++ [ae61a45]: Fix Main thread violation: UIView setHidden called from non-main thread. +``` + +### Enhancements +* More robust synchronization with `NSURLSession`. This fixes many flakiness seen with EarlGrey not waiting for the completion of callback methods after network response has been received. +* Performance improvements in GREYAppStateTracker. It uses a deallocation tracker in place of NSString to free up memory sooner. +* Fallback to `EarlGrey.swift` v3 when gem cannot find the correct file for the current swift version. +* Added `-Wdocumentation` for all EarlGrey projects. +* Use static constructor in place of initialize method for one-time setup. +* Remove extra parentheses added around failed assertion expressions. +* Updated error messages on failure of layout contraints. +* Improved Visibility checker's shifted pixel image redraw logic. + +### Bug Fixes +* Fixed floating point issue in layout constraint matchers. [Issue #594](https://github.com/google/EarlGrey/issues/594) +* Fixed an issue where an exception is thrown when `-[UIWebDocumentView text]` is called in the middle of loading. +* Fixed a bug in `isKeyboardShown` with zero sized input accessory views. +* Fixed `CGAffineTransformInvert: singular matrix` message that appears during Pinch tests. + +### Compatibility +* EarlGrey now supports Xcode version 9.0 up to 9.0 beta 6. All EarlGrey project tests pass with these versions. + +## [1.11.0](https://github.com/google/EarlGrey/tree/1.11.0) (07/21/2017) + +``` +Baseline: [0d1086d] ++ [0d1086d]: Modify 1.10.2 -> 1.11.0 and update the CHANGELOG +``` + +### Enhancements +* Added support for iOS 11 & Xcode 9.0. +* Added the `grey_textFieldValue()` matcher for updates to UITextFields with iOS11. + +### Bug Fixes +* Fixed Minor issue that was causing infinitely long touch paths for zero sized areas. +* Grammatical and Language Fixes. +* Refactored FunctionalTests tests for adding iOS 11 support. + +## [1.10.1](https://github.com/google/EarlGrey/tree/1.10.1) (07/14/2017) + +``` +Baseline: [2abda72] ++ [2abda72]: Modified GREYElementInteraction.m to drain the thread for a timeout. +``` + +### Enhancements +* Improved `GREYAssert` macros to not wait until idle as it can cause it to never return. +* Improved Search action to not wait until idle as it can cause it to never return. + +## [1.10.0](https://github.com/google/EarlGrey/tree/1.10.0) (07/05/2017) + +``` +Baseline: [a386cb2] ++ [a386cb2]: Update Changelog for the 1.10.0 release for the Screenshot Docs change. +``` + +### Bug Fixes +* Resolved visibility checker overlapping view issue. [Issue #532](https://github.com/google/EarlGrey/issues/532) +* Use accessibility ID in place of accessibility label for keyboard modifier keys. [Issue #539](https://github.com/google/EarlGrey/issues/539) + +### Enhancements +* Removed `kGREYConfigKeyScreenshotDirLocation` in favor of `kGREYConfigKeyArtifactsDirLocation`. +* Fixed all issues reported by Xcode's static analysis. +* Fixed long press test failures on travis. +* Improved interaction error logging by adding more information about failure to the out error parameter. +* Added more error details to timeout failures. +* Add explicit 1st and 2nd param to grey_allOf and grey_anyOf to prevent redundant uses. +* Update jazzy copyright year. + +### Compatibility +* Adding xcode version to backwards compatibility doc. + +## [1.9.4](https://github.com/google/EarlGrey/tree/1.9.4) (06/09/2017) + +``` +Baseline: [76a6d65] ++ [76a6d65]: Updated Hierarchy traversal to use common traversal logic with DFS/BF. +``` + +### Bug Fixes +* Fixed a bug in scroll action that can sometimes cause a tap at the end of scroll. + +### New Features +* Added `kGREYConfigKeyArtifactsDirLocation` configuration key for setting a custom folder to store artifacts. + +### Enhancements +* Improved CI execution on travis. +* Updated test app with better AutoLayout support. +* Improved docs for earlgrey gem, contributors guide, etc. +* Fixed all asserts to use internal implementation instead of NSAssert which + can be disabled. +* Updated cheatsheet render script to use Chrome 59. +* Consolidated DFS and BFS hierarchy traversals. +* Renamed `GREYExposed.h` to `GREYAppleInternals.h` +* Removed redundant categories and moved methods to private headers. + +### Contributors +* [bootstraponline](https://github.com/bootstraponline) + +## [1.9.3](https://github.com/google/EarlGrey/tree/1.9.3) (05/26/2017) + +``` +Baseline: [a3ba675] ++ [a3ba675]: Fix breaking test with Long Press +``` + +### Improvements +* Revaming of Swipe Touch Path Gestures to make them more like a real-user. + +### Bug Fixes +* Fixed breaking tests for Long Press Gestures. +* Fix source_tree and relative path for the EarlGrey gem to prevent Carthage breakages. + +## [1.9.2](https://github.com/google/EarlGrey/tree/1.9.2) (04/21/2017) + +``` +Baseline: [b9d7a7c] + + [b9d7a7c]: Update OS=10.3 for travis CI +``` + +### Bug Fixes +* Fixed timeout related failures from being reported as assertion failures. +* Fixed to wait for rotation to complete before verifying that it changed. +* Fixed Swift breaks by correcting issue with Gem adding EarlGrey.swift for + Objective C targets. +* Fixed race condition with reading and writing to state tracker elementID. + +## [1.9.1](https://github.com/google/EarlGrey/tree/1.9.1) (04/14/2017) + +``` +Baseline: [932c3f6] + + [932c3f6]: Doc updates +``` + +### Bug Fixes +* Fixed a bug in interaction point calculation for cases where activation point +and the center of visible area is hidden. + +### Enhancements +* Updated documentation for GREYCondition and ruby setup. +* Minor improvements to formatting of failure messages. +* Updated travis to run tests on iOS 10.3 and Xcode 8.3. +* Deleted .arcconfig file. + +### Contributors +* [bootstraponline](https://github.com/bootstraponline) + +## [1.9.0](https://github.com/google/EarlGrey/tree/1.9.0) (03/31/2017) + +``` +Baseline: [6bceffc] + + [6bceffc]: Sync 1.9.0 +``` + +### Compatibility +* Requires iOS 8 as the minimum deployment target. +* Supports Xcode 8.3 and iOS 10.3 on devices and simulators. +* The EarlGrey gem runs out of the box for Swift 3.0 and Swift 2.3. + +### New Features +* Add `-[GREYKeyboard dismissKeyboardWithError:]` API to dismiss the keyboard. + +### Enhancements +* Improved earlgrey gem by removing post_install and letting pod update + the project. +* Improved swift support for `grey_allOf` and `grey_anyOf`. +* Several documentation updates including installation steps improvements. +* Added gem badge to `README.md`. + +### Contributors +* [bootstraponline](https://github.com/bootstraponline) +* [Felix Krause](https://github.com/KrauseFx)
+ +## [1.8.0](https://github.com/google/EarlGrey/tree/1.8.0) (03/17/2017) + +``` +Baseline: [0dc7c18] + + [0dc7c18]: 1.8.0 Release +``` + +### New Features +* Added multi-finger swipe action API's: + * grey_multiFingerSwipeFastInDirection + * grey_multiFingerSwipeSlowInDirection + * grey_multiFingerSwipeFastInDirectionWithStartPoint + * grey_multiFingerSwipeSlowInDirectionWithStartPoint + +### Bug Fixes +* Fixed issue with accessibility spamming "Remote service does not respond to _accessibilityMachPort" message on iOS 9.1 device. +* Fixed issues with EarlGrey working with a `UIAccessibilityTextFieldElement`. +* Fixed typing by blacklisting `UICompatibilityInputViewController` in UIViewController tracking. + +### Compatibility +* Requires iOS 8 as the minimum deployment target. +* Supports Xcode 8.3 beta 4 and iOS 10.3 on devices and simulators. +* The EarlGrey gem runs out of the box for Swift 3.0 and Swift 2.3. + +### Enhancements +* Improvements to the EarlGrey FunctionalTests TestRig. +* All `GREYAssertXXX` macros now wait for the app to idle before being evaluated. +* Unified the `Copy Files` modification script for Carthage and CocoaPods support. + +### Contributors +[bootstraponline](https://github.com/bootstraponline)
+[petaren](https://github.com/petaren) + +## [1.7.2](https://github.com/google/EarlGrey/tree/1.7.2) (02/17/2017) + +``` +Baseline: [6d55af5] + + [6d55af5]: 1.7.2 Release +``` + +### Bug Fixes +* Fixed Swizzler to properly reset swizzled selectors. +* Fixed typing by blacklisting UICompatibilityInputViewController in UIViewController tracking. + +### Compatibility +* Requires iOS 8 as the minimum deployment target. +* Supports Xcode 8.2.1 and iOS 10.2.1 on devices and simulators. +* The EarlGrey gem runs out of the box for Swift 3.0 and Swift 2.3. + +### Enhancements +* Updated analytics to use an client ID instead of user ID. + +### Contributors +[mbaxley](https://github.com/mbaxley), thank you! + +## [1.7.1](https://github.com/google/EarlGrey/tree/1.7.1) (02/03/2017) + +``` +Baseline: [e026773] ++ [e026773]: Change version numbers for EarlGrey 1.7.1 +``` + +### Bug Fixes +* Fixed an issue with constraint failure details not being logged in the error trace. +* Updated nullability for GREYMatchers to improve Swift support. +* Minor changes to logging strings and docs. + +### Compatibility +* Requires iOS 8 as the minimum deployment target. +* Supports Xcode 8.2.1 and iOS 10.2.1 on devices and simulators. +* The EarlGrey gem runs out of the box for Swift 3.0 and Swift 2.3. + +### Enhancements +* Updated analytics to use an md5 hashed uid. + +## [1.7.0](https://github.com/google/EarlGrey/tree/1.7.0) (01/25/2017) + +``` +Baseline: [f823ff2] ++ [f823ff2]: Removing JSON escape in reported errors. +``` + +### Bug Fixes +* Fixed a flake in testTrackingZombieQueue. +* Fixed CGRectIntegralInside to handle negative rectangles. +* Improved memory handling by moving autorelease pool inside loops. +* Fixed the bundle id to be consistent across all the test projects. +* Minor CI and other bug fixes. + +### Compatibility +* Requires iOS 8 as the minimum deployment target. +* Supports Xcode 8.2.1 and iOS 10.2.1 on devices and simulators. + +### New Features +* Updated analytics to include *hash* of test class name and *hash* of test case names to better estimate the volume of EarlGrey usage. +* Updated the readme to explain these changes. +* Updated tests for analytics to test new features. + +### Enhancements +* Improved EarlGrey error logging for better post processing [Issue #392](https://github.com/google/EarlGrey/issues/392). +* Removed the deprecated methods and cleaned up private headers. +* The EarlGrey gem runs out of the box for Swift 3.0 and Swift 2.3. + +### Deprecations +* Removed deprecated methods `grey_pinchFastInDirection` and `grey_pinchSlowInDirection` in favor of `grey_pinchFastInDirectionAndAngle` and `grey_pinchSlowInDirectionAndAngle` respectively. + +### Contributors +[bootstraponline](https://github.com/bootstraponline), [stkhapugin](https://github.com/stkhapugin) and [kebernet](https://github.com/kebernet) + +## [1.6.2](https://github.com/google/EarlGrey/tree/1.6.2) (01/06/2017) + +``` +Baseline: [0cdda9c] ++ [0cdda9c]: EarlGrey Sync for 1.6.2 +``` + +### Bug Fixes +* Updated the EarlGrey API for Swift 3.0 as per the latest guidelines. +* Improved web tests to work with current google.com UI. +* Fixed a bug in the visibility checker for 32bit platform. +* Fixed flakiness caused by NSDate issues in EarlGreyExampleSwiftTests. + +### Enhancements +* Added a travis hook to stop CI runs for docs-only changes. + +### Contributors +Thanks to [bootstraponline](https://github.com/bootstraponline) +and the rest of the contributors! + +## [1.6.1](https://github.com/google/EarlGrey/tree/1.6.1) (12/20/2016) + +``` +Baseline: [9e04024] + + [9e04024]: Release 1.6.1 +``` + +### Bug Fixes +* Add a test for long pressing the link in the UI webview. +* Fix issue with xcodeproj gem in travis runs. + +### Enhancements +* Update travis run to use Xcode 8.2 + +## [1.6.0](https://github.com/google/EarlGrey/tree/1.6.0) (12/06/2016) + +``` +Baseline: [5080a21] + + [5080a21]: Updated changelog info.plist pod spec and gem version for 1.6.0 release. +``` + +### Compatibility +* Requires iOS 8 as the minimum deployment target. +* The EarlGrey gem runs out of the box for Swift 3.0 and Swift 2.3. +* Has been tested for support till iOS 10.1 on devices and simulator. + +### Bug Fixes +* Fixed CocoaPods issue with using EarlGrey as a module in Swift projects. +* Fixed issue with Accessibility service not enabled for simulators and devices. +* Minor documentation and syntax fixes. + +### Enhancements +* Moved failure handler from a global variable to a thread local storage, like NSAssertionHandlers. +* Exposed the angle for pinch action in GREYPinchAction. +* Added EarlGreyExample CocoaPods project to travis. + +### Deprecations +* Deprecated `grey_pinchSlowInDirection` and `grey_pinchFastInDirection` in favor of + `grey_pinchFastInDirectionAndAngle` and `grey_pinchSlowInDirectionAndAngle`. + +## [1.5.3](https://github.com/google/EarlGrey/tree/1.5.3) (11/14/2016) + +``` +Baseline: [690eaa2] + + [690eaa2]: Updated ChangeLog and pod spec for 1.5.3 release +``` + +### Enhancements +* Resolve CocoaPods rating [Github issue](https://github.com/CocoaPods/CocoaPods/issues/6175) + +## [1.5.2](https://github.com/google/EarlGrey/tree/1.5.2) (11/11/2016) + +``` +Baseline: [f3ee931] + + [f3ee931]: Updated ChangeLog and pod spec for 1.5.2 release +``` + +### Compatibility +* Requires iOS 8 as the minimum deployment target. +* The EarlGrey gem runs out of the box for Swift 3.0 and Swift 2.3. +* Has been tested for support till iOS 10.1 on devices and simulator. + +### Enhancements +* Enhance precision of timer used for touch injection +* Removed requirement for bridging header for Swift and EarlGrey + +## [1.5.1](https://github.com/google/EarlGrey/tree/1.5.1) (11/07/2016) + +``` +Baseline: [d9eb1bc] + + [d9eb1bc]: Updated ChangeLog and pod spec for 1.5.1 release +``` + +### Compatibility +* Requires iOS 8 as the minimum deployment target. +* The EarlGrey gem runs out of the box for Swift 3.0 and Swift 2.3. +* Has been tested for support till iOS 10.01 on devices and simulator. + +### Bug Fixes +* Fixed CI Ruby test for Carthage. + +### Enhancements +* Improved touch injection speed by making it work independent of the screen refresh rate. +* Added synchronization for `NSURLConnection::sendSynchronousRequest`. +* Exclude URLs that start with `data` scheme from being synchronized. +* Updated `grey_clearText` action to accept elements conforming to UITextInput protocol. + +## [1.5.0](https://github.com/google/EarlGrey/tree/1.5.0) (10/31/2016) + +``` +Baseline: [55d42a4] + + [55d42a4]: Updated ChangeLog and pod spec for 1.5 release +``` + +### Compatibility +* Requires iOS 8 as the minimum deployment target. +* The EarlGrey gem runs out of the box for [Swift 3.0](https://docs.google.com/document/d/1AeleXccp35EUX4ILa6CT3CwlxLSZq1YLrco9JF27p9k/edit) and Swift 2.3. +* Has been tested for support till iOS 10.01 on devices and simulator. + +### Bug Fixes +* Failing analytics tests fixes. +* Fixed flaky Travis Stopwatch Test. +* Fixed rspec tests broken by ruby update and changing the directory. + +### Enhancements +* Improved UIAppStateTracker APIs to allow for ignoring states. +* Improved failure handlers for multiple invocations within context of a valid test case. + +### Deprecations +* Swift 2.2 is no longer supported. + +## [1.4.0](https://github.com/google/EarlGrey/tree/1.4.0) (10/07/2016) + +``` +Baseline: [b5e34db] + + [b5e34db]: Update Info.plist / Podspec / Cheatsheet for EarlGrey 1.4.0 +``` + +### Compatibility +* Requires iOS 8 as the minimum deployment target. +* EarlGrey.gem runs out of the box for Swift 2.2.x. For Swift 3.0, please + use the [Swift Migration Guide](https://swift.org/migration-guide/) to + add the `Use Legacy Swift` build setting to your test target until we + provide support. +* Has been tested for support till iOS 10.01 on devices and simulator. + +### Enhancements +* A better way to blacklist URL's in GREYConfiguration by adding them to an NSArray. +* A verbose logger to provide more descriptive EarlGrey logs that can be enabled by + setting the `kGREYAllowVerboseLogging` key in NSUserDefaults to `YES`. Verbose + logging also measures the performance of interactions and the thread executor by + using a stopwatch class. +* Improvements to `-[XCTestCase greyStatus]` to better reflect the status of a test. + +### Bug Fixes +* Corrected selection of `UIPickerView`s even when they were disabled. +* Minor documentation and syntax fixes. + +### Deprecations +* Deprecated `GREYFail` in favor of `GREYFailWithDetails`. + +## [1.3.1](https://github.com/google/EarlGrey/tree/1.3.1) (09/19/2016) + +``` +Baseline: [c4913b] + + [c4913b]: Update compatibility doc to include iOS 10. +``` + +### Compatibility +* Requires iOS 8 as the minimum deployment target. +* Has been tested for support till iOS 10.01 on devices and simulator. + +### Enhancements +* Add autolayout to `FTRTypingViewController` + +### Bug Fixes +* Minor documentation and syntax fixes. +* Fixed Functional Test Project scheme preventing it to be run on devices. +* Add a temporary hold on the xcodeproj gem dependency to unblock tests. + +## [1.3.0](https://github.com/google/EarlGrey/tree/1.3.0) (09/09/2016) + +``` +Baseline: [6b2f329] + + [6b2f329]: Add fixes for documentation. +``` + +### Compatibility +* Requires iOS 8 as the minimum deployment target. +* Has been tested for support till iOS 10 beta 4. + +### New Features + +* The following new matchers were added EarlGrey: + * `grey_selected`: Checks if a UIControl is selected. + * `grey_accessibilityFocused`: Checks if a UI element is focused by accessibility technologies + like Voiceover or Switch Control. + +### Enhancements +* Added an API to find the `XCTestCase` status through an EarlGrey test run. +* Improved the failure description in the failure handler. +* Made the `EarlGrey.swift` file syntax swiftier. +* Improved Unit and Functional test coverage. + +### Bug Fixes +* Fixed Travis issue with the Ruby version. +* Minor documentation and syntax fixes. + +### Deprecations +* `grey_elementAtIndex` has been removed in favor of the `atIndex:` interaction API. For migrating + your tests, please follow the announcement + [here](https://groups.google.com/forum/#!topic/earlgrey-discuss/Q6RhxRhtRvo). + +### Contributors +Special thanks to [axi0mX](https://github.com/axi0mX), +[bootstraponline](https://github.com/bootstraponline), +[KazuCocoa](https://github.com/KazuCocoa) and the rest of our contributors. + +## [1.2.0](https://github.com/google/EarlGrey/tree/1.2.0) (08/31/2016) + +``` +Baseline: [7070e1a] + + [7070e1a]: Updated cheatsheet and podspec for 1.2.0 release +``` + +### New Features + +* EarlGrey now supports multi-touch gestures! Following pinch actions have been added: + * `grey_pinchFastInDirection` + * `grey_pinchSlowInDirection` +* Added `atIndex:` interaction API to select from multiple element matches. + +### Enhancements +* Updated Swift Macros in EarlGrey gem. +* Implemented matcher for UIScrollView scrolled to content edge. + +### Bug Fixes +* Fixed several typos and cleaned up many project files with proper error messages. +* Added carthage `xcodebuild` command to Travis CI. +* Fixed issue with action{Did,Will}PerformAction notification and its userInfo. +* Updated protocol signatures. + +### Contributors +Special thanks to [axi0mX](https://github.com/axi0mX) and the rest of our contributors. + +## [1.1.0](https://github.com/google/EarlGrey/tree/1.1.0) (08/18/2016) + +``` +Baseline: [107dba5] + + [107dba5]: Update podspec for 1.1.0 release [ci skip] +``` + +### New Features + +* API reference documentation generated via [Jazzy](https://rubygems.org/gems/jazzy/) +* Cheatsheet for EarlGrey +* Carthage support +* Easier CocoaPods setup using [EarlGrey gem](https://rubygems.org/gems/earlgrey) +which replaces manually copying over `configure_earlgrey_pods.rb` and `EarlGrey.swift` file. + +### Enhancements + +* For demonstration purposes added Swift demo app and tests +* Update documentation for Swift usage +* Update contribution guidelines +* Added `grey_allOfMatchers` and `grey_anyOfMatchers` to EarlGrey.swift +* Use XCTest's mechanism of halting test execution instead of throwing arbitrary exception +* Helper method to speed up animation +* Added `grey_replaceText` action to directly replace text (without using keyboard) on a field +* Created `grey_atIndex` matcher for matching a single element from a list of matched elements +* Updated FAQs with questions and examples +* Update install guide with Cocoapods 0.39 support +* Added Badge for License, Cocoapod, and Travis +* Efficiency improvement in `GREYAppStateTracker` reducing O(n) to constant amortized time +* Improved webview synchronization +* Added tracking for `dispatch_async_f` and `dispatch_sync_f` methods +* Reduce throttling of CPU by allowing runloops to sleep when idle +* Removed unnecessary runloop drains improving overall speed and reliability +* Introduced trackers for `NSManagedObjectContext` +* Signal handlers and uncaught exception handler invoke previously installed handlers +* Improved accessibility logic to support beta versions of iOS 10 + +### Bug Fixes + +* Race conditions in `GREYOperationQueueIdlingResourceTest` +* Race conditions in `GREYDispatchQueueIdlingResourceTest` +* Addressed Swift 3 related warnings in `EarlGrey.swift` +* Resigning first responder for autocorrect-enabled fields causes keyboard track to mistrack +keyboard disappearance events +* EarlGrey.xcodeproj fails to build for device because code signing identities aren't set +correctly +* Assertion failure in `-[GREYElementProvider dataEnumerator]` due to nil accessibility element +* Rubocop warnings in configure_earlgrey_pods.rb script and Podfile +* EarlGreyFunctionalTests `testSwipeOnWindow` always fails on iPhone 4S +* If parent directory has spaces, `setup-earlgrey.sh` will fail and exit +* Retain cycle in `GREYElementInteraction` +* Retain cycle in `UIApplication` mock in test suite +* Changed CFBundlePackageType in EarlGrey-Info.plist to FMWK + +### Contributors +Special thanks to [bootstraponline](https://github.com/bootstraponline), +[axi0mX](https://github.com/axi0mX), and the rest of our contributors. + +## [1.0.0](https://github.com/google/EarlGrey/tree/1.0.0) (02/16/2016) + +First cup of EarlGrey. + +``` +Baseline: [7099484] + + [7099484]: First version of EarlGrey. +``` + +Initial release. diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/EarlGrey b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/EarlGrey new file mode 100755 index 0000000000..878bf4c514 Binary files /dev/null and b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/EarlGrey differ diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/EarlGrey.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/EarlGrey.h new file mode 100644 index 0000000000..cfee5b342a --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/EarlGrey.h @@ -0,0 +1,73 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * Umbrella public header for the EarlGrey framework. + * + * Instead of importing individual headers, import this header using: + * @code + * @import EarlGrey; // if your project uses modules + * @endcode + * OR if your project doesn't use modules: + * @code + * #import + * @endcode + * + * To learn more, check out: http://github.com/google/EarlGrey + */ + +#import + +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/EarlGreyImpl.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/EarlGreyImpl.h new file mode 100644 index 0000000000..eefe229908 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/EarlGreyImpl.h @@ -0,0 +1,173 @@ +// +// Copyright 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import + +#import + +@class GREYElementInteraction, GREYFrameworkException; +@protocol GREYMatcher, GREYFailureHandler; + +/** + * Convenience replacement for every EarlGrey method call with + * EarlGreyImpl::invokedFromFile:lineNumber: so it can get the invocation file and line to + * report to XCTest on failure. + */ +#define EarlGrey \ + [EarlGreyImpl invokedFromFile:[NSString stringWithUTF8String:__FILE__] ?: @"UNKNOWN FILE" \ + lineNumber:__LINE__] + +NS_ASSUME_NONNULL_BEGIN + +/** + * Key for currently set failure handler for EarlGrey in thread's local storage dictionary. + */ +GREY_EXTERN NSString *const kGREYFailureHandlerKey; + +/** + * Error domain for keyboard dismissal. + */ +GREY_EXTERN NSString *const kGREYKeyboardDismissalErrorDomain; + +/** + * Error code for keyboard dismissal actions. + */ +typedef NS_ENUM(NSInteger, GREYKeyboardDismissalErrorCode) { + /** + * The keyboard dismissal failed. + */ + GREYKeyboardDismissalFailedErrorCode = 0, // Keyboard Dismissal failed. +}; + +/** + * Entrypoint to the EarlGrey framework. + * Use methods of this class to initiate interaction with any UI element on the screen. + */ +@interface EarlGreyImpl : NSObject + +/** + * Provides the file name and line number of the code that is calling into EarlGrey. + * In case of a failure, the information is used to tell XCTest the exact line which caused + * the failure so it can be highlighted in the IDE. + * + * @param fileName The name of the file where the failing code exists. + * @param lineNumber The line number of the failing code. + * + * @return An EarlGreyImpl instance, with details of the code invoking EarlGrey. + */ ++ (instancetype)invokedFromFile:(NSString *)fileName lineNumber:(NSUInteger)lineNumber; + +/** + * @remark init is not an available initializer. Use the EarlGrey macro to start an + * interaction. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * Creates a pending interaction with a single UI element on the screen. + * + * In this step, a matcher is supplied to EarlGrey which is later used to sift through the elements + * in the UI Hierarchy. This method only denotes that you have an intent to perform an action and + * packages a GREYElementInteraction object to do so. + * The interaction is *actually* started when it's performed with a @c GREYAction or + * @c GREYAssertion. + * + * An interaction will fail when multiple elements are matched. In that case, you will have to + * refine the @c elementMatcher to match a single element or use GREYInteraction::atIndex: to + * specify the index of the element in the list of elements matched. + * + * By default, EarlGrey looks at all the windows from front to back and + * searches for the UI element. To focus on a specific window or container, use + * GREYElementInteraction::inRoot: method. + * + * For example, this code will match a UI element with accessibility identifier "foo" + * inside a custom UIWindow of type MyCustomWindow: + * @code + * [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"foo")] + * inRoot:grey_kindOfClass([MyCustomWindow class])] + * @endcode + * + * @param elementMatcher The matcher specifying the UI element that will be targeted by the + * interaction. + * + * @return A GREYElementInteraction instance, initialized with an appropriate matcher. + */ +- (GREYElementInteraction *)selectElementWithMatcher:(id)elementMatcher; + +/** + * Sets the global failure handler for all framework related failures. + * + * A default failure handler is provided by the framework and it is @b strongly advised to use + * that if you don't need to customize error handling in your test. Passing in @c nil will revert + * the failure handler to default framework provided failure handler. + * + * @param handler The failure handler to be used for all test failures. + */ +- (void)setFailureHandler:(_Nullable id)handler; + +/** + * Convenience wrapper to invoke GREYFailureHandler::handleException:details: on the global + * failure handler. + * + * @param exception The exception to be handled. + * @param details Any extra details about the failure. + */ +- (void)handleException:(GREYFrameworkException *)exception details:(NSString *)details; + +/** + * Rotate the device to a given @c deviceOrientation. All device orientations except for + * @c UIDeviceOrientationUnknown are supported. If a non-nil @c errorOrNil is provided, it will + * be populated with the failure reason if the orientation change fails, otherwise a test failure + * will be registered. + * + * @param deviceOrientation The desired orientation of the device. + * @param[out] errorOrNil Error that will be populated on failure. If @c nil, a test + * failure will be reported if the rotation attempt fails. + * + * @return @c YES if the rotation was successful, @c NO otherwise. + */ +- (BOOL)rotateDeviceToOrientation:(UIDeviceOrientation)deviceOrientation + errorOrNil:(__strong NSError **)errorOrNil; + +/** + * Shakes the device. If a non-nil @c errorOrNil is provided, it will + * be populated with the failure reason if the orientation change fails, otherwise a test failure + * will be registered. + * + * @param[out] errorOrNil Error that will be populated on failure. If @c nil, the a test + * failure will be reported if the shake attempt fails. + * + * @throws GREYFrameworkException if the action fails and @c errorOrNil is @c nil. + * @return @c YES if the shake was successful, @c NO otherwise. If @c errorOrNil is @c nil and + * the operation fails, it will throw an exception. + */ +- (BOOL)shakeDeviceWithError:(__strong NSError **)errorOrNil; + +/** + * Dismisses the keyboard by resigning the first responder, if any. Will populate the provided + * error if the first responder is not present or if the keyboard is not visible. + * + * @param[out] errorOrNil Error that will be populated on failure. If @c nil, a test + * failure will be reported if the dismissing fails. + * + * @return @c YES if the dismissing of the keyboard was successful, @c NO otherwise. + */ +- (BOOL)dismissKeyboardWithError:(__strong NSError **)errorOrNil; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYAction.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYAction.h new file mode 100644 index 0000000000..a13d5075ff --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYAction.h @@ -0,0 +1,51 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A protocol for actions that are performed on accessibility elements. + */ +@protocol GREYAction + +/** + * Perform the action specified by the GREYAction object on an @c element if and only if the + * @c element matches the constraints of the action. + * + * @param element The element the action is to be performed on. This must not be @c nil. + * @param[out] errorOrNil Error that will be populated on failure. The implementing class should + * handle the behavior when it is @c nil by, for example, logging the error + * or throwing an exception. + * + * @return @c YES if the action succeeded, else @c NO. If an action returns @c NO, it does not + * mean that the action was not performed at all but somewhere during the action execution + * the error occurred and so the UI may be in an unrecoverable state. + */ +- (BOOL)perform:(id)element error:(__strong NSError *_Nullable *)errorOrNil; + +/** + * A method to get the name of this action. + * + * @return The name of the action. If the action fails, then the name is printed along with all + * other relevant information. + */ +- (NSString *)name; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYActionBlock.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYActionBlock.h new file mode 100644 index 0000000000..a7a53c3ba4 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYActionBlock.h @@ -0,0 +1,94 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +@protocol GREYMatcher; + +NS_ASSUME_NONNULL_BEGIN + +/** + * Block type for defining the action's 'perform' code. + * + * @param element The element on which the block is going to be performed. + * @param[out] errorOrNil The error set on failure. The error returned can be @c nil, signifying + * that the action succeeded. + * + * @throws NSException when there is a failure and @c errorOrNil is not provided + * (i.e. it is @c nil). + * + * @return @c YES if the action performed succeeded, else @c NO. + */ +typedef BOOL (^GREYPerformBlock)(id element, __strong NSError *_Nullable *errorOrNil); + +/** + * A class for creating block based GREYAction. + */ +@interface GREYActionBlock : GREYBaseAction + +/** + * Creates a GREYAction that performs the action in the provided @c block. + * + * @param name The name of the action + * @param block A block that contains the action to execute. + * + * @return A GREYActionBlock instance with the given name. + */ ++ (instancetype)actionWithName:(NSString *)name performBlock:(GREYPerformBlock)block; + +/** + * Creates a GREYAction that performs the action in the provided @c block subject to the + * provided @c constraints. + * + * @param name The name of the action. + * @param constraints Constraints that must be satisfied before the action is performed + * This is optional and can be @c nil. + * @param block A block that contains the action to execute. + * + * @return A GREYActionBlock instance with the given name and constraints. + */ ++ (instancetype)actionWithName:(NSString *)name + constraints:(id _Nullable)constraints + performBlock:(GREYPerformBlock)block; + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * @remark initWithName::constraints: is overridden from its superclass. + */ +- (instancetype)initWithName:(NSString *)name + constraints:(id)constraints NS_UNAVAILABLE; + +/** + * Designated Initializer. + * + * @param name The name of the action. + * @param constraints Constraints that must be satisfied before the action is performed + * This is optional and can be @c nil. + * @param block A block that contains the action to execute. + * + * @return A GREYActionBlock instance with the given name and constraints. + */ +- (instancetype)initWithName:(NSString *)name + constraints:(id _Nullable)constraints + performBlock:(GREYPerformBlock)block NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYActions.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYActions.h new file mode 100644 index 0000000000..f289d622f5 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYActions.h @@ -0,0 +1,545 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import +#import + +@protocol GREYAction; + +NS_ASSUME_NONNULL_BEGIN + +/** + * A interface that exposes UI element actions. + */ +@interface GREYActions : NSObject + +/** + * @return A GREYAction that performs multiple taps of a specified @c count. + */ ++ (id)actionForMultipleTapsWithCount:(NSUInteger)count; + +/** + * @return A GREYAction that performs multiple taps of a specified @c count at a specified + * @c point. + */ ++ (id)actionForMultipleTapsWithCount:(NSUInteger)count atPoint:(CGPoint)point; + +/** + * Returns an action that holds down finger for 1.0 second (@c kGREYLongPressDefaultDuration) to + * simulate a long press. + * + * @return A GREYAction that performs a long press on an element. + */ ++ (id)actionForLongPress; + +/** + * Returns an action that holds down finger for specified @c duration to simulate a long press. + * + * @param duration The duration of the long press. + * + * @return A GREYAction that performs a long press on an element. + */ ++ (id)actionForLongPressWithDuration:(CFTimeInterval)duration; + +/** + * Returns an action that holds down finger for specified @c duration at the specified @c point + * (interpreted as being relative to the element) to simulate a long press. + * + * @param point The point that should be tapped. + * @param duration The duration of the long press. + * + * @return A GREYAction that performs a long press on an element. + */ ++ (id)actionForLongPressAtPoint:(CGPoint)point duration:(CFTimeInterval)duration; + +/** + * Returns an action that scrolls a @c UIScrollView by @c amount (in points) in the specified + * @c direction. + * + * @param direction The direction of the swipe. + * @param amount The amount of points in CGPoints to scroll. + * + * @return A GREYAction that scrolls a scroll view in a given @c direction for a given @c amount. + */ ++ (id)actionForScrollInDirection:(GREYDirection)direction amount:(CGFloat)amount; + +/** + * Returns a scroll action that scrolls in a @c direction for an @c amount of points starting from + * the given start point specified as percentages. @c xOriginStartPercentage is the x start + * position as a percentage of the total width of the scrollable visible area, + * @c yOriginStartPercentage is the y start position as a percentage of the total height of the + * scrollable visible area. @c xOriginStartPercentage and @c yOriginStartPercentage must be between + * 0 and 1, exclusive. + * + * @param direction The direction of the scroll. + * @param amount The amount scroll in points to inject. + * @param xOriginStartPercentage X coordinate of the start point specified as a percentage (0, 1) + * exclusive, of the total width of the scrollable visible area. + * @param yOriginStartPercentage Y coordinate of the start point specified as a percentage (0, 1) + * exclusive, of the total height of the scrollable visible area. + * + * @return A GREYAction that scrolls a scroll view in a given @c direction for a given @c amount + * starting from the given start points. + */ ++ (id)actionForScrollInDirection:(GREYDirection)direction + amount:(CGFloat)amount + xOriginStartPercentage:(CGFloat)xOriginStartPercentage + yOriginStartPercentage:(CGFloat)yOriginStartPercentage; + +/** + * @return A GREYAction that scrolls to the given content @c edge of a scroll view. + */ ++ (id)actionForScrollToContentEdge:(GREYContentEdge)edge; + +/** + * A GREYAction that scrolls to the given content @c edge of a scroll view with the scroll action + * starting from the given start point specified as percentages. @c xOriginStartPercentage is the x + * start position as a percentage of the total width of the scrollable visible area, + * @c yOriginStartPercentage is the y start position as a percentage of the total height of the + * scrollable visible area. @c xOriginStartPercentage and @c yOriginStartPercentage must be between + * 0 and 1, exclusive. + * + * @param edge The edge towards which the scrolling is to take place. + * @param xOriginStartPercentage X coordinate of the start point specified as a percentage (0, 1) + * exclusive, of the total width of the scrollable visible area. + * @param yOriginStartPercentage Y coordinate of the start point specified as a percentage (0, 1) + * exclusive, of the total height of the scrollable visible area. + * + * @return A GREYAction that scrolls to the given content @c edge of a scroll view with the scroll + * action starting from the given start point. + */ ++ (id)actionForScrollToContentEdge:(GREYContentEdge)edge + xOriginStartPercentage:(CGFloat)xOriginStartPercentage + yOriginStartPercentage:(CGFloat)yOriginStartPercentage; + +/** + * Returns an action that fast swipes through the view. The start point of the swipe is chosen to + * achieve the maximum the swipe possible to the other edge. + * + * @param direction The direction of the swipe. + * + * @return A GREYAction that performs a fast swipe in the given direction. + */ ++ (id)actionForSwipeFastInDirection:(GREYDirection)direction; + +/** + * Returns an action that slow swipes through the view. The start point of the swipe is chosen to + * achieve maximum the swipe possible to the other edge. + * + * @param direction The direction of the swipe. + * + * @return A GREYAction that performs a slow swipe in the given direction. + */ ++ (id)actionForSwipeSlowInDirection:(GREYDirection)direction; + +/** + * Returns an action that swipes through the view quickly in the given @c direction from a specific + * origin. + * + * @param direction The direction of the swipe. + * @param xOriginStartPercentage the x start position as a percentage of the total width + * of the view. This must be between 0 and 1. + * @param yOriginStartPercentage the y start position as a percentage of the total height + * of the view. This must be between 0 and 1. + * + * @return A GREYAction that performs a fast swipe through a view in a specific direction from + * the specified point. + */ ++ (id)actionForSwipeFastInDirection:(GREYDirection)direction + xOriginStartPercentage:(CGFloat)xOriginStartPercentage + yOriginStartPercentage:(CGFloat)yOriginStartPercentage; + +/** + * Returns an action that swipes through the view quickly in the given @c direction from a + * specific origin. + * + * @param direction The direction of the swipe. + * @param xOriginStartPercentage the x start position as a percentage of the total width + * of the view. This must be between 0 and 1. + * @param yOriginStartPercentage the y start position as a percentage of the total height + * of the view. This must be between 0 and 1. + * + * @return A GREYAction that performs a slow swipe through a view in a specific direction from + * the specified point. + */ ++ (id)actionForSwipeSlowInDirection:(GREYDirection)direction + xOriginStartPercentage:(CGFloat)xOriginStartPercentage + yOriginStartPercentage:(CGFloat)yOriginStartPercentage; + +/** + * Returns an action that performs a multi-finger slow swipe through the view in the given + * @c direction. + * + * @param direction The direction of the swipe. + * @param numberOfFingers Number of fingers touching the screen for the swipe. + * + * @return A GREYAction that performs a multi-finger slow swipe through a view in a specific + * direction from the specified point. + */ ++ (id)actionForMultiFingerSwipeSlowInDirection:(GREYDirection)direction + numberOfFingers:(NSUInteger)numberOfFingers; + +/** + * Returns an action that performs a multi-finger fast swipe through the view in the given + * @c direction. + * + * @param direction The direction of the swipe. + * @param numberOfFingers Number of fingers touching the screen for the swipe. + * + * @return A GREYAction that performs a multi-finger fast swipe through a view in a specific + * direction from the specified point. + */ ++ (id)actionForMultiFingerSwipeFastInDirection:(GREYDirection)direction + numberOfFingers:(NSUInteger)numberOfFingers; + +/** + * Returns an action that performs a multi-finger slow swipe through the view in the given + * @c direction from a specified origin. + * + * @param direction The direction of the swipe. + * @param numberOfFingers Number of fingers touching the screen for the swipe. + * @param xOriginStartPercentage The x start position as a percentage of the total width + * of the view. This must be between 0 and 1. + * @param yOriginStartPercentage The y start position as a percentage of the total height + * of the view. This must be between 0 and 1. + * + * @return A GREYAction that performs a multi-finger slow swipe through a view in a specific + * direction from the specified point. + */ ++ (id)actionForMultiFingerSwipeSlowInDirection:(GREYDirection)direction + numberOfFingers:(NSUInteger)numberOfFingers + xOriginStartPercentage:(CGFloat)xOriginStartPercentage + yOriginStartPercentage:(CGFloat)yOriginStartPercentage; + +/** + * Returns an action that performs a multi-finger fast swipe through the view in the given + * @c direction from a specified origin. + * + * @param direction The direction of the swipe. + * @param numberOfFingers Number of fingers touching the screen for the swipe. + * @param xOriginStartPercentage The x start position as a percentage of the total width + * of the view. This must be between 0 and 1. + * @param yOriginStartPercentage The y start position as a percentage of the total height + * of the view. This must be between 0 and 1. + * + * @return A GREYAction that performs a multi-finger fast swipe through a view in a specific + * direction from the specified point. + */ ++ (id)actionForMultiFingerSwipeFastInDirection:(GREYDirection)direction + numberOfFingers:(NSUInteger)numberOfFingers + xOriginStartPercentage:(CGFloat)xOriginStartPercentage + yOriginStartPercentage:(CGFloat)yOriginStartPercentage; + +/** + * Returns an action that pinches view quickly in the specified @c direction and @c angle. + * + * @param pinchDirection The direction of the pinch action. + * @param angle The angle of the pinch action in radians. + * Use @c kGREYPinchAngleDefault for the default angle (currently set to + * 30 degrees). + * + * @return A GREYAction that performs a fast pinch on the view in the specified @c direction. + */ ++ (id)actionForPinchFastInDirection:(GREYPinchDirection)pinchDirection + withAngle:(double)angle; + +/** + * Returns an action that pinches view slowly in the specified @c direction and @c angle. + * + * @param pinchDirection The direction of the pinch action. + * @param angle The angle of the pinch action in radians. + * Use @c kGREYPinchAngleDefault for the default angle (currently set to + * 30 degrees). + * + * @return A GREYAction that performs a slow pinch on the view in the specified @c direction. + */ ++ (id)actionForPinchSlowInDirection:(GREYPinchDirection)pinchDirection + withAngle:(double)angle; + +/** + * Returns an action that attempts to move slider to within 1.0e-6f values of @c value. + * + * @param value The value to which the slider should be moved. If this is not attainable after a + * reasonable number of attempts (currently 10) we assume that the @c value is + * unattainable for a user (it is probably the case this value resides between two + * pixels). In this case, the slider will end up at a user attainable value + * that is closest to @c value. + * + * @return A GREYAction that moves a slider to a given @c value. + */ ++ (id)actionForMoveSliderToValue:(float)value; + +/** + * Returns an action that changes the value of UIStepper to @c value by tapping the appropriate + * button multiple times. + * + * @param value The value to change the UIStepper to. + * + * @return A GREYAction that sets the given @c value on a stepper. + */ ++ (id)actionForSetStepperValue:(double)value; + +/** + * Returns an action that taps on an element at the activation point of the element. + * + * @return A GREYAction to tap on an element. + */ ++ (id)actionForTap; + +/** + * Returns an action that taps on an element at the specified @c point. + * + * @param point The point that should be tapped. It must be in the coordinate system of the + * element and it's position is relative to the origin of the element, as in + * (element_width/2, element_height/2) will tap at the center of element. + * + * @return A GREYAction to tap on an element at a specific point. + */ ++ (id)actionForTapAtPoint:(CGPoint)point; + +/** + * Returns an action that uses the iOS keyboard to input a string. + * + * @param text The text to be typed. For Objective-C, backspace is supported by using "\b" in the + * string and "\u{8}" in Swift strings. Return key is supported with "\n". + * For Example: @"Helpo\b\bloWorld" will type HelloWorld in Objective-C. + * "Helpo\u{8}\u{8}loWorld" will type HelloWorld in Swift. + * + * @return A GREYAction to type a specific text string in a text field. + */ ++ (id)actionForTypeText:(NSString *)text; + +/** + * Returns an action that sets text on a UITextField or webview input directly. + * + * @param text The text to be typed. + * + * @return A GREYAction to type a specific text string in a text field. + */ ++ (id)actionForReplaceText:(NSString *)text; + +/** + * @return A GREYAction that clears a text field by injecting back-spaces. + */ ++ (id)actionForClearText; + +/** + * Returns an action that toggles a switch control. This action is applicable to all elements that + * implement the selector UISwitch::isOn and include UISwitch controls. + * + * @param on The switch control state. + * + * @return A GREYAction to toggle a UISwitch. + */ ++ (id)actionForTurnSwitchOn:(BOOL)on; + +/** + * Returns an action that injects dates/times into UIDatePickers. + * + * @param date The date to set the UIDatePicker. + * + * @return A GREYAction that sets a given date/time on a UIDatePicker. + */ ++ (id)actionForSetDate:(NSDate *)date; + +/** + * Returns an action that selects @c value on the given @c column of a UIPickerView. + * + * @param column The UIPickerView column being set. + * @param value The value to set the UIPickerView. + * + * @return A GREYAction to set the value of a specified column of a UIPickerView. + */ ++ (id)actionForSetPickerColumn:(NSInteger)column toValue:(NSString *)value; + +/** + * Returns an action that executes JavaScript against a UIWebView and sets the return value to + * @c outResult if provided. + * + * @param js The Javascript code to be executed. + * @param[out] outResult The result of the code execution. + * + * @return A GREYAction that executes JavaScript code against a UIWebView. + */ ++ (id)actionForJavaScriptExecution:(NSString *)js + output:(__strong NSString *_Nullable *_Nullable)outResult; + +/** + * Returns an action that takes a snapshot of the selected element. + * + * @param[out] outImage The UIImage where the image content is stored. + * + * @return A GREYAction that takes a snapshot of an UI element. + */ ++ (id)actionForSnapshot:(__strong UIImage *_Nullable *_Nullable)outImage; + +@end + +#if !(GREY_DISABLE_SHORTHAND) +/** Shorthand macro for GREYActions::actionForMultipleTapsWithCount: with count @c 2. */ +GREY_EXPORT id grey_doubleTap(void); + +/** + * Shorthand macro for + * GREYActions::actionForMultipleTapsWithCount: with count @c 2 and @c point. + */ +GREY_EXPORT id grey_doubleTapAtPoint(CGPoint point); + +/** Shorthand macro for GREYActions::actionForMultipleTapsWithCount:. */ +GREY_EXPORT id grey_multipleTapsWithCount(NSUInteger count); + +/** Shorthand macro for GREYActions::actionForLongPress. */ +GREY_EXPORT id grey_longPress(void); + +/** Shorthand macro for GREYActions::actionForLongPressWithDuration:. */ +GREY_EXPORT id grey_longPressWithDuration(CFTimeInterval duration); + +/** Shorthand macro for GREYActions::actionForLongPressAtPoint:duration:. */ +GREY_EXPORT id grey_longPressAtPointWithDuration(CGPoint point, + CFTimeInterval duration); + +/** Shorthand macro for GREYActions::actionForScrollInDirection:amount:. */ +GREY_EXPORT id grey_scrollInDirection(GREYDirection direction, CGFloat amount); + +/** + * Shorthand macro for + * GREYActions::actionForScrollInDirection:amount:xOriginStartPercentage:yOriginStartPercentage:. + */ +GREY_EXPORT id grey_scrollInDirectionWithStartPoint(GREYDirection direction, + CGFloat amount, + CGFloat xOriginStartPercentage, + CGFloat yOriginStartPercentage); + +/** Shorthand macro for GREYActions::actionForScrollToContentEdge:. */ +GREY_EXPORT id grey_scrollToContentEdge(GREYContentEdge edge); + +/** + * Shorthand macro for + * GREYActions::actionForScrollToContentEdge:xOriginStartPercentage:yOriginStartPercentage:. + */ +GREY_EXPORT id grey_scrollToContentEdgeWithStartPoint(GREYContentEdge edge, + CGFloat xOriginStartPercentage, + CGFloat yOriginStartPercentage); + +/** Shorthand macro for GREYActions::actionForSwipeFastInDirection:. */ +GREY_EXPORT id grey_swipeFastInDirection(GREYDirection direction); + +/** Shorthand macro for GREYActions::actionForSwipeSlowInDirection:. */ +GREY_EXPORT id grey_swipeSlowInDirection(GREYDirection direction); + +/** + * Shorthand macro for + * GREYActions::actionForSwipeFastInDirection:xOriginStartPercentage:yOriginStartPercentage:. + */ +GREY_EXPORT id grey_swipeFastInDirectionWithStartPoint(GREYDirection direction, + CGFloat xOriginStartPercentage, + CGFloat yOriginStartPercentage); + +/** + * Shorthand macro for + * GREYActions::actionForSwipeSlowInDirection:xOriginStartPercentage:yOriginStartPercentage:. + */ +GREY_EXPORT id grey_swipeSlowInDirectionWithStartPoint(GREYDirection direction, + CGFloat xOriginStartPercentage, + CGFloat yOriginStartPercentage); + +/** + * Shorthand macro for + * GREYActions::actionForMultiFingerSwipeSlowInDirection:numberOfFingers:. + */ +GREY_EXPORT id grey_multiFingerSwipeSlowInDirection(GREYDirection direction, + NSUInteger numberOfFingers); + +/** + * Shorthand macro for + * GREYActions::actionForMultiFingerSwipeFastInDirection:numberOfFingers:. + */ +GREY_EXPORT id grey_multiFingerSwipeFastInDirection(GREYDirection direction, + NSUInteger numberOfFingers); + +/** + * Shorthand macro for + * GREYActions::actionForMultiFingerSwipeSlowInDirection:numberOfFingers:xOriginStartPercentage: + * yOriginStartPercentage:. + */ +GREY_EXPORT id grey_multiFingerSwipeSlowInDirectionWithStartPoint( + GREYDirection direction, + NSUInteger numberOfFingers, + CGFloat xOriginStartPercentage, + CGFloat yOriginStartPercentage); + +/** + * Shorthand macro for + * GREYActions::actionForMultiFingerSwipeFastInDirection:numberOfFingers:xOriginStartPercentage: + * yOriginStartPercentage:. + */ +GREY_EXPORT id grey_multiFingerSwipeFastInDirectionWithStartPoint( + GREYDirection direction, + NSUInteger numberOfFingers, + CGFloat xOriginStartPercentage, + CGFloat yOriginStartPercentage); + +/** Shorthand macro for GREYActions::actionForPinchFastInDirection:pinchDirection:angle:. */ +GREY_EXPORT id grey_pinchFastInDirectionAndAngle(GREYPinchDirection pinchDirection, + double angle); + +/** Shorthand macro for GREYActions::actionForPinchSlowInDirection:pinchDirection:angle:. */ +GREY_EXPORT id grey_pinchSlowInDirectionAndAngle(GREYPinchDirection pinchDirection, + double angle); + +/** Shorthand macro for GREYActions::actionForMoveSliderToValue:. */ +GREY_EXPORT id grey_moveSliderToValue(float value); + +/** Shorthand macro for GREYActions::actionForSetStepperValue:. */ +GREY_EXPORT id grey_setStepperValue(double value); + +/** Shorthand macro for GREYActions::actionForTap. */ +GREY_EXPORT id grey_tap(void); + +/** Shorthand macro for GREYActions::actionForTapAtPoint:. */ +GREY_EXPORT id grey_tapAtPoint(CGPoint point); + +/** Shorthand macro for GREYActions::actionForTypeText:. */ +GREY_EXPORT id grey_typeText(NSString *text); + +/** Shorthand macro for GREYActions::actionForReplaceText:. */ +GREY_EXPORT id grey_replaceText(NSString *text); + +/** Shorthand macro for GREYActions::actionForClearText. */ +GREY_EXPORT id grey_clearText(void); + +/** Shorthand macro for GREYActions::actionForTurnSwitchOn:. */ +GREY_EXPORT id grey_turnSwitchOn(BOOL on); + +/** Shorthand macro for GREYActions::actionForSetDate:. */ +GREY_EXPORT id grey_setDate(NSDate *date); + +/** Shorthand macro for GREYActions::actionForSetPickerColumn:toValue:. */ +GREY_EXPORT id grey_setPickerColumnToValue(NSInteger column, NSString *value); + +/** Shorthand macro for GREYActions::actionForJavaScriptExecution:output:. */ +GREY_EXPORT id grey_javaScriptExecution( + NSString *js, __strong NSString *_Nullable *_Nullable outResult); + +/** Shorthand macro for GREYActions::actionForSnapshot:. */ +GREY_EXPORT id grey_snapshot(__strong UIImage *_Nullable *_Nullable outImage); + +#endif // GREY_DISABLE_SHORTHAND + +NS_ASSUME_NONNULL_END + diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYAllOf.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYAllOf.h new file mode 100644 index 0000000000..60d3095c64 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYAllOf.h @@ -0,0 +1,84 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A matcher for combining multiple matchers with a logical @c AND operator, so that a match + * only occurs when all combined matchers match the element. The invocation of the matchers + * is in the same order in which they are passed. As soon as one matcher fails, the + * rest of the matchers are not invoked. + */ +@interface GREYAllOf : GREYBaseMatcher + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * Designated initializer that adds the different matchers to be combined. + * + * @param matchers Matchers that conform to GREYMatcher and will be combined together with + * a logical AND in the order they are passed in. + * + * @return An instance of GREYAllOf, initialized with the provided @c matchers. + */ +- (instancetype)initWithMatchers:(NSArray<__kindof id> *)matchers + NS_DESIGNATED_INITIALIZER; + +#if !(GREY_DISABLE_SHORTHAND) + +/** + * A shorthand matcher that is a logical AND of all the matchers passed in as variable arguments. + * + * @param first The first matcher in the list of matchers. + * @param second The second matcher in the list of matchers. + * @param thirdOrNil The third matcher in the list of matchers, optionally the nil terminator. + * @param ... Any more matchers to be added. Matchers are invoked in the order they are + * specified and only if the preceding matcher passes. This va-arg must be + * terminated with a @c nil value. + * + * @return An object conforming to GREYMatcher, initialized with the required matchers. + */ +GREY_EXPORT id grey_allOf(id first, + id second, + id _Nullable thirdOrNil, + ...) + NS_SWIFT_UNAVAILABLE("Use grey_allOf(_:) instead") NS_REQUIRES_NIL_TERMINATION; + +/** + * A shorthand matcher that is a logical AND of all the matchers passed in within an NSArray. + * + * @param matchers An NSArray of one or more matchers to be added. Matchers are invoked in the + * order they are specified and only if the preceding matcher passes. + * + * @return An object conforming to GREYMatcher, initialized with the required matchers. + */ +GREY_EXPORT id + grey_allOfMatchers(NSArray<__kindof id> *matchers) + NS_SWIFT_NAME(grey_allOf(_:)); + +#endif // GREY_DISABLE_SHORTHAND + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYAnyOf.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYAnyOf.h new file mode 100644 index 0000000000..70c2829e02 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYAnyOf.h @@ -0,0 +1,84 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Matcher for combining multiple matchers with a logical @c OR operator, so that a match occurs + * when any of the matchers match the element. The invocation of the matchers is in the same + * order in which they are passed. As soon as one of the matchers succeeds, the rest are + * not invoked. + */ +@interface GREYAnyOf : GREYBaseMatcher + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * Designated initializer to add all the matchers to be checked. + * + * @param matchers The matchers, one of which is required to be matched by the matcher. + * They are invoked in the order that they are passed in. + * + * @return An instance of GREYAnyOf, initialized with the provided matchers. + */ +- (instancetype)initWithMatchers:(NSArray<__kindof id> *)matchers + NS_DESIGNATED_INITIALIZER; + +#if !(GREY_DISABLE_SHORTHAND) + +/** + * A matcher that is a logical OR of all the matchers passed in as variable arguments. + * + * @param first The first matcher in the list of matchers. + * @param second The second matcher in the list of matchers. + * @param thirdOrNil The third matcher in the list of matchers, optionally the nil terminator. + * @param ... Any more matchers to be added. Matchers are invoked in the order they are + * specified and only if the preceding matcher fails. + * This va-arg must be terminated with a @c nil value. + * + * @return An object conforming to GREYMatcher, initialized with the required matchers. + */ +GREY_EXPORT id grey_anyOf(id first, + id second, + id _Nullable thirdOrNil, + ...) + NS_SWIFT_UNAVAILABLE("Use grey_anyOf(_:) instead") + NS_REQUIRES_NIL_TERMINATION; + +/** + * A matcher that is a logical OR of all the matchers passed in within an NSArray. + * + * @param matchers An array of one more matchers to be added. Matchers are invoked in the order + * they are specified and only if the preceding matcher fails. + * + * @return An object conforming to GREYMatcher, initialized with the required matchers. + */ +GREY_EXPORT id grey_anyOfMatchers(NSArray<__kindof id> *matchers) + NS_SWIFT_NAME(grey_anyOf(_:)); + +#endif // GREY_DISABLE_SHORTHAND + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYAssertion.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYAssertion.h new file mode 100644 index 0000000000..82a3a01e2a --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYAssertion.h @@ -0,0 +1,51 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Protocol to which EarlGrey assertion classes must conform. + */ +@protocol GREYAssertion + +/** + * Checks whether the assertion is valid for the provided @c element, throwing an exception if the + * if the assertion fails and the @c errorOrNil parameter is @c nil. If a non-nil @c errorOrNil is + * provided, it will be set to error that represents the assertion failure cause. + * If the assertion does not accept @c nil elements, the error domain should be + * @c kGREYInteractionErrorDomain and the error code @c kGREYInteractionElementNotFoundErrorCode. + * GREYAssertionDefines.h defines macros for throwing common exception types. + * + * @param element Element on which the assertion should be checked. + * @param[out] errorOrNil If non-nil, set to the cause of the assertion failure. + * + * @throws NSException If the assertion fails and the provided @c errorOrNil is @c nil. + * The specific type depends on the implementation. + * + * @return @c YES if the assertion holds for the specified element, @c NO otherwise. + */ +- (BOOL)assert:(_Nullable id)element error:(__strong NSError *_Nullable *_Nullable)errorOrNil; + +/** + * @return The name of the assertion. + */ +- (NSString *)name; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYAssertionBlock.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYAssertionBlock.h new file mode 100644 index 0000000000..7591b79816 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYAssertionBlock.h @@ -0,0 +1,70 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A block that accepts an @c element, which will be invoked when an assertion is going to be + * performed on the element. If the assertion fails and a non-nil @c errorOrNil is provided, + * the block should populate it with the cause of failure. + * + * @param element Element that the assertion will be checked against. + * @param[out] errorOrNil If non-nil, set to the cause of the assertion failure. + * + * @return @c YES if the assertion is valid for @c element, @c NO otherwise. + */ +typedef BOOL (^GREYCheckBlockWithError)(_Nullable id element, + __strong NSError *_Nullable *_Nullable errorOrNil); + +/** + * An interface to create GREYAssertions from blocks. + */ +@interface GREYAssertionBlock : NSObject + +/** + * Creates an assertion with the given @c name and @c block that is executed when + * GREYAssertion::assert:error: selector is performed on the assertion. + * + * @param name The assertion name. + * @param block The block that will be invoked to perform the assertion. + * + * @return A new block-based assertion object. + */ ++ (instancetype)assertionWithName:(NSString *)name + assertionBlockWithError:(GREYCheckBlockWithError)block; + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * Initializes an assertion with the given @c name and @c block that is executed when + * GREYAssertion::assert:error: selector is performed on the assertion. + * + * @param name The assertion name. + * @param block The block that will be invoked to perform the assertion. + * + * @return The initialized assertion object. + */ +- (instancetype)initWithName:(NSString *)name + assertionBlockWithError:(GREYCheckBlockWithError)block NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYAssertionDefines.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYAssertionDefines.h new file mode 100644 index 0000000000..c7dce615d9 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYAssertionDefines.h @@ -0,0 +1,423 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file + * @brief Helper macros for performing assertions and throwing assertion failure exceptions. + * On failure, these macros take screenshots and log full view hierarchy. They wait for app to idle + * before performing the assertion. + */ + +#ifndef GREY_ASSERTION_DEFINES_H +#define GREY_ASSERTION_DEFINES_H + +#import +#import +#import +#import +#import + +/** + * Exposes internal method to get the failure handler registered with EarlGrey. + * It must be called from main thread otherwise the behavior is undefined. + */ +GREY_EXPORT id grey_getFailureHandler(void); + +/** + * These Macros are safe to call from anywhere within a testcase. + */ +#pragma mark - Public Macros + +/** + * Generates a failure with the provided @c __description if the expression @c __a1 evaluates to + * @c NO. + * + * @param __a1 The expression that should be evaluated. + * @param __description Description to print if @c __a1 evaluates to @c NO. May be a format + * string, in which case the variable args will be required. + * @param ... Variable args for @c __description if it is a format string. + */ +#define GREYAssert(__a1, __description, ...) \ +({ \ + I_GREYSetCurrentAsFailable(); \ + NSString *timeoutString__ = @"Couldn't assert that (" #__a1 ") is true."; \ + I_GREYWaitForIdle(timeoutString__); \ + I_GREYAssertTrue((__a1), (__description), ##__VA_ARGS__); \ +}) + +/** + * Generates a failure with the provided @c __description if the expression @c __a1 evaluates to + * @c NO. + * + * @param __a1 The expression that should be evaluated. + * @param __description Description to print if @c __a1 evaluates to @c NO. May be a format + * string, in which case the variable args will be required. + * @param ... Variable args for @c __description if it is a format string. + */ +#define GREYAssertTrue(__a1, __description, ...) \ +({ \ + I_GREYSetCurrentAsFailable(); \ + NSString *timeoutString__ = @"Couldn't assert that (" #__a1 ") is true."; \ + I_GREYWaitForIdle(timeoutString__); \ + I_GREYAssertTrue((__a1), (__description), ##__VA_ARGS__); \ +}) + +/** + * Generates a failure with the provided @c __description if the expression @c __a1 evaluates to + * @c YES. + * + * @param __a1 The expression that should be evaluated. + * @param __description Description to print if @c __a1 evaluates to @c NO. May be a format + * string, in which case the variable args will be required. + * @param ... Variable args for @c __description if it is a format string. + */ +#define GREYAssertFalse(__a1, __description, ...) \ +({ \ + I_GREYSetCurrentAsFailable(); \ + NSString *timeoutString__ = @"Couldn't assert that (" #__a1 ") is false."; \ + I_GREYWaitForIdle(timeoutString__); \ + I_GREYAssertFalse((__a1), (__description), ##__VA_ARGS__); \ +}) + +/** + * Generates a failure with the provided @c __description if the expression @c __a1 is @c nil. + * + * @param __a1 The expression that should be evaluated. + * @param __description Description to print if @c __a1 is @c nil. May be a format + * string, in which case the variable args will be required. + * @param ... Variable args for @c __description if it is a format string. + */ +#define GREYAssertNotNil(__a1, __description, ...) \ +({ \ + I_GREYSetCurrentAsFailable(); \ + NSString *timeoutString__ = @"Couldn't assert that (" #__a1 ") is not nil."; \ + I_GREYWaitForIdle(timeoutString__); \ + I_GREYAssertNotNil((__a1), (__description), ##__VA_ARGS__); \ +}) + +/** + * Generates a failure with the provided @c __description if the expression @c __a1 is not @c nil. + * + * @param __a1 The expression that should be evaluated. + * @param __description Description to print if @c __a1 is not @c nil. May be a format + * string, in which case the variable args will be required. + * @param ... Variable args for @c __description if it is a format string. + */ +#define GREYAssertNil(__a1, __description, ...) \ +({ \ + I_GREYSetCurrentAsFailable(); \ + NSString *timeoutString__ = @"Couldn't assert that (" #__a1 ") is nil."; \ + I_GREYWaitForIdle(timeoutString__); \ + I_GREYAssertNil((__a1), (__description), ##__VA_ARGS__); \ +}) + +/** + * Generates a failure with the provided @c __description if the expression @c __a1 and + * the expression @c __a2 are not equal. + * @c __a1 and @c __a2 must be scalar types. + * + * @param __a1 The left hand scalar value on the equality operation. + * @param __a2 The right hand scalar value on the equality operation. + * @param __description Description to print if @c __a1 and @c __a2 are not equal. May be a format + * string, in which case the variable args will be required. + * @param ... Variable args for @c __description if it is a format string. + */ +#define GREYAssertEqual(__a1, __a2, __description, ...) \ +({ \ + I_GREYSetCurrentAsFailable(); \ + NSString *timeoutString__ = @"Couldn't assert that (" #__a1 ") and (" #__a2 ") are equal."; \ + I_GREYWaitForIdle(timeoutString__); \ + I_GREYAssertEqual((__a1), (__a2), (__description), ##__VA_ARGS__); \ +}) + +/** + * Generates a failure with the provided @c __description if the expression @c __a1 and + * the expression @c __a2 are equal. + * @c __a1 and @c __a2 must be scalar types. + * + * @param __a1 The left hand scalar value on the equality operation. + * @param __a2 The right hand scalar value on the equality operation. + * @param __description Description to print if @c __a1 and @c __a2 are equal. May be a format + * string, in which case the variable args will be required. + * @param ... Variable args for @c __description if it is a format string. + */ +#define GREYAssertNotEqual(__a1, __a2, __description, ...) \ +({ \ + I_GREYSetCurrentAsFailable(); \ + NSString *timeoutString__ = \ + @"Couldn't assert that (" #__a1 ") and (" #__a2 ") are not equal."; \ + I_GREYWaitForIdle(timeoutString__); \ + I_GREYAssertNotEqual((__a1), (__a2), (__description), ##__VA_ARGS__); \ +}) + +/** + * Generates a failure with the provided @c __description if the expression @c __a1 and + * the expression @c __a2 are not equal. + * @c __a1 and @c __a2 must be descendants of NSObject and will be compared with method isEqual. + * + * @param __a1 The left hand object on the equality operation. + * @param __a2 The right hand object on the equality operation. + * @param __description Description to print if @c __a1 and @c __a2 are not equal. May be a format + * string, in which case the variable args will be required. + * @param ... Variable args for @c __description if it is a format string. + */ +#define GREYAssertEqualObjects(__a1, __a2, __description, ...) \ +({ \ + I_GREYSetCurrentAsFailable(); \ + NSString *timeoutString__ = \ + @"Couldn't assert that (" #__a1 ") and (" #__a2 ") are equal objects."; \ + I_GREYWaitForIdle(timeoutString__); \ + I_GREYAssertEqualObjects((__a1), (__a2), __description, ##__VA_ARGS__); \ +}) + +/** + * Generates a failure with the provided @c __description if the expression @c __a1 and + * the expression @c __a2 are equal. + * @c __a1 and @c __a2 must be descendants of NSObject and will be compared with method isEqual. + * + * @param __a1 The left hand object on the equality operation. + * @param __a2 The right hand object on the equality operation. + * @param __description Description to print if @c __a1 and @c __a2 are equal. May be a format + * string, in which case the variable args will be required. + * @param ... Variable args for @c __description if it is a format string. + */ +#define GREYAssertNotEqualObjects(__a1, __a2, __description, ...) \ +({ \ + I_GREYSetCurrentAsFailable(); \ + NSString *timeoutString__ = \ + @"Couldn't assert that (" #__a1 ") and (" #__a2 ") are not equal objects."; \ + I_GREYWaitForIdle(timeoutString__); \ + I_GREYAssertNotEqualObjects((__a1), (__a2), (__description), ##__VA_ARGS__); \ +}) + +/** + * Generates a failure unconditionally, with the provided @c __description. + * + * @param __description Description to print. May be a format string, in which case the variable + * args will be required. + * @param ... Variable args for @c __description if it is a format string. + */ +#define GREYFail(__description, ...) \ +({ \ + I_GREYSetCurrentAsFailable(); \ + I_GREYFail((__description), ##__VA_ARGS__); \ +}) + +/** + * Generates a failure unconditionally, with the provided @c __description and @c __details. + * + * @param __description Description to print. + * @param __details The failure details. May be a format string, in which case the variable + * args will be required. + * @param ... Variable args for @c __description if it is a format string. + */ +#define GREYFailWithDetails(__description, __details, ...) \ +({ \ + I_GREYSetCurrentAsFailable(); \ + I_GREYFailWithDetails((__description), (__details), ##__VA_ARGS__); \ +}) + +/** + * Generates a failure unconditionally for when the constraints for performing an action fail, + * with the provided @c __description and @c __details. + * + * @param __description Description to print. + * @param __details The failure details. May be a format string, in which case the variable + * args will be required. + * @param ... Variable args for @c __description if it is a format string. + */ +#define GREYConstraintsFailedWithDetails(__description, __details, ...) \ +({ \ + I_GREYSetCurrentAsFailable(); \ + I_GREYConstraintsFailedWithDetails((__description), (__details), ##__VA_ARGS__); \ +}) + +#pragma mark - Private Macros + +/** + * THESE ARE METHODS TO BE CALLED BY THE FRAMEWORK ONLY. + * DO NOT CALL OUTSIDE FRAMEWORK + */ + +/// @cond INTERNAL + +// No private macro should call this. +#define I_GREYSetCurrentAsFailable() \ +({ \ + id failureHandler__ = grey_getFailureHandler(); \ + if ([failureHandler__ respondsToSelector:@selector(setInvocationFile:andInvocationLine:)]) { \ + [failureHandler__ setInvocationFile:[NSString stringWithUTF8String:__FILE__] \ + andInvocationLine:__LINE__]; \ + } \ +}) + +// No private macro should call this. +#define I_GREYWaitForIdle(__timeoutDescription) \ +({ \ + CFTimeInterval interactionTimeout__ = \ + GREY_CONFIG_DOUBLE(kGREYConfigKeyInteractionTimeoutDuration); \ + NSError *error__; \ + BOOL success__ = \ + [[GREYUIThreadExecutor sharedInstance] executeSyncWithTimeout:interactionTimeout__ \ + block:nil \ + error:&error__]; \ + if (!success__) { \ + I_GREYTimeout(__timeoutDescription, @"Timed out waiting for app to idle. %@", error__); \ + } \ +}) + +#define I_GREYFormattedString(__var, __format, ...) \ +({ \ + /* clang warns us about a leak in formatting but we don't care as we are about to fail. */ \ + _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Wformat-nonliteral\"") \ + _Pragma("clang diagnostic ignored \"-Wformat-security\"") \ + (__var) = [NSString stringWithFormat:(__format), ##__VA_ARGS__]; \ + _Pragma("clang diagnostic pop") \ +}) + +#define I_GREYRegisterFailure(__exceptionName, __description, __details, ...) \ +({ \ + NSString *details__; \ + I_GREYFormattedString(details__, __details, ##__VA_ARGS__); \ + id failureHandler__ = grey_getFailureHandler(); \ + [failureHandler__ handleException:[GREYFrameworkException exceptionWithName:__exceptionName \ + reason:(__description)] \ + details:(details__)]; \ +}) + +#define I_GREYAssertTrue(__a1, __description, ...) \ +({ \ + if (!(__a1)) { \ + NSString *formattedDescription__; \ + I_GREYFormattedString(formattedDescription__, (__description), ##__VA_ARGS__); \ + I_GREYRegisterFailure(kGREYAssertionFailedException, \ + @"(" #__a1 " is true) failed", \ + formattedDescription__); \ + } \ +}) + +#define I_GREYAssertFalse(__a1, __description, ...) \ +({ \ + if ((__a1)) { \ + NSString *formattedDescription__; \ + I_GREYFormattedString(formattedDescription__, (__description), ##__VA_ARGS__); \ + I_GREYRegisterFailure(kGREYAssertionFailedException, \ + @"(" #__a1 " is false) failed", \ + formattedDescription__); \ + } \ +}) + +#define I_GREYAssertNotNil(__a1, __description, ...) \ +({ \ + if ((__a1) == nil) { \ + NSString *formattedDescription__; \ + I_GREYFormattedString(formattedDescription__, (__description), ##__VA_ARGS__); \ + I_GREYRegisterFailure(kGREYNotNilException, \ + @"(" #__a1 " != nil) failed", \ + formattedDescription__); \ + } \ +}) + +#define I_GREYAssertNil(__a1, __description, ...) \ +({ \ + if ((__a1) != nil) { \ + NSString *formattedDescription__; \ + I_GREYFormattedString(formattedDescription__, (__description), ##__VA_ARGS__); \ + I_GREYRegisterFailure(kGREYNilException, \ + @"(" #__a1 " == nil) failed", \ + formattedDescription__); \ + } \ +}) + +#define I_GREYAssertEqual(__a1, __a2, __description, ...) \ +({ \ + if ((__a1) != (__a2)) { \ + NSString *formattedDescription__; \ + I_GREYFormattedString(formattedDescription__, (__description), ##__VA_ARGS__); \ + I_GREYRegisterFailure(kGREYAssertionFailedException, \ + @"(" #__a1 " == (" #__a2 ")) failed", \ + formattedDescription__); \ + } \ +}) + +#define I_GREYAssertNotEqual(__a1, __a2, __description, ...) \ +({ \ + if ((__a1) == (__a2)) { \ + NSString *formattedDescription__; \ + I_GREYFormattedString(formattedDescription__, (__description), ##__VA_ARGS__); \ + I_GREYRegisterFailure(kGREYAssertionFailedException, \ + @"(" #__a1 " != (" #__a2 ")) failed", \ + formattedDescription__); \ + } \ +}) + +#define I_GREYAssertEqualObjects(__a1, __a2, __description, ...) \ +({ \ + if (![(__a1) isEqual:(__a2)]) { \ + NSString *formattedDescription__; \ + I_GREYFormattedString(formattedDescription__, (__description), ##__VA_ARGS__); \ + I_GREYRegisterFailure(kGREYAssertionFailedException, \ + @"[" #__a1 " isEqual:(" #__a2 ")] failed", \ + formattedDescription__); \ + } \ +}) + +#define I_GREYAssertNotEqualObjects(__a1, __a2, __description, ...) \ +({ \ + if ([(__a1) isEqual:(__a2)]) { \ + NSString *formattedDescription__; \ + I_GREYFormattedString(formattedDescription__, (__description), ##__VA_ARGS__); \ + I_GREYRegisterFailure(kGREYAssertionFailedException, \ + @"![" #__a1 " isEqual:(" #__a2 ")] failed", \ + formattedDescription__); \ + } \ +}) + +#define I_GREYFail(__description, ...) \ +({ \ + NSString *formattedDescription__; \ + I_GREYFormattedString(formattedDescription__, __description, ##__VA_ARGS__); \ + I_GREYRegisterFailure(kGREYGenericFailureException, formattedDescription__, @""); \ +}) + +#define I_GREYFailWithDetails(__description, __details, ...) \ + I_GREYRegisterFailure(kGREYGenericFailureException, __description, __details, ##__VA_ARGS__) + +#define I_GREYConstraintsFailedWithDetails(__description, __details, ...) \ + I_GREYRegisterFailure(kGREYConstraintFailedException, __description, __details, ##__VA_ARGS__) + +#define I_GREYTimeout(__description, __details, ...) \ + I_GREYRegisterFailure(kGREYTimeoutException, __description, __details, ##__VA_ARGS__) + +#define I_GREYActionFail(__description, __details, ...) \ + I_GREYRegisterFailure(kGREYActionFailedException, __description, __details, ##__VA_ARGS__) + +#define I_GREYAssertionFail(__description, __details, ...) \ + I_GREYRegisterFailure(kGREYAssertionFailedException, __description, __details, ##__VA_ARGS__) + +#define I_GREYElementNotFound(__description, __details, ...) \ + I_GREYRegisterFailure(kGREYNoMatchingElementException, __description, __details, ##__VA_ARGS__) + +#define I_GREYMultipleElementsFound(__description, __details, ...) \ + I_GREYRegisterFailure(kGREYMultipleElementsFoundException, \ + __description, \ + __details, \ + ##__VA_ARGS__) + +/// @endcond + +#endif // GREY_ASSERTION_DEFINES_H diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYAssertions.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYAssertions.h new file mode 100644 index 0000000000..aa06b5b6a2 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYAssertions.h @@ -0,0 +1,23 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +/** + * An interface that exposes UI element assertions. + */ +@interface GREYAssertions : NSObject +@end diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYBaseAction.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYBaseAction.h new file mode 100644 index 0000000000..026cbeb2ca --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYBaseAction.h @@ -0,0 +1,66 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +@protocol GREYMatcher; + +NS_ASSUME_NONNULL_BEGIN + +/** + * A base class for all actions that incorporates commonalities between initialization + * parameters and constraint checking. + */ +@interface GREYBaseAction : NSObject + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * The designated initializer for a base action with the provided @c constraints. + * + * @param name The name of the GREYAction being performed. + * + * @param constraints The constraints to be satisified by the element before the + * action is performed. + * + * @return An instance of GREYBaseAction, initialized with the @c constraints for it to check for. + */ +- (instancetype)initWithName:(NSString *)name + constraints:(id)constraints NS_DESIGNATED_INITIALIZER; + +/** + * A method that checks that @c element satisfies @c constraints this action was initialized with. + * Subclasses should call this method if they want to check for constraints in their perform:error: + * implementation. + * + * @param element A UI element being checked for the @c constraints. + * @param[out] errorOrNilPtr Error stored when an element did not satisfy the @c constraints. + * If an error is set but this pointer is @c nil, + * then an action failed exception is thrown. + * + * @throws GREYFrameworkException if constraints fail and @c errorOrNilPtr is not provided. + * + * @return @c YES if the constraints are satisfied on the element. @c NO otherwise. + */ +- (BOOL)satisfiesConstraintsForElement:(id)element error:(__strong NSError **)errorOrNilPtr; + +@end + +NS_ASSUME_NONNULL_END + diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYBaseMatcher.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYBaseMatcher.h new file mode 100644 index 0000000000..abe1bf08cb --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYBaseMatcher.h @@ -0,0 +1,49 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A base class that implements the GREYMatcher protocol methods. + * Prefer subclassing this class over creating your own matchers. + * Every subclass must override and provide its own implementation for GREYBaseMatcher::matches: + * and GREYBaseMatcher::describeTo: methods. + */ +@interface GREYBaseMatcher : NSObject + +#pragma mark - GREYMatcher + +/** + * @see GREYMatcher::matches: + * + * @remark Subclasses are required to implement this method. + */ +- (BOOL)matches:(_Nullable id)item; + +/** + * @see GREYMatcher::describeTo: + * + * @remark Subclasses are required to implement this method. + */ +- (void)describeTo:(id)description; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYCondition.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYCondition.h new file mode 100644 index 0000000000..bc547c7fd6 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYCondition.h @@ -0,0 +1,93 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A class for creating boolean conditions that can be waited on until the condition is satisfied + * or a timeout elapses. + * + * Conditions are specified in the form of a block that returns a @c BOOL value indicating whether + * the condition is met. + */ +@interface GREYCondition : NSObject + +/** + * Creates a condition with a block that should return @c YES when the condition is met. + * + * @param name A descriptive name for the condition + * @param conditionBlock The block that will be used to evaluate the condition. + * + * @return A new initialized GREYCondition instance. + */ ++ (instancetype)conditionWithName:(NSString *)name block:(BOOL(^)(void))conditionBlock; + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * Initializes a condition with a block that should return @c YES when the condition is met. + * + * @param name A descriptive name for the condition + * @param conditionBlock The block that will be used to evaluate the condition. + * + * @return The initialized instance. + */ +- (instancetype)initWithName:(NSString *)name + block:(BOOL(^)(void))conditionBlock NS_DESIGNATED_INITIALIZER; + +/** + * Waits for the condition to be met until the specified @c seconds have elapsed. + * + * Will poll the condition as often as possible on the main thread while still giving a fair chance + * for other sources and handlers to be serviced. + * + * @remark Waiting on conditions with this method is very CPU intensive on the main thread. If + * you do not need to return immediately after the condition is met, the consider using + * GREYCondition::waitWithTimeout:pollInterval: + * + * @param seconds Amount of time to wait for the condition to be met, in seconds. + * + * @return @c YES if the condition was met before the timeout, @c NO otherwise. + */ +- (BOOL)waitWithTimeout:(CFTimeInterval)seconds; + +/** + * Waits for the condition to be met until the specified @c seconds have elapsed. Will poll the + * condition immediately and then no more than once every @c interval seconds. Will attempt to poll + * the condition as close as possible to every @c interval seconds. + * + * @remark Will allow the main thread to sleep instead of busily checking the condition. + * + * @param seconds Amount of time to wait for the condition to be met, in seconds. + * @param interval The minimum time that should elapse between checking the condition. + * + * @return @c YES if the condition was met before the timeout, @c NO otherwise. + */ +- (BOOL)waitWithTimeout:(CFTimeInterval)seconds pollInterval:(CFTimeInterval)interval; + +/** + * @return Name of the condition. + */ +- (NSString *)name; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYConfiguration.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYConfiguration.h new file mode 100644 index 0000000000..daef80ce5a --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYConfiguration.h @@ -0,0 +1,311 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file GREYConfiguration.h + * @brief A key-value store for configuring global behavior. Configuration values are read just + * before performing a related function. On-going functions may not be affected by the + * changes in the configuration until the values are re-read. + */ + +#import + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Configuration that enables or disables usage tracking for the framework. + * + * Accepted values: @c BOOL (i.e. @c YES or @c NO) + * Default value: @c YES + */ +GREY_EXTERN NSString *const kGREYConfigKeyAnalyticsEnabled; + +/** + * Configuration that enables or disables constraint checks before performing an action. + * + * Accepted values: @c BOOL (i.e. @c YES or @c NO) + * Default value: @c YES + */ +GREY_EXTERN NSString *const kGREYConfigKeyActionConstraintsEnabled; + +/** + * Configuration that holds timeout duration (in seconds) for actions and assertions. Actions or + * assertions that are not scheduled within this time will fail with a timeout. If the action or + * assertion starts within the timeout duration and if a search action is provided, then the search + * action will execute at least once regardless of the timeout duration. + * + * Accepted values: @c double (negative values are invalid) + * Default value: 30.0 + */ +GREY_EXTERN NSString *const kGREYConfigKeyInteractionTimeoutDuration; + +/** + * Configuration that enables or disables EarlGrey's synchronization feature. + * When disabled, any command that used to wait for the app to idle before proceeding will no + * longer do so. + * + * @remark For more fine-grained control over synchronization parameters, you can tweak other + * provided configuration options below. + * + * Accepted values: @c BOOL (i.e. @c YES or @c NO) + * Default value: @c YES + */ +GREY_EXTERN NSString *const kGREYConfigKeySynchronizationEnabled; + +/** + * Configuration for setting the max interval (in seconds) of non-repeating NSTimers that EarlGrey + * will automatically track. + * + * Accepted values: @c double (negative values are invalid) + * Default value: 1.5 + */ +GREY_EXTERN NSString *const kGREYConfigKeyNSTimerMaxTrackableInterval; + +/** + * Configuration for setting the max delay (in seconds) for dispatch_after and dispatch_after_f + * calls that EarlGrey will automatically track. dispatch_after and dispatch_after_f calls + * exceeding the specified time won't be tracked by the framework. + * + * Accepted values: @c double (negative values are invalid) + * Default value: 1.5 + */ +GREY_EXTERN NSString *const kGREYConfigKeyDispatchAfterMaxTrackableDelay; + +/** + * Configuration for setting the max duration (in seconds) for delayed executions on the + * main thread originating from any performSelector:afterDelay invocations that EarlGrey will + * automatically track. + * + * Accepted values: @c double (negative values are invalid) + * Default value: 1.5 + */ +GREY_EXTERN NSString *const kGREYConfigKeyDelayedPerformMaxTrackableDuration; + +/** + * Configuration that determines whether or not CALayer animations are modified. If @c YES, then + * cyclic animations are set to run only once and the animation duration is limited to a maximum + * of @c kGREYConfigKeyCALayerMaxAnimationDuration. + * + * @remark This should only be used if synchronization is disabled; otherwise cyclic animations + * will cause EarlGrey to timeout and fail tests. + * + * Accepted values: @c BOOL (i.e. @c YES or @c NO) + * Default value: @c YES + */ +GREY_EXTERN NSString *const kGREYConfigKeyCALayerModifyAnimations; + +/** + * Configuration for setting max allowable animation duration (in seconds) for any CALayer based + * animation. Animations exceeding the specified time will have their duration truncated to value + * specified by this config. + * + * Accepted values: @c double (negative values are invalid) + * Default value: 10.0 + */ +GREY_EXTERN NSString *const kGREYConfigKeyCALayerMaxAnimationDuration; + +/** + * Configuration that holds regular expressions for URLs that are blacklisted from synchronization. + * EarlGrey will not wait for any network request with URLs matching the blacklisted regular + * expressions to complete. Most frequently blacklisted URLs include those used for sending + * analytics, pingbacks, and background network tasks that don't interfere with testing. + * + * @remark By default, EarlGrey will not synchronize with any URLs with "data" scheme. + * + * Accepted values: @c An @c NSArray of valid regular expressions as @c NSString. + * The strings must be accepted by @c NSRegularExpression. + * Default value: an empty @c NSArray + */ +GREY_EXTERN NSString *const kGREYConfigKeyURLBlacklistRegex; + +/** + * Configuration that enables/disables inclusion of status bar window in every operation performed + * by EarlGrey. By default, the status bar window is excluded from screenshots and UI hierarchy. + * + * Accepted values: @c BOOL (i.e. @c YES or @c NO) + * Default value: NO + */ +GREY_EXTERN NSString *const kGREYConfigKeyIncludeStatusBarWindow; + +/** + * Configuration for setting a directory location where any test artifacts such as screenshots, + * test logs, etc. are stored. The user should ensure that the location provided is writable by + * the test. + * + * Accepted values: NSString containing a valid absolute filepath that is writable by the test. + * Default value: @c nil + */ +GREY_EXTERN NSString *const kGREYConfigKeyArtifactsDirLocation; + +/** + * Provides an interface for runtime configuration of EarlGrey's behavior. + */ +@interface GREYConfiguration : NSObject + +/** + * @return The singleton GREYConfiguration instance. + */ ++ (instancetype)sharedInstance; + +/** + * If a user-configured value is associated with the given @c configKey, it is returned, + * otherwise the default value is returned. If a default value is not found, or an + * NSInvalidArgumentException is raised. + * + * @param configKey The key whose value is being queried. Must be a valid @c NSString. + * + * @throws NSInvalidArgumentException If no value could be found associated with @c configKey. + * + * @return The value for the configuration stored associate with @c configKey. + */ +- (id)valueForConfigKey:(NSString *)configKey; + +/** + * If a user-configured value is associated with the given @c configKey, it is returned, otherwise + * the default value is returned. If a default value is not found, NSInvalidArgumentException is + * raised. + * + * @param configKey The key whose value is being queried. Must be a valid @c NSString. + * + * @throws NSInvalidArgumentException If no value could be found for the given @c configKey. + * + * @return The @c BOOL value for the configuration associated with @c configKey. + */ +- (BOOL)boolValueForConfigKey:(NSString *)configKey; + +/** + * If a user-configured value is associated with the given @c configKey, it is returned, otherwise + * the default value is returned. If a default value is not found, NSInvalidArgumentException is + * raised. + * + * @param configKey The key whose value is being queried. Must be a valid @c NSString. + * + * @throws NSInvalidArgumentException If no value could be found for the given @c configKey. + * + * @return The integer value for the configuration associated with @c configKey. + */ +- (NSInteger)integerValueForConfigKey:(NSString *)configKey; + +/** + * If a user-configured value is associated with the given @c configKey, it is returned, otherwise + * the default value is returned. If a default value is not found, NSInvalidArgumentException is + * raised. + * + * @param configKey The key whose value is being queried. Must be a valid @c NSString. + * + * @throws NSInvalidArgumentException If no value could be found for the given @c configKey. + * + * @return The @c double value for the configuration associated with @c configKey. + */ +- (double)doubleValueForConfigKey:(NSString *)configKey; + +/** + * If a user-configured value is associated with the given @c configKey, it is returned, otherwise + * the default value is returned. If a default value is not found, NSInvalidArgumentException is + * raised. + * + * @param configKey The key whose value is being queried. Must be a valid @c NSString. + * + * @throws NSInvalidArgumentException If no value could be found for the given @c configKey. + * + * @return The string value for the configuration associated with @c configKey. + */ +- (NSString *)stringValueForConfigKey:(NSString *)configKey; + +/** + * If a user-configured value is associated with the given @c configKey, it is returned, otherwise + * the default value is returned. If a default value is not found, NSInvalidArgumentException is + * raised. + * + * @param configKey The key whose value is being queried. Must be a valid @c NSString. + * + * @throws NSInvalidArgumentException If no value could be found for the given @c configKey. + * + * @return The array value for the configuration associated with @c configKey. + */ +- (NSArray *)arrayValueForConfigKey:(NSString *)configKey; + +/** + * Resets all configurations to default values, removing all the configured values. + * + * @remark Any default values added by calling GREYConfiguration:setDefaultValue:forConfigKey: + * are not reset. + */ +- (void)reset; + +/** + * Given a value and a key that identifies a configuration, set the value of the configuration. + * Overwrites any previous value for the configuration. + * + * @remark To restore original values, call GREYConfiguration::reset. + * + * @param value The configuration value to be set. Scalars should be wrapped in @c NSValue. + * @param configKey Key identifying an existing or new configuration. Must be a valid @c NSString. + */ +- (void)setValue:(id)value forConfigKey:(NSString *)configKey; + +/** + * Associates configuration identified by @c configKey with the provided @c value. + * + * @remark Default values persist even after resetting the configuration + * (using GREYConfiguration::reset) + * + * @param value The configuration value to be set. Scalars should be wrapped in @c NSValue. + * @param configKey Key identifying an existing or new configuration. Must be a valid @c NSString. + */ +- (void)setDefaultValue:(id)value forConfigKey:(NSString *)configKey; + +@end + +/** + * @return the value of type @c id associated with the given @c __configName. + */ +#define GREY_CONFIG(__configName) \ + [[GREYConfiguration sharedInstance] valueForConfigKey:(__configName)] + +/** + * @return @c BOOL value associated with the given @c __configName. + */ +#define GREY_CONFIG_BOOL(__configName) \ + [[GREYConfiguration sharedInstance] boolValueForConfigKey:(__configName)] + +/** + * @return @c NSInteger value associated with the given @c __configName. + */ +#define GREY_CONFIG_INTEGER(__configName) \ + [[GREYConfiguration sharedInstance] integerValueForConfigKey:(__configName)] + +/** + * @return @c double value associated with the given @c __configName. + */ +#define GREY_CONFIG_DOUBLE(__configName) \ + [[GREYConfiguration sharedInstance] doubleValueForConfigKey:(__configName)] + +/** + * @return @c NSString value associated with the given @c __configName. + */ +#define GREY_CONFIG_STRING(__configName) \ + [[GREYConfiguration sharedInstance] stringValueForConfigKey:(__configName)] + +/** + * @return @c NSArray value associated with the given @c __configName. + */ +#define GREY_CONFIG_ARRAY(__configName) \ + [[GREYConfiguration sharedInstance] arrayValueForConfigKey:(__configName)] + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYConstants.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYConstants.h new file mode 100644 index 0000000000..b3b4d44378 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYConstants.h @@ -0,0 +1,296 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Any alpha less than this value is considered hidden by Apple. + * @see + * https://developer.apple.com/library/ios/documentation/uikit/reference/uiview_class/uiview/uiview.html#//apple_ref/occ/instm/UIView/hitTest:withEvent: + */ +GREY_EXTERN const CGFloat kGREYMinimumVisibleAlpha; + +/** + * Amount of time a "fast" swipe should last for, in seconds. + */ +GREY_EXTERN const CFTimeInterval kGREYSwipeFastDuration; + +/** + * Amount of time a "slow" swipe should last for, in seconds. + */ +GREY_EXTERN const CFTimeInterval kGREYSwipeSlowDuration; + +/** + * Amount of time a "fast" pinch should last for, in seconds + */ +GREY_EXTERN const CFTimeInterval kGREYPinchFastDuration; + +/** + * Amount of time a "slow" pinch should last for, in seconds + */ +GREY_EXTERN const CFTimeInterval kGREYPinchSlowDuration; + +/** + * Infinite timeout. + */ +GREY_EXTERN const CFTimeInterval kGREYInfiniteTimeout; + +/** + * Limit on the number of UIPickerViews that can be pulled for getting the hierarchy. + */ +GREY_EXTERN const NSInteger kUIPickerViewMaxAccessibilityViews; + +/** + * Amount of time a normal long press should last for, in seconds. Extracted from: + * @see + * https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UILongPressGestureRecognizer_Class/index.html#//apple_ref/occ/instp/UILongPressGestureRecognizer/minimumPressDuration + */ +GREY_EXTERN const CFTimeInterval kGREYLongPressDefaultDuration; + +/** + * Minimum acceptable difference between two floating-point values when comparing them. + */ +GREY_EXTERN const CGFloat kGREYAcceptableFloatDifference; + +/** + * NSUserDefaults key for checking if verbose logging is turned on. (i.e. logs with + * GREYLogVerbose are printed.) + */ +GREY_EXTERN NSString *const kGREYAllowVerboseLogging; + +/** + * The default pinch angle for the pinch action, specified by an approximate angle for a right + * handed two finger pinch. + */ +GREY_EXTERN const double kGREYPinchAngleDefault; + +/** + * Directions for scrolling and swiping. + * + * The direction describes the motion of the view port as a result of the swipe, which is opposite + * to the direction the user's finger moves. For example, a scroll down the page should be + * expressed with @c kGREYDirectionDown as it simulates a touch that starts somewhere in the middle + * of the screen and moves up to simulate an absolute scroll down behavior. + */ +typedef NS_ENUM(NSInteger, GREYDirection) { + /** + * The finger is moving to the right, view port is moving left. + */ + kGREYDirectionLeft = 1, + /** + * The finger is moving to the left, view port is moving right. + */ + kGREYDirectionRight, + /** + * The finger is moving downwards, view port is moving up. + */ + kGREYDirectionUp, + /** + * The finger is moving upwards, view port is moving down. + */ + kGREYDirectionDown, +}; + +/** + * Directions for pinch gesture. + * + * The direction describes the motion of the view port as a result of pinch. There are two + * possible directions for pinch action inward and outward. + */ +typedef NS_ENUM(NSInteger, GREYPinchDirection) { + /** + * Two fingers pinching outward. + */ + kGREYPinchDirectionOutward = 1, + /** + * Two fingers pinching inward. + */ + kGREYPinchDirectionInward, +}; + +/** + * Content edges for scrolling. + */ +typedef NS_ENUM(NSInteger, GREYContentEdge) { + /** + * The left content edge of the screen in the current orientation. + */ + kGREYContentEdgeLeft, + /** + * The right content edge of the screen in the current orientation. + */ + kGREYContentEdgeRight, + /** + * The top content edge of the screen in the current orientation. + */ + kGREYContentEdgeTop, + /** + * The bottom content edge of the screen in the current orientation. + */ + kGREYContentEdgeBottom, +}; + +/** + * Directions for layout specification. + */ +typedef NS_ENUM(NSInteger, GREYLayoutDirection) { + /** + * To the left of the current element. + */ + kGREYLayoutDirectionLeft = 1, + /** + * To the right of the current element. + */ + kGREYLayoutDirectionRight, + /** + * Above the current element. + */ + kGREYLayoutDirectionUp, + /** + * Below the current element. + */ + kGREYLayoutDirectionDown, +}; + +/** + * Layout attributes for matching on layouts (modelled after @c NSLayoutAttribute). + */ +typedef NS_ENUM(NSInteger, GREYLayoutAttribute) { + /** + * The left edge of element. + */ + kGREYLayoutAttributeLeft = 1, + /** + * The right edge of element. + */ + kGREYLayoutAttributeRight, + /** + * The top edge of element. + */ + kGREYLayoutAttributeTop, + /** + * The bottom edge of element. + */ + kGREYLayoutAttributeBottom, +}; + +/** + * Layout relations for comparison of layout attributes (modelled after @c NSLayoutRelation). + */ +typedef NS_ENUM(NSInteger, GREYLayoutRelation) { + /** + * Value is less than or equal to the other operand. + */ + kGREYLayoutRelationLessThanOrEqual = -1, + /** + * Value is equal to the other operand. + */ + kGREYLayoutRelationEqual = 0, + /** + * Value is greater than or equal to the other operand. + */ + kGREYLayoutRelationGreaterThanOrEqual = 1, +}; + +/** + * Types of tap actions + */ +typedef NS_ENUM(NSInteger, GREYTapType) { + /** + * Tap action for basic tap. + */ + kGREYTapTypeShort, + /** + * Tap action for long press tap. + */ + kGREYTapTypeLong, + /** + * Tap action for multiple taps (for example double tap). + */ + kGREYTapTypeMultiple, + /** + * Tap action for keyboard keys. + */ + kGREYTapTypeKBKey, +}; + +/** + * @return A string representation of the given @c deviceOrientation. + */ +NSString *NSStringFromUIDeviceOrientation(UIDeviceOrientation deviceOrientation); + +/** + * @return A string representation of the given @c direction. + */ +NSString *NSStringFromGREYDirection(GREYDirection direction); + +/** + * Returns a string representation of the given @c pinchDirection. + */ +NSString *NSStringFromPinchDirection(GREYPinchDirection pinchDirection); + +/** + * @return A string representation of the given @c edge. + */ +NSString *NSStringFromGREYContentEdge(GREYContentEdge edge); + +/** + * @return A string representation of the given layout @c attribute. + */ +NSString *NSStringFromGREYLayoutAttribute(GREYLayoutAttribute attribute); + +/** + * @return A string representation of the given layout @c relation. + */ +NSString *NSStringFromGREYLayoutRelation(GREYLayoutRelation relation); + +/** + * @return A string representation of the given accessibility trait. + */ +NSString *NSStringFromUIAccessibilityTraits(UIAccessibilityTraits traits); + +/** + * A class containing helper methods for conversion to-and-from constants. + */ +@interface GREYConstants : NSObject + +/** + * @return The direction from center to the given @c edge. + */ ++ (GREYDirection)directionFromCenterForEdge:(GREYContentEdge)edge; + +/** + * @return The edge that is in the given @c direction from the center. + */ ++ (GREYContentEdge)edgeInDirectionFromCenter:(GREYDirection)direction; + +/** + * @return The reverse direction of the given @c direction. + */ ++ (GREYDirection)reverseOfDirection:(GREYDirection)direction; + +/** + * @return A normalized vector in the given @c direction. + */ ++ (CGVector)normalizedVectorFromDirection:(GREYDirection)direction; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYDataEnumerator.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYDataEnumerator.h new file mode 100644 index 0000000000..83a2bb7d6e --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYDataEnumerator.h @@ -0,0 +1,56 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * An block-based enumerator that repeatedly invokes the block to return the next object. + */ +@interface GREYDataEnumerator : NSEnumerator + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * Instantiates the enumerator with custom information and a block to return the next object. + * + * @param userInfo Custom object that is passed into the block. Use this for passing any + * additional information required by the block. + * @param nextObjectBlock A block that is invoked to return the next object in the enumerator. + * + * @return An instance of GREYDataEnumerator, initialized with the specified information. + */ +- (instancetype)initWithUserInfo:(id)userInfo + block:(id(^)(id))nextObjectBlock NS_DESIGNATED_INITIALIZER; + +#pragma mark - NSEnumerator + +/** + * @return The next object in the enumerator returned by the @c nextObjectBlock. + */ +- (id _Nullable)nextObject; +/** + * @return An array of all the objects in the enumerator. + */ +- (NSArray *)allObjects; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYDefines.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYDefines.h new file mode 100644 index 0000000000..6e93fafb08 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYDefines.h @@ -0,0 +1,54 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file GREYDefines.h + * @brief Miscellaneous defines and macros for EarlGrey. + */ + +#import + +#ifndef GREY_DEFINES_H +#define GREY_DEFINES_H + +#define GREY_EXPORT FOUNDATION_EXPORT __used +#define GREY_EXTERN FOUNDATION_EXTERN +#define GREY_UNUSED_VARIABLE __attribute__((unused)) + +#define iOS8_0_OR_ABOVE() ([UIDevice currentDevice].systemVersion.doubleValue >= 8.0) +#define iOS8_1_OR_ABOVE() ([UIDevice currentDevice].systemVersion.doubleValue >= 8.1) +#define iOS8_2_OR_ABOVE() ([UIDevice currentDevice].systemVersion.doubleValue >= 8.2) +#define iOS9_OR_ABOVE() ([UIDevice currentDevice].systemVersion.intValue >= 9) +#define iOS10_OR_ABOVE() ([UIDevice currentDevice].systemVersion.intValue >= 10) +#define iOS11_OR_ABOVE() ([UIDevice currentDevice].systemVersion.intValue >= 11) + +#pragma mark - Math + +/** + * @return The smallest @c int following the @c double @c x. This macro is needed to avoid + * rounding errors when "modules" project setting is enabled causing math functions to + * map from tgmath.h to math.h. + */ +#define grey_ceil(x) ((CGFloat)ceil(x)) + +/** + * @return The largest @c int less than the @c double @c x. This macro is needed to avoid + * rounding errors when "modules" project setting is enabled causing math functions to + * map from tgmath.h to math.h. + */ +#define grey_floor(x) ((CGFloat)floor(x)) + +#endif // GREY_DEFINES_H diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYDescription.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYDescription.h new file mode 100644 index 0000000000..dca2bcc880 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYDescription.h @@ -0,0 +1,48 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A protocol that defines the layout of an object that conforms to GREYMatcher. + */ +@protocol GREYDescription + +/** + * Appends the provided text to the GREYDescription. + * + * @param text The text to be appended to the GREYDescription. + * + * @return An instance of an object conforming to GREYDescription with the provided + * @c text appended to it. + */ +- (id)appendText:(NSString *)text; + +/** + * Appends the description of the provided object to the GREYDescription. + * + * @param object The object whose description is to be appended to the GREYDescription. + * + * @return An instance of an object conforming to GREYDescription with the provided + * object's description appended to it. + */ +- (id)appendDescriptionOf:(id)object; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYDispatchQueueIdlingResource.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYDispatchQueueIdlingResource.h new file mode 100644 index 0000000000..2713ef5bac --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYDispatchQueueIdlingResource.h @@ -0,0 +1,51 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Idling resource that tracks blocks sent to a dispatch queue. + */ +@interface GREYDispatchQueueIdlingResource : NSObject + +/** + * Creates an idling resource backed by the specified @c queue. + * + * @c dispatch_sync blocks and dispatch_sync_f tasks sent to @c queue are tracked. + * @c dispatch_async blocks and @c dispatch_async_f tasks sent to @c queue are tracked. + * @c dispatch_after blocks and @c dispatch_after_f tasks sent to @c queue are tracked if they are + * delayed no more than the delay amount set for the + * @c kGREYConfigKeyTrackableDispatchAfterDuration configuration. A weak reference is held to + * @c queue. If @c queue is deallocated, then the idling resource will deregister itself from the + * UI thread executor. + * + * @param queue The dispatch queue that will be tracked by the resource. + * @param name A descriptive name for the idling resource. + * + * @return An idling resource backed by the specified dispatch queue. + */ ++ (instancetype)resourceWithDispatchQueue:(dispatch_queue_t)queue name:(NSString *)name; + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYElementFinder.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYElementFinder.h new file mode 100644 index 0000000000..d5e0f1e28a --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYElementFinder.h @@ -0,0 +1,61 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +@protocol GREYMatcher, GREYProvider; + +NS_ASSUME_NONNULL_BEGIN + +/** + * Finds UI elements in GREYProvider that are accepted by a matcher. + */ +@interface GREYElementFinder : NSObject + +/** + * The matcher the element finder is initialized with. Objects returned from this class + * must match this matcher. + */ +@property(nonatomic, readonly) id matcher; + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * Initializes the finder with a given @c matcher. + * + * @param matcher Matcher that defines what elements the finder should search for. + * + * @return An instance of GREYElementFinder, initialized with a matcher. + */ +- (instancetype)initWithMatcher:(id)matcher NS_DESIGNATED_INITIALIZER; + +/** + * Performs a search on elements provided by @c elementProvider and returns all the elements + * that are accepted by the matcher this object is initialized with. + * + * @param elementProvider Provides elements to run through the matcher. + * + * @return An array of matched elements. If no matching element is found, then it is empty. + * The relative order of the elements is preserved when returned. + */ +- (NSArray *)elementsMatchedInProvider:(id)elementProvider; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYElementHierarchy.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYElementHierarchy.h new file mode 100644 index 0000000000..d0a7008eaa --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYElementHierarchy.h @@ -0,0 +1,60 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A utility to get the string representation of the UI hierarchy. + */ +@interface GREYElementHierarchy : NSObject + +/** + * Returns UI hierarchy with @c element as the root. @c element can be either a UIView or an + * Accessibility element. + * + * @param element The root element for the hierarchy. + * + * @return The UI hierarchy as a string. + */ ++ (NSString *)hierarchyStringForElement:(id)element; + +/** + * Similar to hierarchyStringForElement: with additional parameters for providing annotations + * for printed views. @c annotationDictionary is a dictionary of type + * @code @{[NSValue valueWithNonretainedObject:id]:NSString} @endcode with UI elements that + * require special formatting i.e. special text to be appended to the description. For example, + * @code @{viewA : @"This is a special view"} @endcode or + * @code @{elementA : @"This is a special view"} @endcode will have it's description as: + * @" This is a special view". + * + * @param element The root element for the hierarchy. + * @param annotationDictionary A dictionary of annotations. + * + * @return The UI hierarchy as a string. + */ ++ (NSString *)hierarchyStringForElement:(id)element + withAnnotationDictionary:(NSDictionary *_Nullable)annotationDictionary; + +/** + * Returns the UI hierarchy for all @c UIWindows provided by the GREYUIWindowProvider. + */ ++ (NSString *)hierarchyStringForAllUIWindows; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYElementInteraction.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYElementInteraction.h new file mode 100644 index 0000000000..24cec5778a --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYElementInteraction.h @@ -0,0 +1,46 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Interface for creating an interaction with a UI element. If no datasource is set, + * a default datasource is used. The default datasource provides access to the entire UI element + * hierarchy of all the windows in the application. + */ +@interface GREYElementInteraction : NSObject + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * Initializes the interaction with a single UI element matching @c elementMatcher. + * + * @param elementMatcher Matcher for selecting UI element to interact with. + * + * @return An instance of GREYElementInteraction, initialized with a specified matcher. + */ +- (instancetype)initWithElementMatcher:(id)elementMatcher; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYElementMatcherBlock.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYElementMatcherBlock.h new file mode 100644 index 0000000000..ee9f1b8fb0 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYElementMatcherBlock.h @@ -0,0 +1,87 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A block for implementing GREYBaseMatcher::matches:. + * + * @param element The element passed to the block for matching. + * + * @return @c YES if the matcher's specified condition was matched by the element, else @c NO. + */ +typedef BOOL (^MatchesBlock)(id element); + +/** + * A block for implementing GREYBaseMatcher::describeTo:. + * + * @param description The description for the matcher. + */ +typedef void (^DescribeToBlock)(id description); + +@protocol GREYDescription; + +/** + * A block based implementation of GREYBaseMatcher. Enables custom implementation of protocol + * method using blocks. + */ +@interface GREYElementMatcherBlock : GREYBaseMatcher + +/** + * The block which will be invoked for the GREYBaseMatcher::matches: method. + */ +@property(nonatomic, copy) MatchesBlock matcherBlock; + +/** + * The block which will be invoked for the GREYBaseMatcher::describeTo: method. + */ +@property(nonatomic, copy) DescribeToBlock descriptionBlock; + +/** + * Class method to instantiate a custom matcher. + * + * @param matchBlock A block for implementing GREYBaseMatcher::matches: method. + * @param describeBlock The block which will be invoked for the GREYBaseMatcher::describeTo: + * method. + * + * @return A GREYElementMatcherBlock instance, initialized with the required matching + * condition and description. + */ ++ (instancetype)matcherWithMatchesBlock:(MatchesBlock)matchBlock + descriptionBlock:(DescribeToBlock)describeBlock; + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * Initializes a custom matcher. + * + * @param matchBlock A block for implementing GREYBaseMatcher::matches: method. + * @param describeBlock The block which will be invoked for the + * GREYBaseMatcher::describeTo: method. + * + * @return A GREYElementMatcherBlock instance, initialized with the required matching + * condition and description. + */ +- (instancetype)initWithMatchesBlock:(MatchesBlock)matchBlock + descriptionBlock:(DescribeToBlock)describeBlock NS_DESIGNATED_INITIALIZER; +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYFailureHandler.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYFailureHandler.h new file mode 100644 index 0000000000..58132f5b02 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYFailureHandler.h @@ -0,0 +1,48 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +@class GREYFrameworkException; + +NS_ASSUME_NONNULL_BEGIN + +/** + * Protocol for handling failures (such as failure of actions and assertions) raised by EarlGrey. + */ +@protocol GREYFailureHandler + +/** + * Called by the framework to raise an exception. + * + * @param exception The exception to be handled. + * @param details Extra information about the failure. + */ +- (void)handleException:(GREYFrameworkException *)exception details:(NSString *)details; + +@optional + +/** + * Sets the file name and line number of operation that caused the failure. + * + * @param fileName The name of the file where the error happened. + * @param lineNumber The line number in the file that caused the error. + */ +- (void)setInvocationFile:(NSString *)fileName andInvocationLine:(NSUInteger)lineNumber; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYFrameworkException.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYFrameworkException.h new file mode 100644 index 0000000000..01755f4eaf --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYFrameworkException.h @@ -0,0 +1,105 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Generic framework failure. + */ +GREY_EXTERN NSString *const kGREYGenericFailureException; +/** + * Thrown on action failure. + */ +GREY_EXTERN NSString *const kGREYActionFailedException; +/** + * Thrown on assertion failure. + */ +GREY_EXTERN NSString *const kGREYAssertionFailedException; +/** + * Thrown when assertion failed due to an unexpected @c nil parameter. + */ +GREY_EXTERN NSString *const kGREYNilException; +/** + * Thrown when assertion failed due to an unexpected non-nil parameter. + */ +GREY_EXTERN NSString *const kGREYNotNilException; + +/** + * Thrown by the selection API when no UI element matches the selection matcher. + */ +GREY_EXTERN NSString *const kGREYNoMatchingElementException; + +/** + * Thrown by the interaction API when either an action or assertion matcher matches multiple + * elements in the UI hierarchy. + */ +GREY_EXTERN NSString *const kGREYMultipleElementsFoundException; + +/** + * Thrown by the interaction API when either an action or assertion times out waiting for the + * app to become idle. + */ +GREY_EXTERN NSString *const kGREYTimeoutException; + +/** + * Thrown by the action API when the constraints required for performing the action are not + * satisfied. + */ +GREY_EXTERN NSString *const kGREYConstraintFailedException; + +/** + * Exception raised by the framework which results in a test failure. + * To catch such exceptions, install a custom failure handler + * using EarlGrey::setFailureHandler:. A default failure handler is provided by the framework. + */ +@interface GREYFrameworkException : NSException + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * Creates a new exception instance. + * + * @param name The name of the exception. + * @param reason The reason for the exception. + * + * @return A GREYFrameworkException instance, initialized with a @c name and @c reason. + */ ++ (instancetype)exceptionWithName:(NSString *)name reason:(nullable NSString *)reason; + +/** + * Creates a new exception instance. + * + * @param name The name of the exception. + * @param reason The reason for the exception. + * @param userInfo userInfo as used by @c NSException. + * EarlGrey doesn't use this param so it's safe to pass nil. + * + * @return A GREYFrameworkException instance, initialized with a @c name and @c reason. + */ ++ (instancetype)exceptionWithName:(NSString *)name + reason:(nullable NSString *)reason + userInfo:(nullable NSDictionary *)userInfo; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYIdlingResource.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYIdlingResource.h new file mode 100644 index 0000000000..8a7d34aa10 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYIdlingResource.h @@ -0,0 +1,52 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A protocol for resources that can potentially modify the UI and should be synchronized with + * before performing any interaction or verification with UI element. + */ +@protocol GREYIdlingResource + +/** + * A method to query idleness of this resource. + * + * Note: This method is called on the main thread and polled continuously until this resource goes + * into idle state or a test timeout occurs. It is discouraged to perform any heavy tasks in this + * method. + * + * @return @c YES if the resource is currently idle; @c NO otherwise. + */ +- (BOOL)isIdleNow; + +/** + * @return A user friendly name that will be printed if this resource fails to idle leading to a + * test timeout. + */ +- (NSString *)idlingResourceName; + +/** + * @return Information that will be printed alongside the name if this resource fails to idle in + * the given timeout. + */ +- (NSString *)idlingResourceDescription; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYInteraction.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYInteraction.h new file mode 100644 index 0000000000..492c6f4179 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYInteraction.h @@ -0,0 +1,268 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import + +@protocol GREYInteractionDataSource; +@protocol GREYAction; +@protocol GREYAssertion; +@protocol GREYMatcher; + +NS_ASSUME_NONNULL_BEGIN + +/** + * Error domain for element interaction failures. + */ +GREY_EXTERN NSString *const kGREYInteractionErrorDomain; + +/** + * Error codes for element interaction failures. + */ +typedef NS_ENUM(NSInteger, GREYInteractionErrorCode) { + /** + * Element search has failed. + */ + kGREYInteractionElementNotFoundErrorCode = 0, + /** + * Constraints failed for performing an interaction. + */ + kGREYInteractionConstraintsFailedErrorCode, + /** + * Action execution has failed. + */ + kGREYInteractionActionFailedErrorCode, + /** + * Assertion execution has failed. + */ + kGREYInteractionAssertionFailedErrorCode, + /** + * Timeout reached before interaction could be performed. + */ + kGREYInteractionTimeoutErrorCode, + /** + * Single element search found multiple elements. + */ + kGREYInteractionMultipleElementsMatchedErrorCode, + /** + * Index provided for matching an element from multiple elements was over the number of elements + * found. + */ + kGREYInteractionMatchedElementIndexOutOfBoundsErrorCode, +}; + +/** + * Notification name for when an action will be performed. The action itself is contained in the + * @c userInfo object from the @c notification and can be obtained using the key + * @c kGREYActionUserInfoKey. + */ +GREY_EXTERN NSString *const kGREYWillPerformActionNotification; + +/** + * Notification name for when an action has been performed. The action itself is contained in the + * @c userInfo object from the @c notification and can be obtained using the key + * @c kGREYActionUserInfoKey. + */ +GREY_EXTERN NSString *const kGREYDidPerformActionNotification; + +/** + * Notification name for when an assertion will be checked. The assertion itself is contained in + * the @c userInfo object from the @c notification and can be obtained using the key + * @c kGREYAssertionUserInfoKey. + */ +GREY_EXTERN NSString *const kGREYWillPerformAssertionNotification; + +/** + * Notification name for when an assertion has been performed. The assertion itself is contained + * in the @c userInfo object from the @c notification and can be obtained using the key + * @c kGREYAssertionUserInfoKey. + */ +GREY_EXTERN NSString *const kGREYDidPerformAssertionNotification; + +/** + * User Info dictionary key for the action performed. + */ +GREY_EXTERN NSString *const kGREYActionUserInfoKey; + +/** + * User Info dictionary key for the element an action was performed on. The element for an + * assertion can be @c nil in case of an error. + */ +GREY_EXTERN NSString *const kGREYActionElementUserInfoKey; + +/** + * User Info dictionary key for any error populated on the action being performed. + */ +GREY_EXTERN NSString *const kGREYActionErrorUserInfoKey; + +/** + * User Info dictionary key for the assertion checked. + */ +GREY_EXTERN NSString *const kGREYAssertionUserInfoKey; + +/** + * User Info dictionary key for the element an assertion was checked on. The element for an + * assertion can be @c nil since assertions can be performed on @c nil elements. + */ +GREY_EXTERN NSString *const kGREYAssertionElementUserInfoKey; + +/** + * User Info dictionary key for any error populated on the assertion being checked. + */ +GREY_EXTERN NSString *const kGREYAssertionErrorUserInfoKey; + +/** + * Represents an interaction with a UI element. + */ +@protocol GREYInteraction + +/** + * Data source for providing UI elements to interact with. + * The dataSource must adopt GREYInteractionDataSource protocol and a weak reference is held. + */ +@property(nonatomic, weak) id dataSource; + +/** + * Indicates that the current interaction should be performed on a UI element contained inside + * another UI element that is uniquely matched by @c rootMatcher. + * + * @param rootMatcher Matcher used to select the container of the element the interaction + * will be performed on. + * + * @return The provided GREYInteraction instance, with an appropriate rootMatcher. + */ +- (instancetype)inRoot:(id)rootMatcher; + +/** + * Performs the @c action repeatedly on the element matching the @c matcher until the element + * to interact with (specified by GREYInteraction::selectElementWithMatcher:) is found or a + * timeout occurs. The search action is only performed when coupled with + * GREYInteraction::performAction:, GREYInteraction::assert:, or + * GREYInteraction::assertWithMatcher: APIs. This API only creates an interaction consisting of + * repeated executions of the search action provided. You need to call an action or assertion + * after this in order to interaction with the element being searched for. + * + * For example, this code will perform an upward scroll of 50 points until an element is found + * and then tap on it: + * @code + * [[[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"elementToFind")] + * usingSearchAction:grey_scrollInDirection(kGREYDirectionUp, 50.0f) + * onElementWithMatcher:grey_accessibilityID(@"ScrollingWindow")] + * performAction:grey_tap()] // This should be separately called for the action. + * @endcode + * + * @param action The action to be performed on the element. + * @param matcher The matcher that the element matches. + * + * @return The provided GREYInteraction instance, with an appropriate action and matcher. + */ +- (instancetype)usingSearchAction:(id)action + onElementWithMatcher:(id)matcher; + +/** + * Performs an @c action on the selected UI element. + * + * @param action The action to be performed on the @c element. + * @throws NSException if the action fails. + * + * @return The provided GREYInteraction instance with an appropriate action. + */ +- (instancetype)performAction:(id)action NS_REFINED_FOR_SWIFT; + +/** + * Performs an @c action on the selected UI element with an error set on failure. + * + * @param action The action to be performed on the @c element. + * @param[out] errorOrNil Error populated on failure. + * @throws NSException on action failure if @c errorOrNil is not set. + * + * @return The provided GREYInteraction instance, with an action and an error that will be + * populated on failure. + */ +- (instancetype)performAction:(id)action + error:(__strong NSError *_Nullable *_Nullable)errorOrNil + NS_SWIFT_NOTHROW NS_REFINED_FOR_SWIFT; + +/** + * Performs an @c assertion on the selected UI element. + * + * @param assertion The assertion to be performed on the @c element. + * @throws NSException if the @c assertion fails. + * + * @return The provided GREYInteraction instance with a valid assertion. + */ +- (instancetype)assert:(id)assertion; + +/** + * Performs an @c assertion on the selected UI element with an error set on failure. + * + * @param assertion The assertion to be performed on the @c element. + * @param[out] errorOrNil Error populated on failure. + * @throws NSException on assertion failure if @c errorOrNil is not set. + * + * @return The provided GREYInteraction instance with an assertion and an error that will be + * populated on failure. + */ +- (instancetype)assert:(id)assertion + error:(__strong NSError *_Nullable *_Nullable)errorOrNil NS_SWIFT_NOTHROW; + +/** + * Performs an assertion that evaluates @c matcher on the selected UI element. + * + * @param matcher The matcher to be evaluated on the @c element. + * + * @return The provided GREYInteraction instance with a matcher to be evaluated on an element. + */ +- (instancetype)assertWithMatcher:(id)matcher NS_REFINED_FOR_SWIFT; + +/** + * Performs an assertion that evaluates @c matcher on the selected UI element. + * + * @param matcher The matcher to be evaluated on the @c element. + * @param[out] errorOrNil Error populated on failure. + * @throws NSException on assertion failure if @c errorOrNil is not set. + * + * @return The provided GREYInteraction instance, with a matcher to be evaluated on an element and + * an error that will be populated on failure. + */ +- (instancetype)assertWithMatcher:(id)matcher + error:(__strong NSError *_Nullable *_Nullable)errorOrNil + NS_SWIFT_NOTHROW NS_REFINED_FOR_SWIFT; + +/** + * In case of multiple matches, selects the element at the specified index. In case of the + * index being over the number of matched elements, it throws an exception. Please make sure + * that this is used after you've created the matcher. For example, in case three elements are + * matched, and you wish to match with the second one, then @c atIndex would be used in this + * manner: + * + * @code + * [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(@"Generic Matcher")] atIndex:1]; + * @endcode + * + * @param index The zero-indexed position of the element in the list of matched elements + * to be selected. + * @throws NSException if the @c index is more than the number of matched elements. + * + * @return An interaction (assertion or an action) to be performed on the element at the + * specified index in the list of matched elements. + */ +- (instancetype)atIndex:(NSUInteger)index; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYLayoutConstraint.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYLayoutConstraint.h new file mode 100644 index 0000000000..8595e1542d --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYLayoutConstraint.h @@ -0,0 +1,106 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Modeled after NSLayoutConstraint, this class captures information related to a layout + * constraint: two attributes and a relation that must be satisfied between them. + */ +@interface GREYLayoutConstraint : NSObject + +/** + * Creates a GREYLayoutConstraint to verify a constraint attribute on an element. The relation is + * given by : @c attribute value = @c referenceAttribute * @c multiplier + @c constant. + * + * For example, with constraint relation @c kGREYLayoutRelationEqual, multiplier 2.0 and + * constant 10.0, the attribute values of 20.0 and 5.0 satisfy the constraint because: + * 20.0 = 5.0 * 2.0 + 10.0 but 30.0 and 40.0 don't because 30.0 != 40.0 * 2.0 + 10.0. + * + * @param attribute A layout attribute to create the constraint from. + * @param relation The GREYLayoutRelation between the @c attribute and + * the @c referenceAttribute + * @param referenceAttribute The layout attribute whose relation is being checked + * with respect to @attribute. + * @param multiplier Value to multiply the @c referenceAttribute value. + * @param constant Any constant to be added to the relation being checked. + * + * @return A GREYLayoutConstraint instance, that constrains an element's attribute with + * respect to a reference. + */ ++ (instancetype)layoutConstraintWithAttribute:(GREYLayoutAttribute)attribute + relatedBy:(GREYLayoutRelation)relation + toReferenceAttribute:(GREYLayoutAttribute)referenceAttribute + multiplier:(CGFloat)multiplier + constant:(CGFloat)constant; + +/** + * Creates a GREYLayoutConstraint that checks the position of a UI element with respect to a + * particular direction + * + * @param direction The direction being checked against the reference element. + * @param separation The separation between an element and an edge in the given @c direction. + * + * @return A GREYLayoutConstraint instance that constrains an element to a particular direction. + */ ++ (instancetype)layoutConstraintForDirection:(GREYLayoutDirection)direction + andMinimumSeparation:(CGFloat)separation; + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * Checks if the given element satisfies the provided constraints, as shown by a reference element. + * + * @param element The element being checked for the constraints. + * @param referenceElement The reference element to check the @c element against. + * + * @return @c YES if the the given elements satisify the constraint, else @NO. + */ +- (BOOL)satisfiedByElement:(id)element andReferenceElement:(id)referenceElement; + +/** + * @return A description of the GREYLayoutConstraint created. + */ +- (NSString *)description; + +/** + * The attribute constraint being checked. + */ +@property(nonatomic, assign) GREYLayoutAttribute attribute; +/** + * The GREYLayoutRelation between the @c attribute and the @c referenceAttribute. + */ +@property(nonatomic, assign) GREYLayoutRelation relation; +/** + * The value the @c attribute is being compared to. + */ +@property(nonatomic, assign) GREYLayoutAttribute referenceAttribute; +/** + * Value to multiply the @c referenceAttribute value with. + */ +@property(nonatomic, assign) CGFloat multiplier; +/** + * Any constant to be added to the relation being checked. + */ +@property(nonatomic, assign) CGFloat constant; +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYManagedObjectContextIdlingResource.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYManagedObjectContextIdlingResource.h new file mode 100644 index 0000000000..5a7bfc0d0c --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYManagedObjectContextIdlingResource.h @@ -0,0 +1,55 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +@class NSManagedObjectContext; + +NS_ASSUME_NONNULL_BEGIN + +/** + * Idling resource that tracks core data managed object context operations. + * + * Tracks the managed object context's internal operation queue and optionally any pending changes + * yet to be committed. + */ +@interface GREYManagedObjectContextIdlingResource : NSObject + +/** + * Creates an idling resource tracking @c managedObjectContext. + * + * A weak reference is held to @c managedObjectContext. If @c managedObjectContext is deallocated, + * then the idling resource will deregister itself from the thread executor. + * + * @param managedObjectContext The managed object context to be tracked by the resource. + * @param trackPendingChanges If @c YES, then the idling resource will report that it is busy + * when the managed object context has pending changes. + * @param name A descriptive name for the idling resource. + * + * @return An idling resource tracking @c managedObjectContext. + */ ++ (instancetype)resourceWithManagedObjectContext:(NSManagedObjectContext *)managedObjectContext + trackPendingChanges:(BOOL)trackPendingChanges + name:(NSString *)name; + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYMatcher.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYMatcher.h new file mode 100644 index 0000000000..4a4bd69429 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYMatcher.h @@ -0,0 +1,74 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Matchers are another way of expressing simple or complex logical expressions. This protocol + * defines a set of methods that must be implemented by every matcher object. + */ +@protocol GREYMatcher + +/** + * A method to evaluate the matcher for the provided @c item. + * + * @param item The object which is to be evaluated against the matcher. + * + * @return @c YES if the object matched the matcher, @c NO otherwise. + */ +- (BOOL)matches:(_Nullable id)item; + +/** + * A method to evaluate the matcher for the provided @c item with a description for the issue + * in case of a mismatch. + * + * @param item The object which is to be evaluated against the matcher. + * + * @param mismatchDescription The description that is built or appended if the provided @c item + * does not match the matcher. + * + * @return @c YES if the object matched the matcher, @c NO otherwise. In case of a mismatch, the + * reason for mismatch is added to @c mismatchDescription. + */ +- (BOOL)matches:(_Nullable id)item describingMismatchTo:(id)mismatchDescription; + +/** + * A method to generate the description containing the reason for why a matcher did not match an + * item. + * + * @param item The object which is to be evaluated against the matcher. + * + * @param mismatchDescription The description that is built or appended if the provided @c item + * does not match the matcher. + * + * @remark This method assumes that GREYMatcher::matches: is false, but will not check this. + */ +- (void)describeMismatchOf:(_Nullable id)item to:(id)mismatchDescription; + +/** + * A method to generate a description of an object. + * + * @param description The description that is built or appended. + */ +- (void)describeTo:(id)description; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYMatchers.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYMatchers.h new file mode 100644 index 0000000000..2156e2d762 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYMatchers.h @@ -0,0 +1,563 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@protocol GREYMatcher; + +/** + * EarlGrey matchers for UI elements. + */ +@interface GREYMatchers : NSObject + +/** + * Matcher for application's key window. + * + * @return A matcher for the application's key window. + */ ++ (id)matcherForKeyWindow; + +/** + * Matcher for UI element with the provided accessibility @c label. + * + * @param label The accessibility label to be matched. + * + * @return A matcher for the accessibility label of an accessible element. + */ ++ (id)matcherForAccessibilityLabel:(NSString *)label; + +/** + * Matcher for UI element with the provided accessibility ID @c accessibilityID. + * + * @param accessibilityID The accessibility ID to be matched. + * + * @return A matcher for the accessibility ID of an accessible element. + */ ++ (id)matcherForAccessibilityID:(NSString *)accessibilityID; + +/** + * Matcher for UI element with the provided accessibility @c value. + * + * @param value The accessibility value to be matched. + * + * @return A matcher for the accessibility value of an accessible element. + */ ++ (id)matcherForAccessibilityValue:(NSString *)value; + +/** + * Matcher for UI element with the provided accessibility @c traits. + * + * @param traits The accessibility traits to be matched. + * + * @return A matcher for the accessibility traits of an accessible element. + * + */ ++ (id)matcherForAccessibilityTraits:(UIAccessibilityTraits)traits; + +/** + * Matcher for UI element with the provided accessiblity @c hint. + * + * @param hint The accessibility hint to be matched. + * + * @return A matcher for the accessibility hint of an accessible element. + */ ++ (id)matcherForAccessibilityHint:(NSString *)hint; + +/** + * Matcher for UI element with accessiblity focus. + * + * @return A matcher for the accessibility focus of an accessible element. + */ ++ (id)matcherForAccessibilityElementIsFocused; + +/** + * Matcher for UI elements of type UIButton, UILabel, UITextField or UITextView displaying the + * provided @c inputText. + * + * @param text The text to be matched in the UI elements. + * + * @return A matcher to check for any UI elements with a text field containing the given text. + */ ++ (id)matcherForText:(NSString *)text; + +/** + * Matcher for element that is the first responder. + * + * @return A matcher that verifies if a UI element is the first responder. + */ ++ (id)matcherForFirstResponder; + +/** + * Matcher to check if system alert view is shown. + * + * @return A matcher to check if a system alert view is being shown. + */ ++ (id)matcherForSystemAlertViewShown; + +/** + * Matcher for UI element whose percent visible area (of its accessibility frame) exceeds the + * given @c percent. + * + * @param percent The percent visible area that the UI element being matched has to be visible. + * Allowed values for @c percent are [0,1] inclusive. + * + * @return A matcher that checks if a UI element has a visible area at least equal + * to a minimum value. + */ ++ (id)matcherForMinimumVisiblePercent:(CGFloat)percent; + +/** + * Matcher for UI element that is sufficiently visible to the user. EarlGrey considers elements + * that are more than @c kElementSufficientlyVisiblePercentage (75 %) visible areawise to be + * sufficiently visible. + * + * @return A matcher intialized with a visibility percentage that confirms an element is + * sufficiently visible. + */ ++ (id)matcherForSufficientlyVisible; + +/** + * Matcher for UI element that is not visible to the user at all i.e. it has a zero visible area. + * + * @return A matcher for verifying if an element is not visible. + */ ++ (id)matcherForNotVisible; + +/** + * Matcher for UI element that matches EarlGrey's criteria for user interaction. Currently it must + * satisfy at least the following criteria: + * 1) At least a few pixels of the element are visible to the user. + * 2) The element's accessibility activation point OR the center of the element's visible area + * is completely visible. +* + * @return A matcher that checks if a UI element is interactable. + */ ++ (id)matcherForInteractable; + +/** + * Matcher to check if a UI element is accessible. + * + * @return A matcher that checks if a UI element is accessible. + */ ++ (id)matcherForAccessibilityElement; + +/** + * Matcher for elements that are instances of the provided @c klass or any class that inherits from + * it. + * + * @param klass A class. + * + * @return A matcher that checks if the given element's class is the provided @c klass or any of + * its derived classes. + */ ++ (id)matcherForKindOfClass:(Class)klass; + +/** + * Matcher for matching UIProgressView's values. Use greaterThan, greaterThanOrEqualTo, + * lessThan etc to create @c comparisonMatcher. For example, to match the UIProgressView + * elements that have progress value greater than 50.2, use + * @code [GREYMatchers matcherForProgress:grey_greaterThan(@(50.2))] @endcode. In case if an + * unimplemented matcher is required, please implement it similar to @c grey_closeTo. + * + * @param comparisonMatcher The matcher with the value to check the progress against. + * + * @return A matcher for checking a UIProgessView's value. + */ ++ (id)matcherForProgress:(id)comparisonMatcher; + +/** + * Matcher for UI element that respond to the provided @c sel. + * + * @param sel The selector to be responded to. + * + * @return A matcher to check if a UI element's class responds to a particular selector. + */ ++ (id)matcherForRespondsToSelector:(SEL)sel; + +/** + * Matcher for UI element that conform to the provided @c protocol. + * + * @param protocol The protocol that the UI element must conform to. + * + * @return A matcher to check if a UI element's class confirms to a particular protocol. + */ ++ (id)matcherForConformsToProtocol:(Protocol *)protocol; + +/** + * Matcher that matches any UI element with an ancestor matching the given @c ancestorMatcher. + * + * @param ancestorMatcher A matcher that's run against the ancestors of the UI element being + * matched. + * + * @return A matcher to check if a specified element has an ancestor that matches + * @c ancestorMatcher. + */ ++ (id)matcherForAncestor:(id)ancestorMatcher; + +/** + * Matcher that matches any UI element with a descendant matching the given @c descendantMatcher. + * + * @param descendantMatcher A matcher that's run against the descendants of the UI element being + * matched. + * + * @return A matcher to check if a specified element has a descendant that matches + * @c descendantMatcher. + */ ++ (id)matcherForDescendant:(id)descendantMatcher; + +/** + * Matcher that matches UIButton that has title label as @c text. + * + * @param title The title to be checked on the UIButtons being matched. + * + * @return A matcher to confirm UIButton titles. + */ ++ (id)matcherForButtonTitle:(NSString *)title; + +/** + * Matcher that matches UIScrollView that has contentOffset as @c offset. + * + * @param offset The content offset to be checked on the UIScrollView being + * matched. + * + * @return A matcher to confirm UIScrollView content offset. + */ ++ (id)matcherForScrollViewContentOffset:(CGPoint)offset; + +/** + * Matcher that matches UIStepper with value as @c value. + * + * @param value A value that the UIStepper should be checked for. + * + * @return A matcher for checking UIStepper values. + */ ++ (id)matcherForStepperValue:(double)value; + +/** + * Matcher that matches a UISlider's value. + * + * @param valueMatcher A matcher for the UISlider's value. You must provide a valid + * @c valueMatcher for the floating point value comparison. The + * @c valueMatcher should be of the type @c closeTo, @c greaterThan, + * @c lessThan, @c lessThanOrEqualTo, @c greaterThanOrEqualTo. The + * value matchers should account for any loss in precision for the given + * floating point value. If you are using @c grey_closeTo, use delta diff as + * @c kGREYAcceptableFloatDifference. In case if an unimplemented matcher + * is required, please implement it similar to @c grey_closeTo. + * + * @return A matcher for checking a UISlider's value. + */ ++ (id)matcherForSliderValueMatcher:(id)valueMatcher; + +/** + * Matcher that matches UIDatePicker that is set to @c value. + * + * @param value The date value that should be present in the UIDatePicker + * + * @return A matcher for a date in a UIDatePicker. + */ ++ (id)matcherForDatePickerValue:(NSDate *)value; + +/** + * Matcher that matches UIPickerView that has a column set to @c value. + * + * @param column The column of the UIPickerView to be matched. + * @param value The value that should be set in the column of the UIPickerView. + * + * @return A matcher to check the value in a particular column of a UIPickerView. + */ ++ (id)matcherForPickerColumn:(NSInteger)column + setToValue:(nullable NSString *)value; + +/** + * Matcher that verifies whether an element, that is a UIControl, is enabled. + * + * @return A matcher for checking whether a UI element is an enabled UIControl. + */ ++ (id)matcherForEnabledElement; + +/** + * Matcher that verifies whether an element, that is a UIControl, is selected. + * + * @return A matcher for checking whether a UI element is a selected UIControl. + */ ++ (id)matcherForSelectedElement; + +/** + * Matcher that verifies whether a view has its userInteractionEnabled property set to @c YES. + * + * @return A matcher for checking whether a view' userInteractionEnabled property is set to @c YES. + */ ++ (id)matcherForUserInteractionEnabled; + +/** + * Matcher that verifies that the selected element satisfies the given constraints to the + * reference element. + * Usage: + * @code + * GREYLayoutConstraint *constraint1 = [GREYLayoutConstraint layoutConstraintWithAttribute ... ]; + * GREYLayoutConstraint *constraint2 = [GREYLayoutConstraint layoutConstraintForDirection ... ]; + * id *matcher = [GREYMatcher matcherForConstraints:@[ constraint1, constraint2 ] + * toReferenceElementMatching:aReferenceElementMatcher]; + * [EarlGrey selectElementWithMatcher ...] assertWithMatcher:matcher]; + * @endcode + * + * @param constraints The constraints to be matched. + * @param referenceElementMatcher The reference element with the correct constraints. + * + * @remark Constraints are often represented using floating point numbers. Floating point + * arithmetic can often induce errors based on the way the numbers are represented in + * hardware; hence, floating point comparisons use a margin value + * @c kGREYAcceptableFloatDifference that is used for adding accuracy to such arithmetic. + * + * @return A matcher to verify the GREYLayoutConstraints on a UI element. + */ ++ (id)matcherForConstraints:(NSArray *)constraints + toReferenceElementMatching:(id)referenceElementMatcher; + +/** + * Matcher primarily for asserting that the element is @c nil or not found. + * + * @return A matcher to check if a specified element is @c nil or not found. + */ ++ (id)matcherForNil; + +/** + * Matcher for asserting that the element exists in the UI hierarchy (i.e. not @c nil). + * + * @return A matcher to check if a specified element is not @c nil. + */ ++ (id)matcherForNotNil; + +/** + * Matcher for toggling the switch control. + * + * @param on The state of the switch control. The switch control is in ON state if @c on is @c YES + * or OFF state if @c on is NO. + * + * @return A matcher to check if a UISwitch is on or off. + */ ++ (id)matcherForSwitchWithOnState:(BOOL)on; + +/** + * A Matcher for NSNumbers that matches when the examined number is within a specified @c delta + * from the specified value. + * + * @param value The expected value of the number being matched. + * + * @param delta The delta within which matches are allowed + * + * @return A matcher that checks if a number is close to a specified @c value. + */ ++ (id)matcherForCloseTo:(double)value delta:(double)delta; + +/** + * A Matcher that matches against any object, including @c nils. + * + * @return A matcher that matches any object. + */ ++ (id)matcherForAnything; + +/** + * A Matcher that checks if a provided object is equal to the specified @c value. The equality is + * determined by calling the @c isEqual: method of the object being examined. In case the @c + * value is @c nil, then the object itself is checked to be @c nil. + * + * @param value The value to be checked for equality. Please ensure that scalar types are + * passed in as boxed (object) values. + * + * @return A matcher that checks if an object is equal to the provided one. + */ ++ (id)matcherForEqualTo:(id)value; + +/** + * A Matcher that checks if a provided object is less than a specified @c value. The comparison + * is made by calling the @c compare: method of the object being examined. + * + * @param value The value to be compared, which should return @c NSOrderedDescending. Please + * ensure that scalar values are passed in as boxed (object) values. + * + * @return A matcher that checks an object is lesser than another provided @c value. + */ ++ (id)matcherForLessThan:(id)value; + +/** + * A Matcher that checks if a provided object is greater than a specified @c value. The comparison + * is made by calling the @c compare: method of the object being examined. + * + * @param value The value to be compared, which should return @c NSOrderedAscending. Please + * ensure that scalar values are passed in as boxed (object) values. + * + * @return A matcher that checks an object is greater than another provided @c value. + */ ++ (id)matcherForGreaterThan:(id)value; + +/** + * Matcher that matches a UIScrollView scrolled to content @c edge. + * + * @param edge The content edge UIScrollView should be scrolled to. + * + * @return A matcher that matches a UIScrollView scrolled to content @c edge. + */ ++ (id)matcherForScrolledToContentEdge:(GREYContentEdge)edge; + +/** + * Matcher that matches a UITextField's content. + * + * @param value The text string contained inside the UITextField. + * + * @return A matcher that matches the value inside a UITextField. + */ ++ (id)matcherForTextFieldValue:(NSString *)value; + +@end + +#if !(GREY_DISABLE_SHORTHAND) + +/** Shorthand for GREYMatchers::matcherForKeyWindow. */ +GREY_EXPORT id grey_keyWindow(void); + +/** Shorthand for GREYMatchers::matcherForAccessibilityLabel:. */ +GREY_EXPORT id grey_accessibilityLabel(NSString *label); + +/** Shorthand for GREYMatchers::matcherForAccessibilityID:. */ +GREY_EXPORT id grey_accessibilityID(NSString *accessibilityID); + +/** Shorthand for GREYMatchers::matcherForAccessibilityValue:. */ +GREY_EXPORT id grey_accessibilityValue(NSString *grey_accessibilityValue); + +/** Shorthand for GREYMatchers::matcherForAccessibilityTraits:. */ +GREY_EXPORT id grey_accessibilityTrait(UIAccessibilityTraits traits); + +/** Shorthand for GREYMatchers::matcherForAccessibilityElementIsFocused. */ +GREY_EXPORT id grey_accessibilityFocused(void); + +/** Shorthand for GREYMatchers::matcherForAccessibilityHint:. */ +GREY_EXPORT id grey_accessibilityHint(NSString *hint); + +/** Shorthand for GREYMatchers::matcherForText:. */ +GREY_EXPORT id grey_text(NSString *inputText); + +/** Shorthand for GREYMatchers::matcherForFirstResponder. */ +GREY_EXPORT id grey_firstResponder(void); + +/** Shorthand for GREYMatchers::matcherForSystemAlertViewShown. */ +GREY_EXPORT id grey_systemAlertViewShown(void); + +/** Shorthand for GREYMatchers::matcherForMinimumVisiblePercent:. */ +GREY_EXPORT id grey_minimumVisiblePercent(CGFloat percent); + +/** Shorthand for GREYMatchers::matcherForSufficientlyVisible. */ +GREY_EXPORT id grey_sufficientlyVisible(void); + +/** Shorthand for GREYMatchers::matcherForInteractable. */ +GREY_EXPORT id grey_interactable(void); + +/** Shorthand for GREYMatchers::matcherForNotVisible. */ +GREY_EXPORT id grey_notVisible(void); + +/** Shorthand for GREYMatchers::matcherForAccessibilityElement. */ +GREY_EXPORT id grey_accessibilityElement(void); + +/** Shorthand for GREYMatchers::matcherForKindOfClass:. */ +GREY_EXPORT id grey_kindOfClass(Class klass); + +/** Shorthand for GREYMatchers::matcherForProgress:. */ +GREY_EXPORT id grey_progress(id comparisonMatcher); + +/** Shorthand for GREYMatchers::matcherForRespondsToSelector:. */ +GREY_EXPORT id grey_respondsToSelector(SEL sel); + +/** Shorthand for GREYMatchers::matcherForConformsToProtocol:. */ +GREY_EXPORT id grey_conformsToProtocol(Protocol *protocol); + +/** Shorthand for GREYMatchers::matcherForAncestor:. */ +GREY_EXPORT id grey_ancestor(id ancestorMatcher); + +/** Shorthand for GREYMatchers::matcherForDescendant:. */ +GREY_EXPORT id grey_descendant(id descendantMatcher); + +/** Shorthand for GREYMatchers::matcherForButtonTitle:. */ +GREY_EXPORT id grey_buttonTitle(NSString *text); + +/** Shorthand for GREYMatchers::matcherForScrollViewContentOffset:. */ +GREY_EXPORT id grey_scrollViewContentOffset(CGPoint offset); + +/** Shorthand for GREYMatchers::matcherForStepperValue:. */ +GREY_EXPORT id grey_stepperValue(double value); + +/** Shorthand for GREYMatchers::matcherForSliderValueMatcher:. */ +GREY_EXPORT id grey_sliderValueMatcher(id valueMatcher); + +/** Shorthand for GREYMatchers::matcherForDatePickerValue:. */ +GREY_EXPORT id grey_datePickerValue(NSDate *date); + +/** Shorthand for GREYMatchers::matcherForPickerColumn:setToValue:. */ +GREY_EXPORT id grey_pickerColumnSetToValue(NSInteger column, + NSString * _Nullable value); + +/** Shorthand for GREYMatchers::matcherForEnabledElement. */ +GREY_EXPORT id grey_enabled(void); + +/** Shorthand for GREYMatchers::matcherForSelectedElement. */ +GREY_EXPORT id grey_selected(void); + +/** Shorthand for GREYMatchers::matcherForUserInteractionEnabled. */ +GREY_EXPORT id grey_userInteractionEnabled(void); + +/** Shorthand for GREYMatchers::matcherForConstraints:toReferenceElementMatching:. */ +GREY_EXPORT id grey_layout(NSArray *constraints, + id referenceElementMatcher); + +/** Shorthand for GREYMatchers::matcherForNil. */ +GREY_EXPORT id grey_nil(void); + +/** Shorthand for GREYMatchers::matcherForNotNil. */ +GREY_EXPORT id grey_notNil(void); + +/** Shorthand for GREYMatchers::matcherForSwitchWithOnState:. */ +GREY_EXPORT id grey_switchWithOnState(BOOL on); + +/** Shorthand for GREYMatchers::matcherForCloseTo:. */ +GREY_EXPORT id grey_closeTo(double value, double delta); + +/** Shorthand for GREYMatchers::matcherForAnything. */ +GREY_EXPORT id grey_anything(void); + +/** Shorthand for GREYMatchers::matcherForEqualTo:. */ +GREY_EXPORT id grey_equalTo(id value); + +/** Shorthand for GREYMatchers::matcherForLessThan:. */ +GREY_EXPORT id grey_lessThan(id value); + +/** Shorthand for GREYMatchers::matcherForGreaterThan:. */ +GREY_EXPORT id grey_greaterThan(id value); + +/** Shorthand for GREYMatchers::matcherForScrolledToContentEdge:. */ +GREY_EXPORT id grey_scrolledToContentEdge(GREYContentEdge edge); + +/** Shorthand for GREYMatchers::matcherForTextFieldValue:. */ +GREY_EXPORT id grey_textFieldValue(NSString *value); + +#endif // GREY_DISABLE_SHORTHAND + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYNSTimerIdlingResource.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYNSTimerIdlingResource.h new file mode 100644 index 0000000000..4b62155517 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYNSTimerIdlingResource.h @@ -0,0 +1,47 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * An idling resource to track NSTimer firing events so that the framework can synchronize + * with them. + */ +@interface GREYNSTimerIdlingResource : NSObject + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * Creates an idling resource that tracks the specified @c timer, causing actions to wait until + * the timer is fired or invalidated. If @c removeOnIdle is @c YES, the idling resource will + * automatically remove itself from the list of registered idling resources when it becomes idle. + * + * @param timer The timer that will be tracked by the idling resource. + * @param name A descriptive name for the idling resource. + * @param removeOnIdle Defines whether the resource should unregister itself when it becomes idle. + * + * @return A new and initialized GREYNSTimerIdlingResource instance. + */ ++ (instancetype)trackTimer:(NSTimer *)timer name:(NSString *)name removeOnIdle:(BOOL)removeOnIdle; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYNot.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYNot.h new file mode 100644 index 0000000000..43f4e61538 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYNot.h @@ -0,0 +1,50 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A matcher to negate the result of another matcher. + */ +@interface GREYNot : GREYBaseMatcher + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * Initializes this matcher with another @c matcher whose result is negated. + * + * @param matcher A matcher whose result will be negated. + * + * @return An instance of GREYNot, initialized with a matcher. + */ +- (instancetype)initWithMatcher:(id)matcher NS_DESIGNATED_INITIALIZER; + +#if !(GREY_DISABLE_SHORTHAND) + +/** Shorthand macro for GREYNot::initWithMatcher:. */ +GREY_EXPORT id grey_not(id matcher); + +#endif // GREY_DISABLE_SHORTHAND + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYOperationQueueIdlingResource.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYOperationQueueIdlingResource.h new file mode 100644 index 0000000000..43b3bfee69 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYOperationQueueIdlingResource.h @@ -0,0 +1,46 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Idling resource that monitors operation queues. + */ +@interface GREYOperationQueueIdlingResource : NSObject + +/** + * Creates an idling resource for monitoring @c queue for idleness. + * A queue is considered idle when it has no pending operations. + * A weak reference is held to @c queue. If @c queue is deallocated, then the idling resource will + * deregister itself from the UI thread executor. + * + * @param queue The queue that will be tracked by the resource. + * @param name A descriptive name for the idling resource. + * + * @return Returns an idling resource for the specified NSOperationQueue. + */ ++ (instancetype)resourceWithNSOperationQueue:(NSOperationQueue *)queue name:(NSString *)name; + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYProvider.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYProvider.h new file mode 100644 index 0000000000..cf94986d96 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYProvider.h @@ -0,0 +1,33 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A protocol for providing arbitrary data as an enumeration. + */ +@protocol GREYProvider + +/** + * @return A new enumerator that can be used to enumerate data backed by this provider. + */ +- (NSEnumerator *)dataEnumerator; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYScreenshotUtil.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYScreenshotUtil.h new file mode 100644 index 0000000000..90bb166100 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYScreenshotUtil.h @@ -0,0 +1,89 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Provides interfaces for taking screenshots of the entire screen and UI elements of the App. + */ +@interface GREYScreenshotUtil : NSObject + +/** + * Draws the application's main screen using the bitmap graphics context specified by the @c + * bitmapContextRef reference, centering it if the context size is different than the screen size. + * The provided reference must point to a CGBitmapContext. When @c afterUpdates is set to @c YES, + * this method waits for the screen to draw pending changes before taking a screenshot, otherwise + * the screenshot contains the current contents of the screen. + * + * @param bitmapContextRef Target bitmap context for rendering. + * @param afterUpdates Boolean indicating whether to render before (@c NO) or after (@c YES) + * screen updates. + */ ++ (void)drawScreenInContext:(CGContextRef)bitmapContextRef afterScreenUpdates:(BOOL)afterUpdates; + +/** + * @return An image of the current app's screen frame buffer. This method waits for any pending + * screen updates to go through before taking a screenshot. Returned image orientation is + * same as the current interface orientation. + */ ++ (UIImage *)takeScreenshot; + +/** + * @return The App Store and iTunes Connect friendly image of the current screen frame buffer. + */ ++ (UIImage *)takeScreenshotForAppStore; + +/** + * @return A snapshot of the provided @c element. @c element must be an instance of @c UIView or + * an accessibility element. + */ ++ (UIImage *)snapshotElement:(id)element; + +/** + * Saves the provided @c image as a PNG to the given @c filename under the given @c directoryPath. + * If the given directory path doesn't exist, it will be created. + * + * @param image The source image. + * @param filename The target file name. + * @param directoryPath The path to the directory where the image must be saved. + * + * @return The complete filepath and name of the saved image or @c nil on failure. + */ ++ (NSString *)saveImageAsPNG:(UIImage *)image + toFile:(NSString *)filename + inDirectory:(NSString *)directoryPath; + +@end + +/** + * Returns a new buffer that contains XRGB pixels for the provided @c imageRef i.e. the alpha + * channel is removed. If @c outBitmapContext is not @c NULL, it is set to the bitmap context of + * the returned buffer and caller must call CGContextRelease on it. Each pixel in returned buffer + * occupies 4 bytes and the buffer must be free()'d by the caller. + * + * @param imageRef The source image. + * @param[out] outBmpCtx Optional bitmap context that holds the returned buffer. + * + * @return A new buffer that contains XRGB pixels for the provided image. + */ +GREY_EXPORT unsigned char *_Nullable grey_createImagePixelDataFromCGImageRef( + CGImageRef imageRef, CGContextRef _Nullable *_Nullable outBmpCtx); + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYScrollActionError.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYScrollActionError.h new file mode 100644 index 0000000000..391ab19f10 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYScrollActionError.h @@ -0,0 +1,42 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import + +/** + * The Error domain for a scroll error. + */ +GREY_EXTERN NSString *const kGREYScrollErrorDomain; + +/** + * Error codes for scrolling related errors. + */ +typedef NS_ENUM(NSInteger, GREYScrollErrorCode) { + /** + * Reached content edge before the entire scroll action was complete. + */ + kGREYScrollReachedContentEdge, + /** + * It is not possible to scroll. + */ + kGREYScrollImpossible, + /** + * Could not scroll to the element we are looking for. + */ + kGREYScrollToElementFailed, +}; diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYSyncAPI.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYSyncAPI.h new file mode 100644 index 0000000000..87591f3772 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYSyncAPI.h @@ -0,0 +1,47 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import + +/** + * @file + * @brief Methods for executing sync or async blocks with EarlGrey operations. + */ + +NS_ASSUME_NONNULL_BEGIN + +/** + * Executes a block containing EarlGrey statements on the main thread and waits for it to + * complete. @c block is retained until execution completes. + * Important: Must be called from a non-main thread otherwise it will block main thread + * indefinitely. + * + * @param block Block that will be executed. + */ +GREY_EXPORT void grey_execute_sync(void (^block)(void)); + +/** + * Executes a block containing EarlGrey statements on the main thread without waiting for it to + * complete. @c block is retained until execution completes. + * Can be invoked safely from the main or non-main thread. + * + * @param block Block that will be executed. + */ +GREY_EXPORT void grey_execute_async(void (^block)(void)); + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYTestHelper.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYTestHelper.h new file mode 100644 index 0000000000..6f6b0a36f2 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYTestHelper.h @@ -0,0 +1,39 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Provides interface for test helper methods. + */ +@interface GREYTestHelper : NSObject + +/** + * Enables fast animation. Invoke in the XCTest setUp method to increase + * the speed of your tests by not having to wait on slow animations. + */ ++ (void)enableFastAnimation; + +/** + * Disables fast animation. + */ ++ (void)disableFastAnimation; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYUIThreadExecutor.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYUIThreadExecutor.h new file mode 100644 index 0000000000..d6fab7d016 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYUIThreadExecutor.h @@ -0,0 +1,139 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import + +/** + * @file + * @brief Header file for GREYUIThreadExecutor. + */ + +NS_ASSUME_NONNULL_BEGIN + +@protocol GREYIdlingResource; + +/** + * Error domain for thread executor failures. + */ +GREY_EXTERN NSString *const kGREYUIThreadExecutorErrorDomain; + +/** + * Error codes for thread executor failures. + */ +typedef NS_ENUM(NSInteger, GREYUIThreadExecutorErrorCode) { + /** + * Timeout reached before block could be executed. + */ + kGREYUIThreadExecutorTimeoutErrorCode, +}; + +/** + * Typedef for blocks that can be executed by the GREYUIThreadExecutor. + */ +typedef void(^GREYExecBlock)(void); + +/** + * Executor that syncs execution with the UI events on the main thread. + * Before executing a block or operation, it waits for any pending UI events to complete. + */ +@interface GREYUIThreadExecutor : NSObject + +/** + * @return The unique shared instance of the GREYUIThreadExecutor. + */ ++ (instancetype)sharedInstance; + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * Blocking call that drains the main runloop enough times to make each source gets a fair chance + * of service. No guarantee is made on whether the app is in kGREYIdle state after this method + * returns. + */ +- (void)drainOnce; + +/** + * Blocking call that drains the UI thread for the specified number of @c seconds. + * This method can block for longer than the specified time if any of the signalled sources take + * longer than that to execute. + * + * @param seconds Amount of time that the UI thread should be drained for, in seconds. + */ +- (void)drainForTime:(CFTimeInterval)seconds; + +/** + * Blocking call that drains the UI thread until both the UI and registered GREYIdlingResources + * are in idle. + * + * @remark Be very careful while calling this as you could end up in state where the caller expects + * the callee to mark the thread as idle and callee inadvertantly calls + * GREYUIThreadExecutor::drainUntilIdle:, in which case it will go into an infinite loop + * and the test will have to be force-killed by the test-runner. + */ +- (void)drainUntilIdle; + +/** + * Drains the UI thread and waits for both the UI and idling resources to idle until the given + * amount of @c seconds have passed, at which point, a timeout occurs and the method returns @c NO. + * Returns @c YES if idled within @c seconds, @c NO otherwise. + * + * @param seconds Amount of time to wait for the UI and idling resources to idle. + * + * @return @c YES if idled within @c seconds, @c NO otherwise. + */ +- (BOOL)drainUntilIdleWithTimeout:(CFTimeInterval)seconds; + +/** + * Invokes GREYUIThreadExecutor::executeSyncWithTimeout:block:error: with @c kGREYInfiniteTimeout, + * @c execBlock and @c error as the respective parameters. + * + * @param execBlock The block to be executed. + * @param errorOrNil Reference to the error that will store the failure cause, if any. + * + * @return @c YES if the block was executed, @c NO otherwise, in which case @c error will be set to + * the failure cause. + */ +- (BOOL)executeSync:(GREYExecBlock)execBlock + error:(__strong NSError *_Nullable *_Nullable)errorOrNil; + +/** + * Executes @c execBlock on the main thread, synchronizing with all registered GREYIdlingResources + * and UI events. If the UI thread or idling resources are not idle until @c seconds have elapsed, + * @c execBlock is not executed and error (if provided) is populated. + * + * @param seconds The timeout for waiting for the resources to idle, in seconds. + * A value of @c kGREYInfiniteTimeout indicates an infinite timeout. + * @param execBlock The block to be executed. + * @param errorOrNil Reference to the error that will store the failure cause, if any. + * + * @return @c YES if the block was executed, @c NO otherwise, in which case @c error will be set to + * the failure cause. + * + * @remark Blocks are executed in the order in which they were submitted. + * @remark This selector must be invoked on the main thread. + */ +- (BOOL)executeSyncWithTimeout:(CFTimeInterval)seconds + block:(_Nullable GREYExecBlock)execBlock + error:(__strong NSError *_Nullable *_Nullable)errorOrNil; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Info.plist b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Info.plist new file mode 100644 index 0000000000..025c0b1e6c Binary files /dev/null and b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Info.plist differ diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Modules/module.modulemap b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Modules/module.modulemap new file mode 100644 index 0000000000..feb892c9aa --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/Modules/module.modulemap @@ -0,0 +1,6 @@ +framework module EarlGrey { + umbrella header "EarlGrey.h" + + export * + module * { export * } +} diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/CAAnimation+GREYAdditions.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/CAAnimation+GREYAdditions.h new file mode 100644 index 0000000000..b59c62a333 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/CAAnimation+GREYAdditions.h @@ -0,0 +1,72 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +/** + * An enumeration of all states that EarlGrey identifies a CAAnimation to be in. + */ +typedef NS_ENUM(NSUInteger, GREYCAAnimationState) { + /** + * Default state every animation is in. + */ + kGREYAnimationPendingStart = 0, + /** + * State the animation is in when it begins. + */ + kGREYAnimationStarted, + /** + * State the animation is in when it ends. + */ + kGREYAnimationStopped, +}; + +NS_ASSUME_NONNULL_BEGIN + +/** + * EarlGrey specific addition for CAAnimation to track currently running animations. + */ +@interface CAAnimation (GREYAdditions) + +/** + * Sets the animation state to @c state. + * + * @param state The target state. + */ +- (void)grey_setAnimationState:(GREYCAAnimationState)state; + +/** + * Returns the current state of the animation. If CAAnimation::grey_setAnimationState was never + * called on this animation, @c kGREYANIMATION_PENDING_START is returned. + * + * @return The current state. + */ +- (GREYCAAnimationState)grey_animationState; + +/** + * Tracks the animation with GREYAppStateTracker until the expected animation runtime has elapsed, + * after which it untracks itself. + */ +- (void)grey_trackForDurationOfAnimation; + +/** + * Force untrack itself from GREYAppStateTracker, regardless of completion status. + */ +- (void)grey_untrack; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/CALayer+GREYAdditions.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/CALayer+GREYAdditions.h new file mode 100644 index 0000000000..93be60e62d --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/CALayer+GREYAdditions.h @@ -0,0 +1,23 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +/** + * EarlGrey specific additions to CALayer to track animations. + */ +@interface CALayer (GREYAdditions) +@end diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/CGGeometry+GREYAdditions.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/CGGeometry+GREYAdditions.h new file mode 100644 index 0000000000..5d26a41774 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/CGGeometry+GREYAdditions.h @@ -0,0 +1,220 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include +#import + +#pragma mark - Constants + +/** + * Value used to denote a null CGPoint. + */ +extern const CGPoint GREYCGPointNull; + +#pragma mark - CGVector + +/** + * @return The scalar length of @c vector. + */ +CGFloat CGVectorLength(CGVector vector); + +/** + * @return The the vector obtained by scaling the given @c vector by the given @c scale amount. + */ +CGVector CGVectorScale(CGVector vector, CGFloat scale); + +/** + * Creates a vector with the given end points and optionally normalizes it if @c normalize is + * @c YES. + * + * @param startPoint Start point for the vector. + * @param endPoint End point for the vector. + * @param normalize A @c BOOL indicating whether to normalize (@c YES) or not (@c NO). + * + * @return A vector with the given end points and optionally normalized if @c normalize is + * @c YES. + */ +CGVector CGVectorFromEndPoints(CGPoint startPoint, CGPoint endPoint, BOOL normalize); + +#pragma mark - CGPoint + +/** + * Adds the corresponding coordinates of the given @c vector and @c point and returns the result as + * a CGPoint. + * + * @param point The point to add. + * @param vector The vector to add. + * + * @return A point with corresponding coordinates of the given @c point and @c vector added. + */ +CGPoint CGPointAddVector(CGPoint point, CGVector vector); + +/** + * @return The center of the provided @c rect. + */ +CGPoint CGRectCenter(CGRect rect); + +/** + * Multiplies both the coordinates of the given @c inPoint by the given @c amount and returns + * the resulting point. + * + * @param inPoint The input point to multiply. + * @param amount The amount to multiply with. + * + * @return The point obtained by multiplying the given @c inPoint and the given @c amount. + */ +CGPoint CGPointMultiply(CGPoint inPoint, double amount); + +/** + * @return The point obtained by converting @c pointToConvertToPixel from points to pixels as per + * the screen scale. + */ +CGPoint CGPointToPixel(CGPoint positionInPoints); + +/** + * @return The point obtained by converting @c pixelToConvertToPoint from pixels to points as per + * the screen scale. + */ +CGPoint CGPixelToPoint(CGPoint positionInPixels); + +/** + * @return The point obtained after rounding the coordinates of the given @c cgpointInPoints to + * the nearest whole pixel and then to points. + */ +CGPoint CGPointAfterRemovingFractionalPixels(CGPoint cgpointInPoints); + +/** + * @return The point obtained by converting the given @c pointInFixed from fixed to variable + * coordinate system. + */ +CGPoint CGPointFixedToVariable(CGPoint pointInFixed); + +/** + * @return The point obtained by converting the given @c pointInVariable from variable to fixed + * coordinate system. + */ +CGPoint CGPointVariableToFixed(CGPoint pointInVariable); + +/** + * @return @c YES if the given @c point represents an null point, @c NO otherwise. + */ +BOOL CGPointIsNull(CGPoint point); + +#pragma mark - CGFloat + +/** + * @return The value obtained by rounding the given @c floatInPoints to the nearest whole pixel + * and converting it to points as per the screen scale. + */ +CGFloat CGFloatAfterRemovingFractionalPixels(CGFloat floatInPoints); + +#pragma mark - CGRect + +/** + * @return The area of the given @c rect. + */ +double CGRectArea(CGRect rect); + +/** + * Scales the given rectangle @c inRect, by a factor of the given @c amount and then translates + * the origin by a factor of @c amount. This is same as multiplying x, y, width and height of the + * given rectangle by the given @c amount. + * + * @param inRect The rectangle to be scaled and translated. + * @param amount The amount by which to scale (and the factor by which to translate). + * + * @return The scaled and translated rectangle. + */ +CGRect CGRectScaleAndTranslate(CGRect inRect, double amount); + +/** + * @return The rect obtained by converting the given @c rectInPoints from points to pixels as per + * the screen scale. + */ +CGRect CGRectPointToPixel(CGRect rectInPoints); + +/** + * @return The rect obtained by converting the given @c rectInPoints from pixels to points as + * per the screen scale. + */ +CGRect CGRectPixelToPoint(CGRect rectInPixel); + +/** + * Starting with iOS 8.0 window and screen coordinates rotates with the the app's interface + * orientation. This method converts the given rect in fixed coordinate space to an oriented rect + * matching the current app orientation. + * + * @param rectInFixedCoordinates The rect in fixed coordinates to be transformed to variable + * coordinates. + * + * @return The rect obtained by converting the given @c rectInFixedCoordinates from fixed screen + * coordinates to variable screen coordinates. + */ +CGRect CGRectFixedToVariableScreenCoordinates(CGRect rectInFixedCoordinates); + +/** + * Starting with iOS 8.0 window and screen coordinates rotates with the the app's interface + * orientation. This method converts the given rect in variable coordinate space to fixed + * coordinates. + * + * @param rectInVariableCoordinates The rect in variable coordinates to be transformed to fixed + * coordinates. + * + * @return The rect obtained by converting the given @c rectInVariableCoordinates from variable + * screen coordinates to fixed screen coordinates. + */ +CGRect CGRectVariableToFixedScreenCoordinates(CGRect rectInVariableCoordinates); + +/** + * Return the intersection of @c rect1 and @c rect2. The built-in function can produce floating + * errors on 32-bit platform (i.e. iphone 5), which results in a bigger rectangle than both + * sources. This will remove the errors by forcing the resulting rectangle to be no greater than + * the sources. + * + * @param rect1 The first source rectangle. + * @param rect2 The second source rectangle. + * + * @return A rectangle that represents the intersection of the two specified rectangles. If the two + * rectangles do not intersect, returns the null rectangle. To check for this condition, + * use CGRectIsNull. + */ +CGRect CGRectIntersectionStrict(CGRect rect1, CGRect rect2); + +/** + * Normalizes @c rectInPixels to the largest rectangle that is within rectInPixels and + * pixel-boundary aligned. If the fractional part of height or width are > 0.5, they are rounded up + * otherwise rounded down. + * + * @param rectInPixels A rect in pixel coordinates. + * + * @return The normalized rect. + */ +CGRect CGRectIntegralInside(CGRect rectInPixels); + +#pragma mark - CGAffineTransform + +/** + * Returns the transform required for transforming from fixed coordinate system (iOS 7 and below) + * to variable coordinate system. + * + * @remark This method is only applicable on iOS 7 and below as the later OSes use variable + * coordinate system by default. + * + * @param statusBarOrientation A status bar orientation in fixed coordinate system. + * + * @return The transformed status bar orientation for variable coordinate system. + */ +CGAffineTransform CGAffineTransformForFixedToVariable(UIInterfaceOrientation statusBarOrientation); diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYActions+Internal.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYActions+Internal.h new file mode 100644 index 0000000000..5607f0886e --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYActions+Internal.h @@ -0,0 +1,46 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file GREYActions+Internal.h + * @brief Exposes GREYActions' interfaces and methods that are otherwise private for + * testing purposes. + */ + +NS_ASSUME_NONNULL_BEGIN + +@interface GREYActions (Internal) + +/** + * Use the iOS keyboard to type a string starting from the provided UITextPosition. If the + * position is @c nil, then type text from the text input's current position. Should only be called + * with a position if element conforms to the UITextInput protocol - which it should if you + * derived the UITextPosition from the element. + * + * @param text The text to be typed. + * @param position The position in the text field at which the text is to be typed. + * + * @return @c YES if the action succeeded, else @c NO. If an action returns @c NO, it does not + * mean that the action was not performed at all but somewhere during the action execution + * the error occured and so the UI may be in an unrecoverable state. + * + * @remark This is available only for internal testing purposes. + */ ++ (id)grey_actionForTypeText:(NSString *)text + atUITextPosition:(UITextPosition *)position; +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYAnalytics.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYAnalytics.h new file mode 100644 index 0000000000..9dca03722d --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYAnalytics.h @@ -0,0 +1,75 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +@protocol GREYAnalyticsDelegate; + +NS_ASSUME_NONNULL_BEGIN + +/** + * Provides methods for tracking EarlGrey usage using Google Analytics. + * + * @remark To opt out of Analytics use GREYConfiguration and set config value for + * @c kGREYConfigKeyAnalyticsEnabled to @c NO before the instance tear down method + * XCTestCase::tearDown method returns. Sample code to opt out of analytics: + * @code + * [[GREYConfiguration sharedInstance] setValue:@(NO) + * forConfigKey:kGREYConfigKeyAnalyticsEnabled]; + * @endcode + */ +@interface GREYAnalytics : NSObject + +/** + * @return The singleton instance. + */ ++ (instancetype)sharedInstance; + +/** + * @return The current delegate. + */ +- (id)delegate; + +/** + * Sets a delegate for custom handling of analytics payload data. To reset GREYAnalytics to its + * default behavior pass @c nil. + */ +- (void)setDelegate:(id)delegate; + +/** + * Called when an EarlGrey invocation occurs using any @code [EarlGrey XXX] @endcode statements. + */ +- (void)didInvokeEarlGrey; + +/** + * Sends an Analytics Event hit based on protocol specified in: + * @see https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide#event + * + * @param trackingID The tracking ID under which to track this event. + * @param clientID The ID for the user sending this event. + * @param category The Event Category for the event hit. + * @param action The Event Action for the event hit. + * @param value The event value for the event hit. + */ ++ (void)sendEventHitWithTrackingID:(NSString *)trackingID + clientID:(NSString *)clientID + category:(NSString *)category + action:(NSString *)action + value:(NSString *)value; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYAnalyticsDelegate.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYAnalyticsDelegate.h new file mode 100644 index 0000000000..5aa03f366b --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYAnalyticsDelegate.h @@ -0,0 +1,43 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@protocol GREYAnalyticsDelegate + +/** + * Sent to the delegate to handle Analytics Event hit. See this for more info: + * https://developers.google.com/analytics/devguides/collection/protocol/v1/. + * + * @note In case of failure to track the method must fail silently to prevent test interruption. + * + * @param trackingID The tracking ID under which to track this event. + * @param clientID The ID for the user sending this event. + * @param category The Event Category for the event hit. + * @param action The Event Action for the event hit. + * @param value The event value for the event hit. + */ +- (void)trackEventWithTrackingID:(NSString *)trackingID + clientID:(NSString *)clientID + category:(NSString *)category + action:(NSString *)action + value:(NSString *)value; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYAppStateTracker.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYAppStateTracker.h new file mode 100644 index 0000000000..8c9efa837a --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYAppStateTracker.h @@ -0,0 +1,186 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import + +@class GREYAppStateTrackerObject; + +NS_ASSUME_NONNULL_BEGIN + +/** + * @file + * @brief App state tracker header file. + */ + +/** + * Non-idle states that the App can be at any given point in time. + * These states are not mutually exclusive and can be combined together using Bitwise-OR to + * represent multiple states. + */ +typedef NS_OPTIONS(NSUInteger, GREYAppState) { + /** + * Idle state implies App is not undergoing any state changes and it is OK to interact with it. + */ + kGREYIdle = 0, + /** + * View is pending draw or layout pass. + */ + kGREYPendingDrawLayoutPass = (1UL << 0), + /** + * Waiting for viewDidAppear: method invocation. + */ + kGREYPendingViewsToAppear = (1UL << 1), + /** + * Waiting for viewDidDisappear: method invocation. + */ + kGREYPendingViewsToDisappear = (1UL << 2), + /** + * Pending keyboard transition. + */ + kGREYPendingKeyboardTransition = (1UL << 3), + /** + * Waiting for CA animation to complete. + */ + kGREYPendingCAAnimation = (1UL << 4), + /** + * Waiting for a UIAnimation to be marked as stopped. + */ + kGREYPendingUIAnimation = (1UL << 5), + /** + * Pending root view controller to be set. + */ + kGREYPendingRootViewControllerToAppear = (1UL << 6), + /** + * Pending a UIWebView async load request + */ + kGREYPendingUIWebViewAsyncRequest = (1UL << 7), + /** + * Pending a network request completion. + */ + kGREYPendingNetworkRequest = (1UL << 8), + /** + * Pending gesture recognition. + */ + kGREYPendingGestureRecognition = (1UL << 9), + /** + * Waiting for UIScrollView to finish scrolling. + */ + kGREYPendingUIScrollViewScrolling = (1UL << 10), + /** + * [UIApplication beginIgnoringInteractionEvents] was called and all interaction events are + * being ignored. + */ + kGREYIgnoringSystemWideUserInteraction = (1UL << 11), +}; + +/** + * Idling resource that tracks the application state. + */ +@interface GREYAppStateTracker : NSObject + +/** + * @return The unique shared instance of the GREYAppStateTracker. + */ ++ (instancetype)sharedInstance; + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * @return The state that the App is in currently. + */ +- (GREYAppState)currentState; + +/** + * Updates the state of the object, including the provided @c state and updating the overall state + * of the application. If @c object is already being tracked with for a different state, the + * object's state will be updated to a XOR of the current state and @c state. + * + * @param state The state that should be tracked for the object. + * @param object The object that should have its tracked state updated. + * + * @return The GREYAppStateTracker that was assigned to the object by the state tracker, or @c nil + * if @c object is @c nil. Future calls for the same object will return the same + * identifier until the object is untracked. + */ +- (GREYAppStateTrackerObject * _Nullable)trackState:(GREYAppState)state forObject:(id)object; + +/** + * Untracks the state for the object with the specified id. For untracking, it does not matter + * if the state has been added to being ignored. + * + * @param state The state that should be untracked. + * @param object The GREYAppStateTrackerObject associated with the object whose state should be + * untracked. + */ +- (void)untrackState:(GREYAppState)state forObject:(GREYAppStateTrackerObject *)object; + +/** + * Ignore any state changes made to the state(s) provided. To stop ignoring a state, set this + * to a @c GREYAppState value that does not contain that particular state or use + * @c GREYAppStateTracker::clearIgnoredStates. + * + * @remark This will not retroactively affect any currently tracked objects with the ignored app + * state(s). This only ensures that any further tracking of an object with an app state + * that is being ignored will be ignored. Untracking is not affected by this method. + * + * @param state The app state that should be ignored. This can be a bitwise-OR of multiple + * app states. + */ +- (void)ignoreChangesToState:(GREYAppState)state; + +/** + * Removes any states that were being ignored. + */ +- (void)clearIgnoredStates; + +/** + * Clears all states that are tracked by the GREYAppStateTracker singleton. + * + * @remark This is available only for internal testing purposes. + */ +- (void)grey_clearState; + +@end + +/** + * Utility macro for tracking the state of an object. + * + * @param state The state that should be tracked for the object. + * @param object The object that should have its tracked state updated. + * + * @return The GREYAppStateTracker that was assigned to the object by the state tracker, or @c nil + * if @c object is @c nil. Future calls for the same object will return the same + * identifier until the object is untracked. + */ +#define TRACK_STATE_FOR_OBJECT(state_, object_) \ + [[GREYAppStateTracker sharedInstance] trackState:(state_) forObject:(object_)] + +/** + * Utility macro for untracking the state of an object. + * + * @param state The state that should be untracked. + * @param object The GREYAppStateTrackerObject associated with the object whose state should be + * untracked. + */ +#define UNTRACK_STATE_FOR_OBJECT(state_, object_) \ + [[GREYAppStateTracker sharedInstance] untrackState:(state_) forObject:(object_)] + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYAppStateTrackerObject.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYAppStateTrackerObject.h new file mode 100644 index 0000000000..b69628cbdd --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYAppStateTrackerObject.h @@ -0,0 +1,67 @@ +// +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import "Synchronization/GREYAppStateTracker.h" + +NS_ASSUME_NONNULL_BEGIN + +@class GREYObjectDeallocationTracker; + +/** + * Class used by the GREYAppStateTracker for synchronization purposes. + */ +@interface GREYAppStateTrackerObject : NSObject + +/** + * Initializing the GREYAppStateTrackerObject. + * + * @param deallocationTracker The object that will be pointed to using a weak reference. + * + * @return An instance of GREYAppStateTrackerObject. + */ +- (instancetype)initWithDeallocationTracker:(GREYObjectDeallocationTracker *)deallocationTracker; + +/** + * @remark init is not an available initializer. Use the other initializer. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * @c object is an instance of GREYObjectDeallocatingTracker aka the internal object. The + * GREYAppStateTrackerObject holds weakly to the GREYObjectDeallocatingTracker object. + */ +@property(nonatomic, readonly, weak) GREYObjectDeallocationTracker *object; + +/** + * The state that this object is tracking. + */ +@property(nonatomic, assign) GREYAppState state; + +/** + * The description of the object that is being represented by GREYAppStateTrackerObject. + */ +@property(nonatomic, strong) NSString *objectDescription; + +/** + * @return The callstack that was set when a new state @c state was set. + */ +- (NSArray *)stateAssignmentCallStack; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYAppleInternals.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYAppleInternals.h new file mode 100644 index 0000000000..ecdf10d4cf --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYAppleInternals.h @@ -0,0 +1,423 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file GREYAppleInternals.h + * @brief Exposes interfaces, structs and methods that are otherwise private. + */ + +#import + +@interface UIWindow (GREYExposed) +- (id)firstResponder; +@end + +@interface UIViewController (GREYExposed) +- (void)viewWillMoveToWindow:(id)window; +- (void)viewDidMoveToWindow:(id)window shouldAppearOrDisappear:(BOOL)arg; +@end + +/** + * Structure that represents IOHIDEvents, which are sent from iOS to the application. + */ +typedef struct __IOHIDEvent *IOHIDEventRef; + +/** + * Private class source: + * http://www.opensource.apple.com/source/IOHIDFamily/IOHIDFamily-503.92.1/IOHIDFamily/IOHIDEventTypes.h + */ +#ifdef __LP64__ +typedef double IOHIDFloat; +#else +typedef float IOHIDFloat; +#endif + +typedef UInt32 IOOptionBits; + +/** + * Event mask detailing the events being dispatched by a digitizer. It is possible for digitizer + * events to contain child digitizer events, effectively, behaving as collections. In the + * collection case, the child event mask field referrence by + * kIOHIDEventFieldDigitizerChildEventMask will detail the cumulative event state of the child + * digitizer events. If you append a child digitizer event to a parent digitizer event, appropriate + * state will be transferred on to the parent. + */ +typedef enum { + /** + * Issued when the range state has changed. + */ + kIOHIDDigitizerEventRange = 0x00000001, + /** + * Issued when the touch state has changed. + */ + kIOHIDDigitizerEventTouch = 0x00000002, + /** + * Issued when the position has changed. + */ + kIOHIDDigitizerEventPosition = 0x00000004, +} IOHIDDigitizerEventMask; + +/** + * Creates a digitizer event that sourced from a finger touching the screen. + */ +IOHIDEventRef IOHIDEventCreateDigitizerFingerEvent(CFAllocatorRef allocator, + AbsoluteTime timeStamp, + uint32_t index, + uint32_t identity, + IOHIDDigitizerEventMask eventMask, + IOHIDFloat x, + IOHIDFloat y, + IOHIDFloat z, + IOHIDFloat tipPressure, + IOHIDFloat twist, + Boolean range, + Boolean touch, + IOOptionBits options); + +/** + * Private class for representing internal touch events. + * @see + * https://github.com/nst/iOS-Runtime-Headers/blob/master/Frameworks/UIKit.framework/UIInternalEvent.h + */ +@interface UIInternalEvent : UIEvent +/** + * Sets HIDEvent property for the event. + * + * @param event The event for HIDEvent property. + */ +- (void)_setHIDEvent:(IOHIDEventRef)event; +@end + +/** + * A private class that represents touch related events. This is sent to UIApplication whenever a + * touch occurs. + */ +@interface UITouchesEvent : UIInternalEvent +/** + * Adds a @c touch to the event. It's unclear what @c delayedDelivery does. + * + * @param touch The touch object to be added. + * @param delayedDelivery Unknown private API param. + */ +- (void)_addTouch:(UITouch *)touch forDelayedDelivery:(BOOL)delayedDelivery; + +/** + * Removes all touch objects from the event. + */ +- (void)_clearTouches; +@end + +/** + * A private class that represents backboard services accelerometer. + */ +@interface BKSAccelerometer : NSObject +/** + * Enable or disable accelerometer events. + */ +@property(nonatomic) BOOL accelerometerEventsEnabled; +@end + +/** + * A private class that represents motion related events. This is sent to UIApplication whenever a + * motion occurs. + */ +@interface UIMotionEvent : NSObject { + // The motion accelerometer of the event. + BKSAccelerometer *_motionAccelerometer; +} +@end + +@interface UIApplication (GREYExposed) +- (BOOL)_isSpringBoardShowingAnAlert; +- (UIWindow *)statusBarWindow; +/** + * Changes the main runloop to run in the specified mode, pushing it to the top of the stack of + * current modes. + */ +- (void)pushRunLoopMode:(NSString *)mode; +/** + * Changes the main runloop to run in the specified mode, pushing it to the top of the stack of + * current modes. + */ +- (void)pushRunLoopMode:(NSString *)mode requester:(id)requester; +/** + * Pops topmost mode from the runloop mode stack. + */ +- (void)popRunLoopMode:(NSString *)mode; +/** + * Pops topmost mode from the runloop mode stack. + */ +- (void)popRunLoopMode:(NSString *)mode requester:(id)requester; +/** + * @return The shared UITouchesEvent object of the application, which is used to keep track of + * UITouch objects, and the relevant touch interaction state. + */ +- (UITouchesEvent *)_touchesEvent; +/** + * @return The shared UIMotionEvent object of the application, used to force enable motion + * accelerometer events. + */ +- (UIMotionEvent *)_motionEvent; + +/** + * Sends a motion began event for the specified subtype. + */ +- (void)_sendMotionBegan:(UIEventSubtype)subtype; + +/** + * Sends a motion ended event for the specified subtype. + */ +- (void)_sendMotionEnded:(UIEventSubtype)subtype; +@end + +@interface UIScrollView (GREYExposed) +/** + * Called when user finishes scrolling the content. @c deceleration is @c YES if scrolling movement + * will continue, but decelerate, after user stopped dragging the content. If @c deceleration is + * @c NO, scrolling stops immediately. + * + * @param deceleration Indicating if scrollview was experiencing deceleration. + */ +- (void)_scrollViewDidEndDraggingWithDeceleration:(BOOL)deceleration; + +/** + * Called when user is about to begin scrolling the content. + */ +- (void)_scrollViewWillBeginDragging; + +/** + * Called when scrolling of content has finished, if content continued scrolling with deceleration + * after user stopped dragging it. @c notify determines whether UIScrollViewDelegate will be + * notified that scrolling has finished. + * + * @param notify An indicator specifiying if scrolling has finished. + */ +- (void)_stopScrollDecelerationNotify:(BOOL)notify; +@end + +@interface UIDevice (GREYExposed) +- (void)setOrientation:(UIDeviceOrientation)orientation animated:(BOOL)animated; +@end + +@interface UITouch (GREYExposed) +/** + * Sets flag marking this touch as the first touch for view. + * + * @param first A boolean to indicate if this is the first touch for the view. + */ +- (void)_setIsFirstTouchForView:(BOOL)first; + +/** + * Sets flag marking this touch as a tap. + * + * @param isTap A boolean to indicate that this is a tap. + */ +- (void)setIsTap:(BOOL)isTap; + +/** + * Sets location property to @c location. If @c reset is @c NO, the original value of location will + * be stored in the UITouch's internal property @c previousLocation. If @c reset is @c YES, @c + * location will be stored in @c previousLocation. + * + * @param location The new location relative to the touch's window. + * @param reset An indicator to specify if @c previousLocation must be reset. + */ +- (void)_setLocationInWindow:(CGPoint)location resetPrevious:(BOOL)reset; + +/** + * Sets phase property and notifies phaseChangeDelegate. + * + * @param phase The new phase property. + */ +- (void)setPhase:(UITouchPhase)phase; + +/** + * Sets tapCount property. + * + * @param tapCount The new tap count. + */ +- (void)setTapCount:(NSUInteger)tapCount; + +/** + * Sets timestamp property. + * + * @param timestamp The new timestamp. + */ +- (void)setTimestamp:(NSTimeInterval)timestamp; + +/** + * Sets view property. + * + * @param view The new view property. + */ +- (void)setView:(UIView *)view; + +/** + * Sets window property and converts stored CGPoint structs to the the window's coordinate system. + * + * @param window The new window property. + */ +- (void)setWindow:(UIWindow *)window; + +/** + * Sets HIDEvent property for this touch. + * + * @param event The new HIDEvent property. + */ +- (void)_setHidEvent:(IOHIDEventRef)event; +@end + +@interface UIKeyboardTaskQueue +/** + * Completes all pending or ongoing tasks in the task queue before returning. Must be called from + * the main thread. + */ +- (void)waitUntilAllTasksAreFinished; +@end + +@interface UIKeyboardImpl +/** + * @return Shared instance of UIKeyboardImpl. It may be different from the active instance. + */ ++ (instancetype)sharedInstance; + +/** + * @return The Active instance of UIKeyboardImpl, if one exists; otherwise returns @c nil. Active + * instance could exist even if the keyboard is not shown on the screen. + */ ++ (instancetype)activeInstance; + +/** + * @return The current keyboard layout view, which contains accessibility elements for keyboard + * keys that are shown on the keyboard. + */ +- (UIView *)_layout; + +/** + * @return The string shown on the return key on the keyboard. + */ +- (NSString *)returnKeyDisplayName; + +/** + * @return The task queue keyboard is using to manage asynchronous tasks. + */ +- (UIKeyboardTaskQueue *)taskQueue; + +/** + * Automatically hides the software keyboard if @c enabled is set to @c YES and hardware keyboard + * is available. Setting @c enabled to @c NO will always show software keyboard. This setting is + * global and applies to all instances of UIKeyboardImpl. + * + * @param enabled A boolean that indicates automatic minimization (hiding) of the keyboard. + */ +- (void)setAutomaticMinimizationEnabled:(BOOL)enabled; + +/** + * @return The delegate that the UIKeyboard is typing on. + */ +- (id)delegate; + +/** + * Sets the current UIKeyboard's delegate. + * + * @param delegate The element to set the UIKeyboard's delegate to. + */ +- (void)setDelegate:(id)delegate; +/** + * A method to hide the keyboard without resigning the first responder. This is used only + * in iOS 8.1 where we found that turning off the autocorrection type on the first responder + * using setAutomaticMinimizationEnabled: without toggling the keyboard caused keyboard touches + * to be ignored. + */ +- (void)hideKeyboard; + +/** + * A method to show the keyboard without resigning the first responder. This is used only + * in iOS 8.1 where we found that turning off the autocorrection type on the first responder + * using setAutomaticMinimizationEnabled: without toggling the keyboard caused keyboard touches + * to be ignored. + */ +- (void)showKeyboard; +@end + +/** + * Text Input preferences controller to modify the keyboard preferences for iOS 8+. + */ +@interface TIPreferencesController : NSObject + +/** Whether the autocorrection is enabled. */ +@property BOOL autocorrectionEnabled; + +/** Whether the predication is enabled. */ +@property BOOL predictionEnabled; + +/** The shared singleton instance. */ ++ (instancetype)sharedPreferencesController; + +/** Synchronize the change to save it on disk. */ +- (void)synchronizePreferences; + +/** Modify the preference @c value by @c key. */ +- (void)setValue:(NSValue *)value forPreferenceKey:(NSString *)key; +@end + +/** + * Used for enabling accessibility on simulator and device. + */ +@interface AXBackBoardServer + +/** + * Returns backboard server instance. + */ ++ (id)server; + +/** + * Sets preference with @c key to @c value and raises @c notification. + */ +- (void)setAccessibilityPreferenceAsMobile:(CFStringRef)key + value:(CFBooleanRef)value + notification:(CFStringRef)notification; + +@end + +/** + * Used for enabling accessibility on device. + */ +@interface XCAXClient_iOS + +/** + * Singleton shared instance when initialized will try to background the current process. + */ ++ (id)sharedClient; + +/** + * Programatically enable accessibility on both simulator and device. + * Blocks until accessibility is fully loaded. + * + * @return ignored. + */ +- (bool)_loadAccessibility:(void **)unused; + +@end + +@interface UIAccessibilityTextFieldElement + +/** + * @return The UITextField that contains the accessibility text field element. + */ +-(UITextField *)textField; + +@end diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYAssertions+Internal.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYAssertions+Internal.h new file mode 100644 index 0000000000..3fd2d23a59 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYAssertions+Internal.h @@ -0,0 +1,55 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file GREYAssertions+Internal.h + * @brief Exposes GREYAssertions' interfaces and methods that are otherwise private for + * testing purposes. + */ + +#import + +@class GREYError; +@protocol GREYAssertion; +@protocol GREYMatcher; + +@interface GREYAssertions (Internal) + +/** + * Raise a @c GREYFrameworkException with the provided @c name, @c details and @c error. + * + * @param name The name of the exception. + * @param details The details of the exception. + * @param error The error that is the major reason of the exception. + * + * @remark This is available only for internal usage purposes. + */ ++ (void)grey_raiseExceptionNamed:(NSString *)name + exceptionDetails:(NSString *)details + withError:(GREYError *)error; + +/** +* Create a @c GREYAssertion with the provided @c matcher to check assertions on elements. +* +* @param matcher The @c GREYMatcher object to be matched by the assertion. +* +* @return A @c GREYAssertion object that can be used to match an object with the provided @c matcher. +* +* @remark This is available only for internal testing purposes. +*/ ++ (id)grey_createAssertionWithMatcher:(id)matcher; + +@end diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYCAAnimationDelegate.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYCAAnimationDelegate.h new file mode 100644 index 0000000000..cc151dc0fa --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYCAAnimationDelegate.h @@ -0,0 +1,46 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface GREYCAAnimationDelegate : NSObject + +/** + * Wraps the passed in CAAnimationDelegate in a GREYSurrogateDelegate for helping in tracking + * the delegate's animation start and stop events for better synchronization. + * + * @param delegate The CAAnimationDelegate animation delegate that is to be swizzled. + * + * @return An NSObject conforming to CAAnimationDelegate. + */ ++ (instancetype)surrogateDelegateForDelegate:(id)delegate; + +/** + * @remark init is not an available initializer. Use surrogateDelegateForDelegate. + */ +- (instancetype)init NS_UNAVAILABLE; + +#pragma mark - CAAnimationDelegate + +- (void)animationDidStart:(CAAnimation *)animation; +- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)finished; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYChangeStepperAction.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYChangeStepperAction.h new file mode 100644 index 0000000000..05bdd9e55a --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYChangeStepperAction.h @@ -0,0 +1,49 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Actions for manipulating UIStepper. + */ +@interface GREYChangeStepperAction : GREYBaseAction + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * @remark initWithName::constraints: is overridden from its superclass. + */ +- (instancetype)initWithName:(NSString *)name + constraints:(id)constraints NS_UNAVAILABLE; + +/** + * Initializes with the expected value by which to change the stepper. + * + * @param value The amount by which the stepper should change. + * + * @return An instance of GREYChangeStepperAction. + */ +- (instancetype)initWithValue:(double)value NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END + diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYDispatchQueueTracker.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYDispatchQueueTracker.h new file mode 100644 index 0000000000..d0f569c3ff --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYDispatchQueueTracker.h @@ -0,0 +1,76 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A dispatch queue tracker for tracking dispatch queues. + * + * At most one tracker exists for each dispatch queue. The tracker will continue tracking the + * dispatch queue until the tracker or the tracker's underlying queue has been deallocated. + */ +@interface GREYDispatchQueueTracker : NSObject + +/** + * Returns a tracker tracking @c queue. Creates a tracker only if one does not already exist. + * + * The tracked queue is held weakly so that it can be deallocated normally. The tracker will track + * the busy state of "zombie" queues that have been released by all external references but still + * have enqueued tasks that hold references to the queue. + * + * @param queue The queue that the returned tracker should be tracking. + * + * @return A tracker tracking @c queue. + */ ++ (instancetype)trackerForDispatchQueue:(dispatch_queue_t)queue; + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * Check for the idle state of the tracked dispatch queue. + * + * The tracked dispatch queue is considered busy if a tracked operation has not yet completed. + * @c dispatch_sync blocks and dispatch_sync_f tasks sent to @c queue are tracked. + * @c dispatch_async blocks and @c dispatch_async_f tasks sent to @c queue are tracked. + * @c dispatch_after blocks and @c dispatch_after_f tasks sent to @c queue are tracked if they are + * delayed no more than the delay amount set for the + * @c kGREYConfigKeyTrackableDispatchAfterDuration configuration. + * + * @return @c YES if the dispatch queue being tracked is idle, @c NO otherwise. + */ +- (BOOL)isIdleNow; + +/** + * Check if the tracked queue still has external references. + * + * After all external references to a queue have been dropped, asynchronous tasks on the dispatch + * queue will still complete and the tracker will still report that it is busy until those tasks + * have completed. When the queue is only kept active by enqueued blocks, it is considered to be a + * zombie queue and not a live queue. + * + * @return @c YES if the dispatch queue being tracked no longer has external references, @c NO + * otherwise. + */ +- (BOOL)isTrackingALiveQueue; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYElementInteraction+Internal.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYElementInteraction+Internal.h new file mode 100644 index 0000000000..b0d03372f1 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYElementInteraction+Internal.h @@ -0,0 +1,49 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file GREYElementInteraction+Internal.h + * @brief Exposes GREYElementInteraction's interfaces and methods that are otherwise private for + * testing purposes. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface GREYElementInteraction (Internal) + +/** + * Searches for UI elements within the root views and returns all matched UI elements. The given + * search action is performed until an element is found. + * + * @param timeout The amount of time during which search actions must be performed to find an + * element. + * @param error The error populated on failure. If an element was found and returned when using + * the search actions then any action or timeout errors that happened in the + * previous search are ignored. However, if an element is not found, the error + * will be propagated. + * + * @return An array of matched UI elements in the data source. If no UI element is found in + * @c timeout seconds, a timeout error will be produced and no UI element will be returned. + * + * @remark This is available only for internal testing purposes. + */ +- (NSArray *)matchedElementsWithTimeout:(NSTimeInterval)timeout error:(__strong NSError **)error; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYElementProvider.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYElementProvider.h new file mode 100644 index 0000000000..1003de1d45 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYElementProvider.h @@ -0,0 +1,116 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A provider for UI elements. + */ +@interface GREYElementProvider : NSObject + +/** + * Class method to initialize this provider with the specified @c elements. + * + * @param elements An array of elements that the provider is populated with. + * + * @return An instance of GREYElementProvider populated with @c elements. + */ ++ (instancetype)providerWithElements:(NSArray *)elements; + +/** + * Class method to initialize this provider with the specified @c rootElements. + * + * @param rootElements An array of root elements whose entire hierarchy will populate the provider. + * + * @return An instance of GREYElementProvider with root elements set to @c rootElements. + */ ++ (instancetype)providerWithRootElements:(NSArray *)rootElements; + +/** + * Class method to initialize this provider with the specified @c rootProvider. + * + * @param rootProvider A provider for root elements. The root elements and their entire hierarchy + * will populate the current provider. + * + * @return An instance of GREYElementProvider with root elements set root elements in the root + * provider and their entire hierarchy. + */ ++ (instancetype)providerWithRootProvider:(id)rootProvider; + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * Initializes this provider with the specified @c elements. + * + * @param elements Elements to populate the provider with. + * + * @return An instance of GREYElementProvider populated with @c elements. + */ +- (instancetype)initWithElements:(NSArray *)elements; + +/** + * Initializes this provider with the specified @c rootElements. + * + * @param rootElements An array of root elements whose entire hierarchy will populate the provider. + * + * @return An instance of GREYElementProvider with root elements set to @c rootElements. + */ +- (instancetype)initWithRootElements:(NSArray *)rootElements; + +/** + * Initializes this provider with the specified @c rootProvider. + * + * @param rootProvider A provider for root elements. The root elements and their entire hierarchy + * will populate the current provider. + * + * @return An instance of GREYElementProvider with root elements set root elements in the root + * provider and their entire hierarchy. + */ +- (instancetype)initWithRootProvider:(id)rootProvider; + +/** + * Designated Initializer. Must provide exactly one @c non-nil parameter out of + * all the accepted parameters. + * + * @param rootProvider A provider for root elements. The root elements and their entire hierarchy + * will populate the current provider. + * @param rootElements An array of root elements whose entire hierarchy will populate the provider. + * @param elements An array of elements that will populate the provider. + * + * @return A GREYElementProviderInstance, initialized with at least one of the specified + * parameters. + */ +- (instancetype)initWithRootProvider:(id _Nullable)rootProvider + orRootElements:(NSArray *_Nullable)rootElements + orElements:(NSArray *_Nullable)elements NS_DESIGNATED_INITIALIZER; + +#pragma mark - GREYProvider + +/** + * @return An enumerator for the elements in the provider. + */ +- (NSEnumerator *)dataEnumerator; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYError+Internal.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYError+Internal.h new file mode 100644 index 0000000000..ecc085cfef --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYError+Internal.h @@ -0,0 +1,120 @@ + +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file GREYError+Internal.h + * @brief Exposes GREYError's interfaces and methods that are otherwise private for + * testing purposes. + */ + +#import "Common/GREYError.h" + +@class XCTestCase; + +NS_ASSUME_NONNULL_BEGIN + +/** + * Key used to retrieve the error test case class name from an error object dictionary. + */ +GREY_EXTERN NSString *const kErrorTestCaseClassNameKey; + +/** + * Key used to retrieve the test case method name from an error object dictionary. + */ +GREY_EXTERN NSString *const kErrorTestCaseMethodNameKey; + +/** + * Key used to retrieve the file path from an error object dictionary. + */ +GREY_EXTERN NSString *const kErrorFilePathKey; + +/** + * Key used to retrieve the file name from an error object dictionary. + */ +GREY_EXTERN NSString *const kErrorFileNameKey; + +/** + * Key used to retrieve the line from an error object dictionary. + */ +GREY_EXTERN NSString *const kErrorLineKey; + +/** + * Key used to retrieve the function name from an error object dictionary. + */ +GREY_EXTERN NSString *const kErrorFunctionNameKey; + +/** + * Key used to retrieve the user info from an error object dictionary. + */ +GREY_EXTERN NSString *const kErrorUserInfoKey; + +/** + * Key used to retrieve the error info from an error object dictionary. + */ +GREY_EXTERN NSString *const kErrorErrorInfoKey; + +/** + * Key used to retrieve the bundle ID from an error object dictionary. + */ +GREY_EXTERN NSString *const kErrorBundleIDKey; + +/** + * Key used to retrieve the stack trace from an error object dictionary. + */ +GREY_EXTERN NSString *const kErrorStackTraceKey; + +/** + * Key used to retrieve the app UI hierarchy from an error object dictionary. + */ +GREY_EXTERN NSString *const kErrorAppUIHierarchyKey; + +/** + * Key used to retrieve the app screenshots from an error object dictionary. + */ +GREY_EXTERN NSString *const kErrorAppScreenShotsKey; + +/** + * Key used to retrieve the description glossary from an error object dictionary. + */ +GREY_EXTERN NSString *const kErrorDescriptionGlossaryKey; + +@interface GREYError (Internal) + +@property(nonatomic) NSString *testCaseClassName; +@property(nonatomic) NSString *testCaseMethodName; +@property(nonatomic) NSString *filePath; +@property(nonatomic) NSUInteger line; +@property(nonatomic) NSString *functionName; +@property(nonatomic) NSDictionary *errorInfo; +@property(nonatomic) NSString *bundleID; +@property(nonatomic) NSArray *stackTrace; +@property(nonatomic) NSString *appUIHierarchy; +@property(nonatomic) NSDictionary *appScreenshots; + +- (instancetype)initWithDomain:(NSString *)domain + code:(NSInteger)code + userInfo:(NSDictionary *)dict + testCase:(XCTestCase *)testCase; + ++ (instancetype)errorWithDomain:(NSString *)domain + code:(NSInteger)code + userInfo:(NSDictionary *)dict + testCase:(XCTestCase *)testCase; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYError.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYError.h new file mode 100644 index 0000000000..6b5f0b9382 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYError.h @@ -0,0 +1,331 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import + +@class GREYError; + +NS_ASSUME_NONNULL_BEGIN + +/** + * Creates a @c GREYError object with given @c domain, @c code, @c description + * The description is accessible by querying error's @c userInfo with + * @c NSLocalizedDescriptionKey. + * + * @param domain The error domain. + * @param code The error code. + * @param description The error's localized description. + * + * @return A @c GREYError object with the given input. + */ +#define GREYErrorMake(domain, code, description) \ +I_GREYErrorMake((domain), \ + (code), \ + @{ NSLocalizedDescriptionKey : (description) }, \ + [NSString stringWithUTF8String:__FILE__], \ + __LINE__, \ + [NSString stringWithUTF8String:__PRETTY_FUNCTION__], \ + nil, \ + [NSThread callStackSymbols]) + +/** + * Creates a @c GREYError object with given @c domain, @c code, @c description + * and @c nestedError. + * The description is accessible by querying error's @c userInfo with + * @c NSLocalizedDescriptionKey. The @c nestedError is accessible by error's + * @c userInfo with @c NSUnderlyingErrorKey. + * + * @param domain The error domain. + * @param code The error code. + * @param description The error's localized description. + * @param nestedError An error to be nested in current error. + * + * @return A @c GREYError object with the given input. + */ +#define GREYNestedErrorMake(domain, code, description, nestedError) \ +I_GREYErrorMake((domain), \ + (code), \ + @{ NSLocalizedDescriptionKey : (description), \ + NSUnderlyingErrorKey : (nestedError) }, \ + [NSString stringWithUTF8String:__FILE__], \ + __LINE__, \ + [NSString stringWithUTF8String:__PRETTY_FUNCTION__], \ + nil, \ + [NSThread callStackSymbols]) + +/** + * If @c errorRef is not @c NULL, it is set to a @c GREYError object that is created with + * the given @c domain, @c code and @c description. + * The description is accessible by querying error's @c userInfo with @c NSLocalizedDescriptionKey. + * If @c errorRef is @c NULL, the error information is logged using NSLog. + * + * @param[out] errorRef A @c GREYError reference for retrieving the created + * error object. + * @param domain The error domain. + * @param code The error code. + * @param description The error's localized description. + * + */ +#define GREYPopulateErrorOrLog(errorRef, domain, code, description) \ +({ \ + GREYError *e = GREYErrorMake((domain), (code), (description)); \ + if(errorRef) { \ + *errorRef = e; \ + } else { \ + NSLog(@"%@", e); \ + } \ +}) + +/** + * If @c errorRef is not @c NULL, it is set to a @c GREYError object that is created with + * the given @c domain, @c code, @c description and @c glossary. + * The description is accessible by querying error's @c userInfo with @c NSLocalizedDescriptionKey. + * If @c errorRef is @c NULL, the error information is logged using NSLog. + * + * @param[out] errorRef A @c GREYError reference for retrieving the created + * error object. + * @param domain The error domain. + * @param code The error code. + * @param description The error's localized description. + * @param glossary A glossary dictionary that is going to be populated with the error. + * + */ +#define GREYPopulateErrorNotedOrLog(errorRef, domain, code, description, glossary) \ +({ \ + GREYError *e = GREYErrorMake((domain), (code), (description)); \ + e.descriptionGlossary = (glossary); \ + if(errorRef) { \ + *errorRef = e; \ + } else { \ + NSLog(@"%@", e); \ + } \ +}) + +/** + * If @c errorRef is not @c NULL, it is set to a @c GREYError object that is created + * with the given @c domain, @c code, @c description and @c nestedError. + * The description is accessible by querying error's @c userInfo with + * @c NSLocalizedDescriptionKey. The @c nestedError is accessible by error's + * @c userInfo with @c NSUnderlyingErrorKey. + * If @c errorRef is @c NULL, the error information is logged using NSLog. + * + * @param[out] errorRef A @c GREYError reference for retrieving the created + * error object. + * @param domain The error domain. + * @param code The error code. + * @param description The error's localized description. + * @param nestedError An error to be nested in current error. + * + */ +#define GREYPopulateNestedErrorOrLog(errorRef, domain, code, description, nestedError) \ +({ \ + GREYError *e = GREYNestedErrorMake((domain), (code), (description), (nestedError)); \ + if(errorRef) { \ + *errorRef = e; \ + } else { \ + NSLog(@"%@", e); \ + } \ +}) + +/** + * Creates a @c GREYError object with given @c domain, @c code, @c userInfo, + * @c filePath, @c line, @c functionName, @c errorInfo and @c stackTrace. + * + * @param domain The error domain. + * @param code The error code. + * @param userInfo The user information that should be included + * in the @c GREYError object. + * @param filePath The file path where the error is generated. + * @param line The file line where the error is generated. + * @param functionName The function name where the error is generated. + * @param errorInfo A dictionary containing details about the error. + * @param stackTrace The stack trace for the app when the error is generated. + * + * @return A @c GREYError object with the given input. + */ +GREY_EXTERN GREYError *I_GREYErrorMake(NSString *domain, + NSInteger code, + NSDictionary *_Nullable userInfo, + NSString *filePath, + NSUInteger line, + NSString *functionName, + NSDictionary *_Nullable errorInfo, + NSArray *stackTrace); + +/** + * The string for a generic error in EarlGrey. + */ +GREY_EXTERN NSString *const kGREYGenericErrorDomain; + +/** + * The code for a generic error in EarlGrey. + */ +GREY_EXTERN NSInteger const kGREYGenericErrorCode; + +/** + * Key used to retrieve the failure name from an error object for a failed action. + */ +GREY_EXTERN NSString *const kErrorDetailFailureNameKey; + +/** + * Key used to retrieve the action name from an error object for a failed action. + */ +GREY_EXTERN NSString *const kErrorDetailActionNameKey; + +/** + * Key used to retrieve the assert criteria from an error object for a failed assertion. + */ +GREY_EXTERN NSString *const kErrorDetailAssertCriteriaKey; + +/** + * Key used to retrieve the detailed recovery suggestion from an error object. + */ +GREY_EXTERN NSString *const kErrorDetailRecoverySuggestionKey; + +/** + * Key used to retrieve the error domain from an error object. + */ +GREY_EXTERN NSString *const kErrorDomainKey; + +/** + * Key used to retrieve the error code from an error object. + */ +GREY_EXTERN NSString *const kErrorCodeKey; + +/** + * Key used to retrieve the error description from an error object. + */ +GREY_EXTERN NSString *const kErrorDescriptionKey; + +/** + * Key used to retrieve the failure reason from an error object. + */ +GREY_EXTERN NSString *const kErrorFailureReasonKey; + +/** + * Key used to retrieve the screenshot at failure from an error object's app screenshots. + */ +GREY_EXTERN NSString *const kScreenshotAtFailure; + +/** + * Key used to retrieve the visibility checker's most recent screenshot before failure + * from an error object's app screenshots. + */ +GREY_EXTERN NSString *const kScreenshotBeforeImage; + +/** + * Key used to retrieve the expected visibility checker's most recent screenshot after failure + * from an error object's app screenshots. + */ +GREY_EXTERN NSString *const kScreenshotExpectedAfterImage; + +/** + * Key used to retrieve the actual visibility checker's most recent screenshot after failure + * from an error object's app screenshots. + */ +GREY_EXTERN NSString *const kScreenshotActualAfterImage; + +/** + * The error class for the error objects generated by EarlGrey. + */ +@interface GREYError : NSError + +/** + * The name of the test case class where the error is generated. + */ +@property(nonatomic, readonly) NSString *testCaseClassName; + +/** + * The name of the test case method where the error is generated. + */ +@property(nonatomic, readonly) NSString *testCaseMethodName; + +/** + * The source code file path where the error is generated. + */ +@property(nonatomic, readonly) NSString *filePath; + +/** + * The source code line number where the error is generated. + */ +@property(nonatomic, readonly) NSUInteger line; + +/** + * The source code function name where the error is generated. + */ +@property(nonatomic, readonly) NSString *functionName; + +/** + * The error information dictionary that is associated with the error. + */ +@property(nonatomic, readonly) NSDictionary *errorInfo; + +/** + * The bundle identifier where the error is generated in. + */ +@property(nonatomic, readonly) NSString *bundleID; + +/** + * The stack trace when the error is generated. + */ +@property(nonatomic, readonly) NSArray *stackTrace; + +/** + * The window hierarchy when the error is generated. + */ +@property(nonatomic, readonly) NSString *appUIHierarchy; + +/** + * The screenshots for tha app when the error is generated; + */ +@property(nonatomic, readonly) NSDictionary *appScreenshots; + +/** + * Nested error within current error. + */ +@property(nonatomic, readonly) NSError *nestedError; + +/** + * The description glossary dictionary that is associated with the error. + */ +@property(nonatomic) NSDictionary *descriptionGlossary; + +/** + * @remark init is not an available initializer. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * For a given @c error, creates an array of error dictionaries with its nested error. + * + * @return An array of error dictionaries for the given @c error. + * If the given error does not contain nested error, an empty array will be returned. + */ ++ (NSArray *)grey_nestedErrorDictionariesForError:(NSError *)error; + +/** + * For a given @c error, creates a JSON-formatted description of the error and its nested error. + * + * @return The description of the error including its nested errors, + * if error object was created and set. Otherwise, return @c NULL. + */ ++ (NSString *)grey_nestedDescriptionForError:(NSError *)error; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYErrorConstants.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYErrorConstants.h new file mode 100644 index 0000000000..8e70dc21f3 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYErrorConstants.h @@ -0,0 +1,67 @@ +// +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +/** + * Extern variables specifying the error keys for a base action. + */ +GREY_EXTERN NSString *const kErrorDetailElementDescriptionKey; +GREY_EXTERN NSString *const kErrorDetailConstraintRequirementKey; +GREY_EXTERN NSString *const kErrorDetailConstraintDetailsKey; + +/** + * Extern variables specifying the error domain for GREYElementInteraction. + */ +GREY_EXTERN NSString *const kGREYInteractionErrorDomain; +GREY_EXTERN NSString *const kGREYWillPerformActionNotification; +GREY_EXTERN NSString *const kGREYDidPerformActionNotification; +GREY_EXTERN NSString *const kGREYWillPerformAssertionNotification; +GREY_EXTERN NSString *const kGREYDidPerformAssertionNotification; + +/** + * Extern variables specifying the user info keys for any notifications. + */ +GREY_EXTERN NSString *const kGREYActionUserInfoKey; +GREY_EXTERN NSString *const kGREYActionElementUserInfoKey; +GREY_EXTERN NSString *const kGREYActionErrorUserInfoKey; +GREY_EXTERN NSString *const kGREYAssertionUserInfoKey; +GREY_EXTERN NSString *const kGREYAssertionElementUserInfoKey; +GREY_EXTERN NSString *const kGREYAssertionErrorUserInfoKey; + +/** + * Internal variables specifying the detail keys for error details. + */ +GREY_EXTERN NSString *const kErrorDetailElementMatcherKey; + +/** + * The error domain for pinch action related errors. + */ +GREY_EXTERN NSString *const kGREYPinchErrorDomain; + +/** + * Extern variables specifying the user info keys for a pinch action. + */ +GREY_EXTERN NSString *const kErrorDetailElementKey; +GREY_EXTERN NSString *const kErrorDetailWindowKey; + +/** + * Extern variables specifying the error keys for a change stepper action. + */ +GREY_EXTERN NSString *const kErrorDetailStepperKey; +GREY_EXTERN NSString *const kErrorDetailUserValueKey; +GREY_EXTERN NSString *const kErrorDetailStepMaxValueKey; +GREY_EXTERN NSString *const kErrorDetailStepMinValueKey; diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYFailureFormatter.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYFailureFormatter.h new file mode 100644 index 0000000000..21bed59d0e --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYFailureFormatter.h @@ -0,0 +1,95 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import + +@class GREYError; +@class XCTestCase; + +NS_ASSUME_NONNULL_BEGIN + +/** + * Class to help formatting error objects for logging purposes. + */ +@interface GREYFailureFormatter : NSObject + +/** + * Format a given error object to a string for logging. + * The formatted failure message will follow this order: + * + * FailureLabel: FailureName + * Source File + * Source Line + * Bundle ID + * Stack Trace + * Screenshot + * Window Hierarchy + * + * @param error The error object to be formatted. + * @param excluding An array to exclude parts of the error from the output. + * The key + * @param failureLabel The label to be associated with the error. + * @param failureName The name to be associated with the error. + * @param format Extra message to be included in the message. + * + * @return Formatted error message string. + */ ++ (NSString *)formatFailureForError:(GREYError *)error + excluding:(NSArray *_Nullable)excluding + failureLabel:(NSString *)failureLabel + failureName:(NSString *)failureName + format:(NSString *)format, ... NS_FORMAT_FUNCTION(5, 6); +/** + * Format a failure happened in a given test case for logging. + * + * The formatted failure message will follow this order: + * + * FailureLabel: FailureName + * Source File + * Source Line + * Bundle ID + * Stack Trace + * Screenshot + * Window Hierarchy + * + * @param testCase The test case where the failure happens. + * @param failureLabel The label to be associated with the error. + * @param failureName The name to be associated with the error. + * @param functionName The name of the function where the error is generated. + * @param filePath The path to the source code file where the error happens. + * @param lineNumber The line number of the source code file when the error happens. + * @param stackTrace The stack trace of the executable when the error happens. + * @param appScreenshots The dictionary of app screenshot names and image paths + * when the error happens. + * @param format Extra message to be included in the message. + * + * @return Formatted error message string. + */ ++ (NSString *)formatFailureForTestCase:(XCTestCase *)testCase + failureLabel:(NSString *)failureLabel + failureName:(NSString *)failureName + filePath:(NSString *)filePath + lineNumber:(NSUInteger)lineNumber + functionName:(NSString *_Nullable)functionName + stackTrace:(NSArray *)stackTrace + appScreenshots:(NSDictionary *)appScreenshots + format:(NSString *)format, ... NS_FORMAT_FUNCTION(9, 10); + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYFailureScreenshotter.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYFailureScreenshotter.h new file mode 100644 index 0000000000..403fff1f8b --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYFailureScreenshotter.h @@ -0,0 +1,50 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface GREYFailureScreenshotter : NSObject + +/** + * Generate app screenshot with given prefix and failure name. + * + * @param screenshotPrefix Prefix for the screenshots. + * @param failureName Failure name associated with the screenshots. + * + * @return A dictionary of the screenshot names and their corresponding paths. + */ + ++ (NSDictionary *)generateAppScreenshotsWithPrefix:(NSString *_Nullable)screenshotPrefix + failure:(NSString *)failureName; + +/** + * Generate app screenshot with given prefix and failure name. + * + * @param screenshotPrefix Prefix for the screenshots. + * @param failureName Failure name associated with the screenshots. + * @param screenshotDir The screenshot directory where the screenshots are placed. + * + * @return A dictionary of the screenshot names and their corresponding paths. + */ ++ (NSDictionary *)generateAppScreenshotsWithPrefix:(NSString *_Nullable)screenshotPrefix + failure:(NSString *)failureName + screenshotDir:(NSString *)screenshotDir; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYInteractionDataSource.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYInteractionDataSource.h new file mode 100644 index 0000000000..c5b5e77e6d --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYInteractionDataSource.h @@ -0,0 +1,36 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@protocol GREYProvider; + +NS_ASSUME_NONNULL_BEGIN + +/** + * Provides data to a GREYInteraction. + */ +@protocol GREYInteractionDataSource + +/** + * The root element provider for an interaction. The entire hierarchies starting from the root + * elements are searched to find the right element to interact with. + * + * @return A GREYProvider instance providing data for the interaction. + */ +- (id)rootElementProvider; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYKeyboard.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYKeyboard.h new file mode 100644 index 0000000000..65f3618d3c --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYKeyboard.h @@ -0,0 +1,55 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Provides ability to perform input actions using the iOS system keyboard and also track the + * current keyboard visibility. + */ +@interface GREYKeyboard : NSObject + +/** + * Types @c string using the keyboard in the provided @c firstResponder. Keyboard must be shown + * on the screen when this method is called. + * + * @param string Text to be typed using the keyboard. + * @param firstResponder The element that the text is to be typed in. + * @param[out] errorOrNil Error populated when any failure occurs during typing. If @c nil, then a + * custom error with @c kGREYInteractionActionFailedErrorCode is logged. + * + * @return @c YES if typing succeeded, @c NO otherwise. + */ ++ (BOOL)typeString:(NSString *)string + inFirstResponder:(id)firstResponder + error:(__strong NSError **)errorOrNil; + +/** + * Waits until the keyboard is visible on the screen. + * @return @c YES if the keyboard did appear after the wait, @c NO otherwise. + */ ++ (BOOL)waitForKeyboardToAppear; + +/** + * @return @c YES if the keyboard is present on the screen, @c NO otherwise. + */ ++ (BOOL)isKeyboardShown; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYLogger.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYLogger.h new file mode 100644 index 0000000000..916d7d49e1 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYLogger.h @@ -0,0 +1,73 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file GREYLogger.h + * @brief Macro for printing more logs for aiding in debugging. + */ + +#import + +/** + * Prints a log statement if @c kGREYAllowVerboseLogging is present and turned to @c YES in + * @c NSUserDefaults. You can pass it in the command line arguments as: + * To turn on, set @c kGREYAllowVerboseLogging key in @c NSUserDefaults to @c YES. + * @code + * [[NSUserDefaults standardUserDefaults] setBool:YES forKey:kGREYAllowVerboseLogging]; + * @endcode + * + * @remark Once you set this, as with any @c NSUserDefault, you need to explicitly turn it off + * or delete and re-install the app under test. + * + * @param format The string format to be printed. + * @param ... The parameters to be added to the string format. + */ +#define GREYLogVerbose(format, ...) \ +({ \ + if ([[NSUserDefaults standardUserDefaults] boolForKey:kGREYAllowVerboseLogging]) { \ + NSLog((format), ##__VA_ARGS__); \ + } \ +}) + + +/** + * Log an error generated by the system or EarlGrey to the console. + * + * @param error An error object to be logged. This can be an @c NSError object or + * a @c GREYError object. + * + */ +#define GREYLogError(error) \ +({ \ + I_GREYLogError(error, \ + [NSString stringWithUTF8String:__FILE__], \ + __LINE__, \ + [NSString stringWithUTF8String:__PRETTY_FUNCTION__], \ + [NSThread callStackSymbols]); \ +}) + +NS_ASSUME_NONNULL_BEGIN + +/** + * Log an error generated by the system or EarlGrey to the console. + */ +GREY_EXPORT void I_GREYLogError(NSError *error, + NSString *filePath, + NSUInteger lineNumber, + NSString *functionName, + NSArray *stackTrace); + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYMultiFingerSwipeAction.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYMultiFingerSwipeAction.h new file mode 100644 index 0000000000..b30ddd0ec2 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYMultiFingerSwipeAction.h @@ -0,0 +1,80 @@ +// +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A GREYAction that swipes/flicks with multiple touches + */ +@interface GREYMultiFingerSwipeAction : GREYBaseAction + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * @remark initWithName::constraints: is overridden from its superclass. + */ +- (instancetype)initWithName:(NSString *)name + constraints:(id)constraints NS_UNAVAILABLE; + +/** + * Performs a swipe with multiple parallel fingers in the given @c direction in the given + * @c duration, the start of swipe is chosen to achieve maximum swipe, such as a point close to + * bottom edge of the element is chosen in case of a swipe in up direction. Using this method will + * infer a start percentage of x: 0.5, y: 0.5. + * + * @param direction The direction of the swipe. + * @param duration The time interval for which the swipe takes place. + * @param numberOfFingers The number of parallel fingers to use. Max value: 4. + * + * @return An instance of GREYMultiFingerSwipeAction, initialized with the provided direction, + * duration and number of fingers to swipe with. + */ +- (instancetype)initWithDirection:(GREYDirection)direction + duration:(CFTimeInterval)duration + numberOfFingers:(NSUInteger)numberOfFingers; + +/** + * Performs a swipe with multiple parallel fingers in the given @c direction in the given + * @c duration, the start of swipe is chosen based on @c startPercents. Since swipes must begin + * inside the element and not on the edge of it x/y, startPercents must be in the range (0,1) + * exclusive. + * + * @param direction The direction of the swipe. + * @param duration The time interval for which the swipe takes place. + * @param numberOfFingers The number of parallel fingers to use. Max Value: 4. + * @param startPercents @c startPercents.x sets the value of the x-coordinate of the start point + * by interpolating between left(for 0.0) and right(for 1.0) edge similarly + * @c startPercents.y determines the y coordinate. + * + * @return An instance of GREYMultiFingerSwipeAction, initialized with the provided direction, + * duration, information for the start point and number of fingers to swipe with. + */ +- (instancetype)initWithDirection:(GREYDirection)direction + duration:(CFTimeInterval)duration + numberOfFingers:(NSUInteger)numberOfFingers + startPercents:(CGPoint)startPercents NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END + diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYNSURLConnectionDelegate.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYNSURLConnectionDelegate.h new file mode 100644 index 0000000000..ba89733997 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYNSURLConnectionDelegate.h @@ -0,0 +1,47 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import "Delegate/GREYSurrogateDelegate.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * This is a proxy delegate for NSURLConnectionDelegate which allows us track status of + * the connection. + * + * @todo Support NSURLConnectionDownloadDelegate. + */ +@interface GREYNSURLConnectionDelegate : GREYSurrogateDelegate + + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * Creates an instance of GREYNSURLConnectionDelegate backed by the provided delegate. + * + * @param originalDelegate The original delegate being proxied. + * @return an instance of GREYNSURLConnectionDelegate backed by the original delegate. + */ +- (instancetype)initWithOriginalNSURLConnectionDelegate:(id)originalDelegate; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYObjcRuntime.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYObjcRuntime.h new file mode 100644 index 0000000000..90f7065ba2 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYObjcRuntime.h @@ -0,0 +1,39 @@ +// +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A utility class used for common runtime related operations. + */ +@interface GREYObjcRuntime : NSObject + +/** + * Adds the given method from the given class into the destination class. + * + * @param destination The destination class. + * @param selector The method selector from source class that needs to be added to destination. + * @param source The source class for the method to be added. + */ ++ (void)addInstanceMethodToClass:(Class)destination + withSelector:(SEL)selector + fromClass:(Class)source; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYObjectDeallocationTracker.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYObjectDeallocationTracker.h new file mode 100644 index 0000000000..71c02fdbdb --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYObjectDeallocationTracker.h @@ -0,0 +1,66 @@ +// +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +@class GREYObjectDeallocationTracker; + +NS_ASSUME_NONNULL_BEGIN + +@protocol GREYObjectDeallocationTrackerDelegate + +/** + * Delegate method that is called when the GREYObjectDeallocationTracker is deallocated. + * + * @param objectDeallocationTracker The GREYObjectDeallocationTracker instance that is being + * deallocated. + */ +-(void)objectTrackerDidDeallocate:(GREYObjectDeallocationTracker *)objectDeallocationTracker; + +@end + +@interface GREYObjectDeallocationTracker : NSObject + +/** + * Initialize the GREYObjectDeallocationTracker with a delegate object. + * + * @param object The object that should be tracked by the GREYObjectDeallocationTracker. + * @param delegate The object that conforms to the GREYObjectDeallocationTrackerDelegate protocol + * and wants to receive the delegate callback. + */ +- (instancetype)initWithObject:(id)object + delegate:(id _Nullable)delegate; + +/** + * @remark init is not an available initializer. Use the other initializer. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * Finds the GREYObjectDeallocationTracker associated with the @c object if one exists. Call this + * method if the @c object is already being tracked by an instance of + * GREYObjectDeallocationTracker. + * + * @param object The object that the GREYObjectDeallocationTracker is tracking. + * + * @return An instance of GREYObjectDeallocationTracker or nil if object's deallocation isn't + * being tracked. + */ ++ (GREYObjectDeallocationTracker * _Nullable)deallocationTrackerRegisteredWithObject:(id)object; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYObjectFormatter.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYObjectFormatter.h new file mode 100644 index 0000000000..528ba740b7 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYObjectFormatter.h @@ -0,0 +1,108 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import + +/** + * Indent when perform object formation. + */ +GREY_EXTERN NSInteger const kGREYObjectFormatIndent; + +NS_ASSUME_NONNULL_BEGIN + +@interface GREYObjectFormatter : NSObject + +/** + * Serializes an array of objects into JSON string. + * The supported objects are: NSString, NSNumber, NSArray, NSDictionary and GREYError. + * + * @param array The array to serialize. + * @param indent The spaces that will be applied to each element of the serialized array. + * @param keyOrder Output the key-value pair in the order of the keys specified + * in the keyOrder array. + * + * @return JSON-ified string of the provided @c array. + */ ++ (NSString *)formatArray:(NSArray *)array indent:(NSInteger)indent keyOrder:(NSArray *)keyOrder; + +/** + * Serializes a dictionary of objects into JSON string. + * The supported objects are: NSString, NSNumber, NSArray, NSDictionary and GREYError. + * + * @param dictionary The dictionary to serialize. + * @param indent Number of spaces that will be applied to each element + * of the serialized dictionary. + * @param hideEmpty Hide the key-value pair if the value in the dictionary + * when the key is empty. + * @param keyOrder Output the key-value pair in the order of the keys specified + * in the keyOrder array. + * + * @return JSON-ified string of the provided @c dictionary. + */ ++ (NSString *)formatDictionary:(NSDictionary *)dictionary + indent:(NSInteger)indent + hideEmpty:(BOOL)hideEmpty + keyOrder:(NSArray *_Nullable)keyOrder; + +/** + * Serializes an array of objects into JSON-like string. + * The supported objects are: NSString, NSNumber, NSArray, NSDictionary. + * + * @remark The serialized string is formatted as a JSON for presentation purposes but it doesn't + * have the right escaping applied for special character as it hinders readability. + * + * @param array The array to serialize. + * @param prefix A string that will be applied to each newline of the serialized array. + * @param indent The spaces that will be applied to each element of the serialized array. + * @param keyOrder Output the key-value pair in the order of the keys specified + * in the keyOrder array. + * @return Serialized JSON-like string of the provided @c array. + */ ++ (NSString *)formatArray:(NSArray *)array + prefix:(NSString *_Nullable)prefix + indent:(NSInteger)indent + keyOrder:(NSArray *_Nullable)keyOrder; + +/** + * Serializes a dictionary of objects into JSON-like string. + * The supported objects are: NSString, NSNumber, NSArray, NSDictionary. + * + * @remark The serialized string is formatted as a JSON for presentation purposes but it doesn't + * have the right escaping applied for special character as it hinders readability. + * + * @param dictionary The dictionary to serialize. + * @param prefix A string that will be applied to each newline + * of the serialized dictionary. + * @param indent Number of spaces that will be applied to each element (key and value) + * of the serialized dictionary + * @param hideEmpty Hide the key-value pair if the value in the dictionary + * when the key is empty. + * @param keyOrder Output the key-value pair in the order of the keys specified + * in the keyOrder array. + * + * @return Serialized string of the provided @c dictionary. + */ ++ (NSString *)formatDictionary:(NSDictionary *)dictionary + prefix:(NSString *_Nullable)prefix + indent:(NSInteger)indent + hideEmpty:(BOOL)hideEmpty + keyOrder:(NSArray *_Nullable)keyOrder; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYPathGestureUtils.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYPathGestureUtils.h new file mode 100644 index 0000000000..10f1201a52 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYPathGestureUtils.h @@ -0,0 +1,91 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A utility class for creating and injecting gestures that involve touch paths, for example: + * swipe, scroll etc. + */ +@interface GREYPathGestureUtils : NSObject + +/** + * Generates a touch path in the @c window from the start point, in the given direction to the + * max possible extent. + * + * @param startPointInWindowCoordinates The start point within the given @c window + * @param direction The direction of the touch path. + * @param duration How long the gesture should last (in seconds). + * @param window The window in which the touch path is generated. + * + * @return NSArray of CGPoints that denote the points in the touch path. + */ ++ (NSArray *)touchPathForGestureWithStartPoint:(CGPoint)startPointInWindowCoordinates + andDirection:(GREYDirection)direction + andDuration:(CFTimeInterval)duration + inWindow:(UIWindow *)window; + +/** + * Generates a touch path in the @c window starting from a given @c view in a particular direction + * for a certain amount in the window coordinates of the @c view. The start point of the path is + * controlled by @c startPointPercents, which if specified as @c NAN, the start point will be + * chosen to provide longest possible touch path, otherwise start point will be set to the percents + * specified in the visible area of the given @c view. Note that the percent values must lie within + * (0, 1) exclusive and the x and y axis are always the bottom and the left edge respectively of + * the visible rect. + * + * @param view The view from which the touch path originates. + * @param direction The direction of the touch. + * @param length The length of the touch path. The length of the touch path + * is restricted by the screen dimensions, position of the + * view and the minimum scroll detection length (10 points as + * of iOS 8.0). + * @param startPointPercents The start point of the touch path specified as percents in + * the visible area of the @c view. Must be (0, 1) exclusive. + * @param[out] outRemainingAmountOrNull The difference of the length and the amount, + * if the length falls short. + * + * @return Array of CGPoints that denote the points in the touch path. The touch path's length + * will be at least the minimum scroll detection length, when that is not possible + * (due to @c view position and/or size) @c nil is returned. + */ ++ (NSArray *)touchPathForGestureInView:(UIView *)view + withDirection:(GREYDirection)direction + length:(CGFloat)length + startPointPercents:(CGPoint)startPointPercents + outRemainingAmount:(CGFloat *_Nullable)outRemainingAmountOrNull; + +/** + * Generates a touch path in the @c window from the given @c startPoint and the given @c + * endPoint. + * + * @param startPoint The starting point for touch path. + * @param endPoint The end point for touch path. + * @param cancelInertia A boolean value indicating whether intertial movement should be cancelled. + * + * @return NSArray of CGPoints that denote the points in the touch path. + */ ++ (NSArray *)touchPathForDragGestureWithStartPoint:(CGPoint)startPoint + endPoint:(CGPoint)endPoint + cancelInertia:(BOOL)cancelInertia; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYPickerAction.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYPickerAction.h new file mode 100644 index 0000000000..04e21d4101 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYPickerAction.h @@ -0,0 +1,49 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Actions for manipulating a UIPickerView. + */ +@interface GREYPickerAction : GREYBaseAction + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * @remark initWithName::constraints: is overridden from its superclass. + */ +- (instancetype)initWithName:(NSString *)name + constraints:(id)constraints NS_UNAVAILABLE; + +/** + * Selects a value in a given column of a UIPickerView. + * + * @param column Column of the UIPickerView to change. + * @param value The value to set in the UIPickerView column. + * + * @return An instance of UIPickerAction, initialized with the @c column and @c value. + */ +- (instancetype)initWithColumn:(NSInteger)column value:(NSString *)value NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYPinchAction.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYPinchAction.h new file mode 100644 index 0000000000..b7ba373bed --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYPinchAction.h @@ -0,0 +1,60 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Error domain used for pinch related NSError objects. + */ +GREY_EXTERN NSString *const kGREYPinchErrorDomain; + +/** + * Error codes for pinch related failures. + */ +typedef NS_ENUM(NSInteger, GREYPinchErrorCode) { + kGREYPinchFailedErrorCode = 0, +}; + +/** + * A @c GREYAction that performs the pinch gesture on the view on which it is called. + */ +@interface GREYPinchAction : GREYBaseAction + +/** + * Performs a pinch action in the given @c direction for the @c duration. The start of outward + * pinch is from the center of the view and stops before 20% margin of the view's bounding rect. + * + * For an inward pinch the start point is at a 20% margin of the view's bounding rect on either + * side and stops at the center. The default angle of the pinch action is 30 degrees to closely + * match the average pinch angle of a natural right handed pinch. + * + * @param direction The direction of the pinch. + * @param duration The time interval for which the pinch takes place. + * @param pinchAngle Angle of the vector in radians to which the pinch direction is pointing. + * + * @returns An instance of @c GREYPinchAction, initialized with a provided direction and + * duration and angle. + */ +- (instancetype)initWithDirection:(GREYPinchDirection)direction + duration:(CFTimeInterval)duration + pinchAngle:(double)pinchAngle; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYRunLoopSpinner.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYRunLoopSpinner.h new file mode 100644 index 0000000000..9c411aa810 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYRunLoopSpinner.h @@ -0,0 +1,103 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * @brief Handles spinning the current run loop in the active mode with various configurations. + * Similar to dispatch_sync calls on a thread, you cannot make nested spin calls to the same + * spinner object, but it is OK to create and spin a separate spinner object within a + * source/timer/block invoked by another spinner. + * + * The current run loop mode is the mode that a run loop is currently executing in. The active run + * loop mode is (more or less) the mode that the run loop would be executing if we weren't + * controlling the run loop's execution. Some events, like scrolling, will switch the current mode + * under normal conditions but not while we are spinning the run loop. To make the app behave + * closer to normal app conditions, the run loop spinner spins the run loop in the active mode not + * the current mode. + * + * Draining (or doing a pass over) the run loop in a particular mode is running the run loop so + * that it service all pending blocks, sources, or timers. Spinning the run loop means repeatedly + * draining the run loop, possibly allowing the run loop to sleep between drains. + * + * While the run loop spinner is running the run loop in a particular mode, any source/timer/block + * serviced by the run loop may itself start running the run loop in any mode of its choosing. + * In that case, we consider run loop as not running in the mode that we started spinning, even + * if the source/timer/block started running the run loop in the same mode (nesting the run loop + * mode). + */ +@interface GREYRunLoopSpinner : NSObject + +/** + * The maximum time in seconds that the spinner will spin the run loop. Default is 0. + * + * The spinner will not initiate any run loop drains after @c timeout seconds, but it is possible + * that an ongoing run loop drain will be executing after @c timeout. If @c timeout is 0, then the + * spinner will only drain the run loop for its configured minimum number of run loop drains. + */ +@property(nonatomic) CFTimeInterval timeout; + +/** + * The maximum time in seconds that the current thread will be allowed to sleep while running in + * the active mode that we started spinning. Default is 0. + * + * If set to 0, then the run loop will not be allowed to sleep in the active mode that it started + * spinning. + * + * @remark Not allowing the run loop to sleep can be useful for some test scenarios but causes the + * thread to use significantly more CPU. + */ +@property(nonatomic) CFTimeInterval maxSleepInterval; + +/** + * The minimum number of times that the run loop should be drained in the active mode before + * checking the stop condition. Default is 2. + * + * @remark The default value is 2 because, as per the CFRunLoop implementation, some ports + * (specifically the dispatch port) will only be serviced every other run loop drain. + */ +@property(nonatomic) NSUInteger minRunLoopDrains; + +/** + * This block is invoked in the active run loop mode if the stop condition evaluates to YES. + * Default is a noop. + */ +@property(copy, nonatomic) void (^conditionMetHandler)(void); + +/** + * Spins the current thread's run loop in the active mode using the given stop condition. + * + * Will always spin the run loop for at least the minimum number of run loop drains. Will always + * evaluate @c stopConditionBlock at least once after draining for minimum number of drains. After + * draining for the minimum number of drains, the spinner will evaluate @c stopConditionBlock at + * least once per run loop drain. The spinner will stop initiating drains and return if + * @c stopConditionBlock evaluates to @c YES or if the timeout has elapsed. + * + * @remark This method should not be invoked on the same spinner object in nested calls (e.g. + * sources that are serviced while it's spinning) or concurrently. + * + * @param stopConditionBlock The condition block used by the spinner to determine if it should + * keep spinning the active run loop. + * + * @return @c YES if the spinner evaluated the @c stopConditionBlock to @c YES; @c NO otherwise. + */ +- (BOOL)spinWithStopConditionBlock:(BOOL (^)(void))stopConditionBlock; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYScreenshotUtil+Internal.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYScreenshotUtil+Internal.h new file mode 100644 index 0000000000..0a96300dc8 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYScreenshotUtil+Internal.h @@ -0,0 +1,43 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file GREYScreenshotUtil+Internal.h + * @brief Exposes GREYScreenshotUtil' interfaces and methods that are otherwise private + * for testing purposes. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface GREYScreenshotUtil (Internal) + +/** + * Provides a UIImage that is a screenshot, immediately or after the screen updates as specified. + * + * @param afterScreenUpdates A Boolean specifying if the screenshot is to be taken immediately or + * after a screen update. + * + * @return A UIImage containing a screenshot. + * + * @remark This is available only for internal testing purposes. + */ ++ (UIImage *)grey_takeScreenshotAfterScreenUpdates:(BOOL)afterScreenUpdates; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYScrollAction.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYScrollAction.h new file mode 100644 index 0000000000..4194656ca0 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYScrollAction.h @@ -0,0 +1,71 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A GREYAction that implements the scroll action. + */ +@interface GREYScrollAction : GREYBaseAction + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * @remark initWithName::constraints: is overridden from its superclass. + */ +- (instancetype)initWithName:(NSString *)name + constraints:(id)constraints NS_UNAVAILABLE; + +/** + * Creates a scroll action that scrolls the contents in the given @c direction for the + * given @c amount. + * + * @param direction The direction of the scroll. + * @param amount The amount specified in points. The units here are the same as the units + * of the coordinate system of the element matched. + * + * @return An instance of GREYScrollAction, initialized with the provided + * direction and scroll amount. + */ +- (instancetype)initWithDirection:(GREYDirection)direction amount:(CGFloat)amount; + +/** + * Creates a scroll action that scrolls the contents in the given @c direction for the + * given @c amount with the start point specified by @c startPointPercents. + * + * @param direction The direction of the scroll. + * @param amount The amount specified in points. The units here are the same as the + * units of the coordinate system of the element matched. + * @param startPointPercents The start point of the scroll specified as percents (0, 1) exclusive, + * in the visible area of the scroll view or as @c NAN to pick a point + * that provides maximum scroll length. + * + * @return An instance of GREYScrollAction, initialized with the provided + * direction, scroll amount and start point. + */ +- (instancetype)initWithDirection:(GREYDirection)direction + amount:(CGFloat)amount + startPointPercents:(CGPoint)startPointPercents NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYScrollToContentEdgeAction.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYScrollToContentEdgeAction.h new file mode 100644 index 0000000000..91d4532bdc --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYScrollToContentEdgeAction.h @@ -0,0 +1,65 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A GREYAction that implements a scroll action that scrolls the contents of the matched + * UIScrollView to the given edge of its contents. + */ +@interface GREYScrollToContentEdgeAction : GREYBaseAction + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * @remark initWithName::constraints: is overridden from its superclass. + */ +- (instancetype)initWithName:(NSString *)name + constraints:(id)constraints NS_UNAVAILABLE; + +/** + * Creates a scroll action that scrolls to the given @c edge of the contents in the selected + * scroll view. + * + * @param edge The edge of the UIScrollView to scroll the contents. + * + * @return An instance of GREYScrollToContentEdgeAction, initialized with the provided @c edge. + */ +- (instancetype)initWithEdge:(GREYContentEdge)edge; + +/** + * Creates a scroll action that scrolls to the given @c edge of the contents in the selected + * scroll view with the start point specified by @c startPointPercents. + * + * @param edge The edge of the UIScrollView to scroll the contents. + * @param startPointPercents The start point of the scroll specified as percents (0, 1) exclusive, + * in the visible area of the scroll view or as @c NAN to pick a point + * that provides maximum scroll length. + * + * @return An instance of GREYScrollToContentEdgeAction, initialized with the provided @c edge. + */ +- (instancetype)initWithEdge:(GREYContentEdge)edge + startPointPercents:(CGPoint)startPointPercents NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYSlideAction.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYSlideAction.h new file mode 100644 index 0000000000..cd948ea11e --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYSlideAction.h @@ -0,0 +1,48 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A GREYAction that changes the value on a UISlider. + */ +@interface GREYSlideAction : GREYBaseAction + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * @remark initWithName::constraints: is overridden from its superclass. + */ +- (instancetype)initWithName:(NSString *)name + constraints:(id)constraints NS_UNAVAILABLE; + +/** + * Action for instances of UISlider that allow the thumb to be moved to a specific @c value. + * + * @param value Value to set on the Slider. + * + * @return An instance of GREYSlideAction, initialized with the provided slider value. + */ +- (instancetype)initWithSliderValue:(float)value NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYStopwatch.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYStopwatch.h new file mode 100644 index 0000000000..755ad418da --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYStopwatch.h @@ -0,0 +1,75 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A class that mimics a stopwatch for calculating code latency. + * + * Usage example: + * @code + * GREYStopwatch *stopwatch = [[GREYStopwatch alloc] init]; + * [stopwatch start]; + * -------code block------- + * [stopwatch stop]; + * NSLog(@"Time it took to execute codeblock %f", [stopwatch elapsedTime]); + * @endcode + * + */ +@interface GREYStopwatch : NSObject + +/** + * Set the start time of the stopwatch to the current time as obtained by @c mach_absolute_time(). + * Calling this multiple times will result in the start time being reset every single time. This + * is the only way to set the start time of the stop watch. + */ +- (void)start; + +/** + * Set the stop time of the stopwatch to the current time as obtained by @c mach_absolute_time(). + * This also prevents subsequent calls to @c GREYStopwatch::lapAndReturnTime from being performed. + * This does not affect the stopwatch's saved start time or lap time. Calling stop without first + * calling @c GREYStopwatch::start will throw an exception. + */ +- (void)stop; + +/** + * Returns the time obtained by subtracting the time the stopwatch was last stopped and last + * started. If the stopwatch is never started/stopped then it will throw an exception. This does + * not cumulatively add up the times the stopwatch was started/stopped. If the user wants the + * cumulative value of all start/stops, then the user will have to save the times and add them up. + * + * @return an NSTimeInterval with the interval from the time the stopwatch was started. + */ +- (NSTimeInterval)elapsedTime; + +/** + * Obtain the time interval from subtracting the current time as obtained by + * @c mach_absolute_time() from the reference time that @c GREYStopwatch::lapAndReturnTime was + * last called at. In case @c GREYStopwatch::lapAndReturnTime was never called, then this will + * return the interval from the start time. Similar to @c GREYStopwatch::elapsedTime, this will + * throw an exception if the stopwatch was never started. + * + * @return an NSTimeInterval with the interval from the time the stopwatch was started. + */ +- (NSTimeInterval)lapAndReturnTime; + + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYStringDescription.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYStringDescription.h new file mode 100644 index 0000000000..9d89b9c91d --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYStringDescription.h @@ -0,0 +1,25 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import + +/** + * A string based implementation of GREYDescription protocol. + */ +@interface GREYStringDescription : NSObject +@end diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYSurrogateDelegate.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYSurrogateDelegate.h new file mode 100644 index 0000000000..9664ff0f5f --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYSurrogateDelegate.h @@ -0,0 +1,50 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * This class is used as a common base class for proxy delegates. + * Primarily used to hold needed message forwarding methods. + */ +@interface GREYSurrogateDelegate : NSObject + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * Initializer that takes the original delegate and provides a surrogate backed by the original. + * + * @param originalDelegate The original delegate being proxied. This can be @c nil. + * @param shouldBeWeak Specifies whether the delegate should be weak or strong. + * + * @return an instance of GREYSurrogateDelegate backed by the provided delegate. + */ +- (instancetype)initWithOriginalDelegate:(id)originalDelegate + isWeak:(BOOL)shouldBeWeak NS_DESIGNATED_INITIALIZER; + +/** + * @return The original delegate that's being proxied. + */ +- (id)originalDelegate; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYSwipeAction.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYSwipeAction.h new file mode 100644 index 0000000000..1d43fc17fd --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYSwipeAction.h @@ -0,0 +1,70 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A GREYAction that swipes/flicks the matched element. + */ +@interface GREYSwipeAction : GREYBaseAction + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * @remark initWithName::constraints: is overridden from its superclass. + */ +- (instancetype)initWithName:(NSString *)name + constraints:(id)constraints NS_UNAVAILABLE; + +/** + * Performs a swipe in the given @c direction in the given @c duration, the start of swipe is + * chosen to achieve maximum swipe, such as a point close to bottom edge of the element is chosen + * in case of a swipe in up direction + * + * @param direction The direction of the swipe. + * @param duration The time interval for which the swipe takes place. + * + * @return An instance of GREYSwipeAction, initialized with the provided direction and duration. + */ +- (instancetype)initWithDirection:(GREYDirection)direction + duration:(CFTimeInterval)duration; + +/** + * Performs a swipe in the given @c direction in the given @c duration, the start of swipe is + * chosen based on @c startPercents. Since swipes must begin inside the element and not + * on the edge of it x/y startPercents must be in the range (0,1) exclusive. + * + * @param direction The direction of the swipe. + * @param duration The time interval for which the swipe takes place. + * @param startPercents @c startPercents.x sets the value of the x-coordinate of the start point + * by interpolating between left(for 0.0) and right(for 1.0) edge similarly + * @c startPercents.y determines the y coordinate. + * + * @return An instance of GREYSwipeAction, initialized with the provided direction, duration + * and information for the start point. + */ +- (instancetype)initWithDirection:(GREYDirection)direction + duration:(CFTimeInterval)duration + startPercents:(CGPoint)startPercents; +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYSwizzler.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYSwizzler.h new file mode 100644 index 0000000000..d74a424c2c --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYSwizzler.h @@ -0,0 +1,340 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A utility class used for swizzling class and instance methods. + */ +@interface GREYSwizzler : NSObject + +/** + * Resets @c methodSelector to the original implementation if it's implementation was swapped using + * this swizzler. + * + * @remark If the same method was swizzled multiple times, resetting will restore to the very first + * implementation before any swizzling. + * + * @param methodSelector The selector of the method that was originally swizzled. + * @param klass The class that the class-method belongs to. + * + * @return @c YES if reset was successful, @c NO otherwise. + */ +- (BOOL)resetClassMethod:(SEL)methodSelector class:(Class)klass; + +/** + * Resets @c methodSelector to the original implementation if it's implementation was swapped using + * this swizzler. + * + * @remark If the same method was swizzled multiple times using this swizzler, resetting will + * restore to the very first implementation before any swizzling performed with this + * swizzler. + * + * @param methodSelector The selector of the method that was originally swizzled. + * @param klass The class that the instance-method belongs to. + * + * @return @c YES if reset was successful, @c NO otherwise. + */ +- (BOOL)resetInstanceMethod:(SEL)methodSelector class:(Class)klass; + +/** + * Resets implementation of all the selectors swapped using this swizzler. + */ +- (void)resetAll; + +/** + * Swizzle class methods of a class. The first time a method is swizzled, its current + * implementation will be saved. If @c klass does not directly implement @c methodSelector1 + * (inherits it from a superclass), we dynamically override @c methodSelector1 with a + * copy of @c methodSelector2's implementation. This is to avoid swizzling the superclass's + * implementation. The same happens for @c methodSelector2, if @c klass does not directly + * implement @c methodSelector2, it is added to @c klass before swizzling. + * + * @param klass The class whose methods are to be swizzled. + * @param methodSelector1 Selector of the method which is to be replaced. + * @param methodSelector2 Selector of the method which is to be replaced with. + * + * @return @c YES if methods were successfully swizzled, @c NO otherwise. + */ +- (BOOL)swizzleClass:(Class)klass + replaceClassMethod:(SEL)methodSelector1 + withMethod:(SEL)methodSelector2; + +/** + * Swizzle instance methods of a class. The first time a method is swizzled, its current + * implementation will be saved. If @c klass does not directly implement @c methodSelector1 + * (inherits it from a superclass), we dynamically override @c methodSelector1 with a + * copy of @c methodSelector2's implementation. This is to avoid swizzling the superclass's + * implementation. The same happens for @c methodSelector2, if @c klass does not directly + * implement @c methodSelector2, it is added to @c klass before swizzling. + * + * @param klass The class whose methods are to be swizzled. + * @param methodSelector1 Selector of the method which is to be replaced. + * @param methodSelector2 Selector of the method which is to be replaced with. + * + * @return @c YES if methods were successfully swizzled, @c NO otherwise. + */ +- (BOOL)swizzleClass:(Class)klass + replaceInstanceMethod:(SEL)methodSelector1 + withMethod:(SEL)methodSelector2; + +/** + * Adds @c methodSelector with implementation @c imp to @c klass. After that, swizzles + * @c methodSelector with @c sel. @c sel must be an instance method of @c klass and + * @c methodSelector must have the same signature as @c sel. + * + * @param klass The class whose methods are to be swizzled. + * @param addSelector The selector to add to @c klass. + * @param addIMP Implementation of @c methodSelector when it's added to @c klass. + * @param instanceSelector Selector of the method which will be swizzled with @c methodSelector. + * + * @return @c YES if the given method could be successfully added and swizzled, @c NO otherwise. + */ +- (BOOL)swizzleClass:(Class)klass + addInstanceMethod:(SEL)addSelector + withImplementation:(IMP)addIMP + andReplaceWithInstanceMethod:(SEL)instanceSelector; + +@end + +NS_ASSUME_NONNULL_END + +# pragma mark - Original Method Invocation Macros + +/** + * Invokes the original implementation from inside a swizzled implementation. + * + * @param __returnType The return type of the original implementation. + * @param __swizzledSEL The selector used for swizzling. + */ +#define INVOKE_ORIGINAL_IMP(__returnType, \ + __swizzledSEL) \ +((__returnType(*)(id, \ + SEL)) \ +[self methodForSelector:__swizzledSEL])(self, \ + _cmd) + +/** + * Invokes the original implementation from inside a swizzled implementation. Use this instead of + * INVOKE_ORIGINAL_IMP when the original selector takes one argument. + * + * @param __returnType The return type of the original implementation. + * @param __swizzledSEL The selector used for swizzling. + * @param __arg1 The first argument to be passed to the original implementation. + */ +#define INVOKE_ORIGINAL_IMP1(__returnType, \ + __swizzledSEL, \ + __arg1) \ +((__returnType(*)(id, \ + SEL, \ + __typeof__(__arg1))) \ +[self methodForSelector:__swizzledSEL])(self, \ + _cmd, \ + __arg1) + +/** + * Invokes the original implementation from inside a swizzled implementation. Use this instead of + * INVOKE_ORIGINAL_IMP when the original selector takes two arguments. + * + * @param __returnType The return type of the original implementation. + * @param __swizzledSEL The selector used for swizzling. + * @param __arg1 The first argument to be passed to the original implementation. + * @param __arg2 The second argument to be passed to the original implementation. + */ +#define INVOKE_ORIGINAL_IMP2(__returnType, \ + __swizzledSEL, \ + __arg1, \ + __arg2) \ +((__returnType(*)(id, \ + SEL, \ + __typeof__(__arg1), \ + __typeof__(__arg2))) \ +[self methodForSelector:__swizzledSEL])(self, \ + _cmd, \ + __arg1, \ + __arg2) + +/** + * Invokes the original implementation from inside a swizzled implementation. Use this instead of + * INVOKE_ORIGINAL_IMP when the original selector takes three arguments. + * + * @param __returnType The return type of the original implementation. + * @param __swizzledSEL The selector used for swizzling. + * @param __arg1 The first argument to be passed to the original implementation. + * @param __arg2 The second argument to be passed to the original implementation. + * @param __arg3 The third argument to be passed to the original implementation. + */ +#define INVOKE_ORIGINAL_IMP3(__returnType, \ + __swizzledSEL, \ + __arg1, \ + __arg2, \ + __arg3) \ +((__returnType(*)(id, \ + SEL, \ + __typeof__(__arg1), \ + __typeof__(__arg2), \ + __typeof__(__arg3))) \ +[self methodForSelector:__swizzledSEL])(self, \ + _cmd, \ + __arg1, \ + __arg2, \ + __arg3) + +/** + * Invokes the original implementation from inside a swizzled implementation. Use this instead of + * INVOKE_ORIGINAL_IMP when the original selector takes four arguments. + * + * @param __returnType The return type of the original implementation. + * @param __swizzledSEL The selector used for swizzling. + * @param __arg1 The first argument to be passed to the original implementation. + * @param __arg2 The second argument to be passed to the original implementation. + * @param __arg3 The third argument to be passed to the original implementation. + * @param __arg4 The forth argument to be passed to the original implementation. + */ +#define INVOKE_ORIGINAL_IMP4(__returnType, \ + __swizzledSEL, \ + __arg1, \ + __arg2, \ + __arg3, \ + __arg4) \ +((__returnType(*)(id, \ + SEL, \ + __typeof__(__arg1), \ + __typeof__(__arg2), \ + __typeof__(__arg3), \ + __typeof__(__arg4))) \ +[self methodForSelector:__swizzledSEL])(self, \ + _cmd, \ + __arg1, \ + __arg2, \ + __arg3, \ + __arg4) + +/** + * Invokes the original implementation from inside a swizzled implementation. Use this instead of + * INVOKE_ORIGINAL_IMP when the original selector takes five arguments. + * + * @param __returnType The return type of the original implementation. + * @param __swizzledSEL The selector used for swizzling. + * @param __arg1 The first argument to be passed to the original implementation. + * @param __arg2 The second argument to be passed to the original implementation. + * @param __arg3 The third argument to be passed to the original implementation. + * @param __arg4 The forth argument to be passed to the original implementation. + * @param __arg5 The fifth argument to be passed to the original implementation. + */ +#define INVOKE_ORIGINAL_IMP5(__returnType, \ + __swizzledSEL, \ + __arg1, \ + __arg2, \ + __arg3, \ + __arg4, \ + __arg5) \ +((__returnType(*)(id, \ + SEL, \ + __typeof__(__arg1), \ + __typeof__(__arg2), \ + __typeof__(__arg3), \ + __typeof__(__arg4), \ + __typeof__(__arg5))) \ +[self methodForSelector:__swizzledSEL])(self, \ + _cmd, \ + __arg1, \ + __arg2, \ + __arg3, \ + __arg4, \ + __arg5) + +/** + * Invokes the original implementation from inside a swizzled implementation. Use this instead of + * INVOKE_ORIGINAL_IMP when the original selector takes sixth arguments. + * + * @param __returnType The return type of the original implementation. + * @param __swizzledSEL The selector used for swizzling. + * @param __arg1 The first argument to be passed to the original implementation. + * @param __arg2 The second argument to be passed to the original implementation. + * @param __arg3 The third argument to be passed to the original implementation. + * @param __arg4 The forth argument to be passed to the original implementation. + * @param __arg5 The fifth argument to be passed to the original implementation. + * @param __arg6 The sixth argument to be passed to the original implementation. + */ +#define INVOKE_ORIGINAL_IMP6(__returnType, \ + __swizzledSEL, \ + __arg1, \ + __arg2, \ + __arg3, \ + __arg4, \ + __arg5, \ + __arg6) \ +((__returnType(*)(id, \ + SEL, \ + __typeof__(__arg1), \ + __typeof__(__arg2), \ + __typeof__(__arg3), \ + __typeof__(__arg4), \ + __typeof__(__arg5), \ + __typeof__(__arg6))) \ +[self methodForSelector:__swizzledSEL])(self, \ + _cmd, \ + __arg1, \ + __arg2, \ + __arg3, \ + __arg4, \ + __arg5, \ + __arg6) + +/** + * Invokes the original implementation from inside a swizzled implementation. Use this instead of + * INVOKE_ORIGINAL_IMP when the original selector takes seven arguments. + * + * @param __returnType The return type of the original implementation. + * @param __swizzledSEL The selector used for swizzling. + * @param __arg1 The first argument to be passed to the original implementation. + * @param __arg2 The second argument to be passed to the original implementation. + * @param __arg3 The third argument to be passed to the original implementation. + * @param __arg4 The forth argument to be passed to the original implementation. + * @param __arg5 The fifth argument to be passed to the original implementation. + * @param __arg6 The sixth argument to be passed to the original implementation. + * @param __arg7 The seventh argument to be passed to the original implementation. + */ +#define INVOKE_ORIGINAL_IMP7(__returnType, \ + __swizzledSEL, \ + __arg1, \ + __arg2, \ + __arg3, \ + __arg4, \ + __arg5, \ + __arg6, \ + __arg7) \ +((__returnType(*)(id, \ + SEL, \ + __typeof__(__arg1), \ + __typeof__(__arg2), \ + __typeof__(__arg3), \ + __typeof__(__arg4), \ + __typeof__(__arg5), \ + __typeof__(__arg6), \ + __typeof__(__arg7))) \ +[self methodForSelector:__swizzledSEL])(self, \ + _cmd, \ + __arg1, \ + __arg2, \ + __arg3, \ + __arg4, \ + __arg5, \ + __arg6, \ + __arg7) diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYSyntheticEvents.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYSyntheticEvents.h new file mode 100644 index 0000000000..c1abbb6bde --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYSyntheticEvents.h @@ -0,0 +1,161 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - Error domain and codes + +GREY_EXTERN NSString *const kGREYSyntheticEventInjectionErrorDomain; + +/** + * Error codes for synthetic event injection failures. + */ +typedef NS_ENUM(NSInteger, GREYSyntheticEventInjectionErrorCode) { + kGREYOrientationChangeFailedErrorCode = 0, // Device orientation change has failed. +}; + +#pragma mark - Interface + +/** + * Utility to deliver user actions such as touches, taps, gestures and device rotation to the + * application under test + */ +@interface GREYSyntheticEvents : NSObject + +/** + * Rotate the device to a given @c deviceOrientation. All device orientations except for + * @c UIDeviceOrientationUnknown are supported. If a non-nil @c errorOrNil is provided, it will + * be populated with the failure reason if the orientation change fails, otherwise a test failure + * will be registered. + * + * @param deviceOrientation The desired orientation of the device. + * @param[out] errorOrNil Error that will be populated on failure. If @c nil, the a test + * failure will be reported if the rotation attempt fails. + * + * @throws GREYFrameworkException if the action fails and @c errorOrNil is @c nil. + * @return @c YES if the rotation was successful, @c NO otherwise. If @c errorOrNil is @c nil and + * the operation fails, it will throw an exception. + */ ++ (BOOL)rotateDeviceToOrientation:(UIDeviceOrientation)deviceOrientation + errorOrNil:(__strong NSError **)errorOrNil; + +/** + * Shakes the device. If a non-nil @c errorOrNil is provided, it will + * be populated with the failure reason if the orientation change fails, otherwise a test failure + * will be registered. + * + * @param[out] errorOrNil Error that will be populated on failure. If @c nil, the a test + * failure will be reported if the shake attempt fails. + * + * @throws GREYFrameworkException if the action fails and @c errorOrNil is @c nil. + * @return @c YES if the shake was successful, @c NO otherwise. If @c errorOrNil is @c nil and + * the operation fails, it will throw an exception. + */ ++ (BOOL)shakeDeviceWithError:(__strong NSError **)errorOrNil; + +/** + * Touch along a specified path in a @c CGPoint array. + * This method blocks until all touches are delivered. + * + * @param touchPath An array of @c CGPoints. The first point in @c touchPath is the point where + touch begins, and the last point in @c touchPath is the final touch point + where touch ends. Points in @c touchPath must be in @c window coordinates. + * @param window The UIWindow that contains the points in the @c touchPath where + * the touches are performed. Interaction will begin on the view inside + * @c window which passes the hit-test for the first point in @c touchPath. + * @param duration The time interval over which to space the touches evenly. If 0, all + * touches will be sent one after the other without any delay in-between them. + * @param expendable @c YES indicates if the touch path must be delivered with accurate timing even + * if a few touch objects (excluding the last one) have to be skipped, + * use it to model time sensitive gestures like swipes where timing is more + * important than accuracy. Is ignored if @c NO. + */ ++ (void)touchAlongPath:(NSArray *)touchPath + relativeToWindow:(UIWindow *)window + forDuration:(NSTimeInterval)duration + expendable:(BOOL)expendable; + +/** + * Injects a multi touch sequence specified by the array of @c touchPaths in the specified @c + * duration. + * Note that a single touch path is an array of CGPoint structs identifying the path taken by it + * relative to the specified @c window. Here @c expendable indicates if the touch path must be + * delivered with accurate timing even if a few touch objects (excluding the last one) have to be + * skipped. Use it to model time sensitive gestures like pinch where timing is more important than + * accuracy. + * + * @param touchPaths An array of @c touchpaths each of which are array of @c CGPoints. + * The first point in @c touchPath is the point where touch begins, and the last + * point in @c touchPath is the final touch point where touch ends. Points in @c + * touchPath Points in @c touchPath must be in @c window coordinates. + * @param window The UIWindow that contains the points in the @c touchPath where + * the touches are performed. Interaction will begin on the view inside + * @c window which passes the hit-test for the first point in @c touchPath. + * @param duration The time interval over which to space the touches evenly. If 0, all + * touches will be sent one after the other without any delay in-between them. + * @param expendable @c YES indicates if the touch path must be delivered with accurate timing even + * if a few touch objects (excluding the last one) have to be skipped, + * use it to model time sensitive gestures like swipes where timing is more + * important than accuracy. Is ignored if @c NO. + */ ++ (void)touchAlongMultiplePaths:(NSArray *)touchPaths + relativeToWindow:(UIWindow *)window + forDuration:(NSTimeInterval)duration + expendable:(BOOL)expendable; + +/** + * Begins interaction with a new touch starting at a specified point within a specified + * window's coordinates. + * + * @param point The point where the touch is to start. + * @param window The window that contains the coordinates of the touch points. + * @param immediate If @c YES, this method blocks until touch is delivered, otherwise the touch is + * enqueued for delivery the next time runloop drains. + */ +- (void)beginTouchAtPoint:(CGPoint)point + relativeToWindow:(UIWindow *)window + immediateDelivery:(BOOL)immediate; + +/** + * Continues the current interaction by moving touch to a new point. Providing the same point + * in consecutive calls is intepreted as stationary touches. While delivering these touch points, + * they may be buffered and during delivery if there are multiple stale touch points that + * are time sensitive some of them may be dropped. + * + * @param point The point to move the touch to. + * @param immediate If @c YES, this method blocks until touch is delivered, otherwise the touch is + * enqueued for delivery the next time runloop drains. + * @param expendable @c YES indicates that this touch point is intended to be delivered in a timely + * manner rather than reliably. Is ignored if @c NO. + */ +- (void)continueTouchAtPoint:(CGPoint)point + immediateDelivery:(BOOL)immediate + expendable:(BOOL)expendable; + +/** + * Ends interaction started by GREYSyntheticEvents::beginTouchAtPoint:relativeToWindow. + * This method will block until all the touches since the beginning of the interaction have been + * delivered. + */ +- (void)endTouch; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYTapAction.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYTapAction.h new file mode 100644 index 0000000000..4094bab0fe --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYTapAction.h @@ -0,0 +1,113 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A GREYAction that taps on a given element. + */ +@interface GREYTapAction : GREYBaseAction + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * @remark initWithName::constraints: is overridden from its superclass. + */ +- (instancetype)initWithName:(NSString *)name + constraints:(id)constraints NS_UNAVAILABLE; + +/** + * A GREYAction that taps the given element. + * + * @param tapType The type of tap to be performed. + * + * @return An instance of GREYTapAction, initialized with the tap type to be performed. + */ +- (instancetype)initWithType:(GREYTapType)tapType; + +/** + * A GREYAction that taps the given element for a given number of times. + * + * @param tapType The type of tap to be performed. + * @param numberOfTaps Number of times the element should be tapped. + * + * @return An instance of GREYTapAction, initialized with the tap type and + the number of times it should be performed. + */ +- (instancetype)initWithType:(GREYTapType)tapType numberOfTaps:(NSUInteger)numberOfTaps; + +/** + * A GREYAction that taps the given element for a given number of times at the given location. + * + * @param tapType The type of tap to be performed. + * @param numberOfTaps Number of times the element should be tapped. + * @param tapLocation The location to be tapped, relative to the view being tapped. + * + * @return An instance of GREYTapAction, initialized with the tap type and + the number of times it should be performed and the location to be tapped. + */ +- (instancetype)initWithType:(GREYTapType)tapType + numberOfTaps:(NSUInteger)numberOfTaps + location:(CGPoint)tapLocation; + +/** + * A GREYAction that performs a long press with a given duration. + * + * @param duration The duration of the long press. + * + * @return An instance of GREYTapAction, initialized with the duration of the long press. + */ +- (instancetype)initLongPressWithDuration:(CFTimeInterval)duration; + +/** + * A GREYAction that performs a long press with a given @c duration at the given @c location. + * + * @param duration The duration of the long press. + * @param location The location of the long press relative to the element recieving the touch + * event. + * + * @return An instance of GREYTapAction, initialized with the @c duration and @c location of + * the long press. + */ +- (instancetype)initLongPressWithDuration:(CFTimeInterval)duration location:(CGPoint)location; + +/** + * A GREYAction that performs a tap of the specified @c type for the speficied @c numberOfTaps at + * the @c location, with each tap in case of time based touch events like long press lasting for + * the given @c duration. + * + * @param tapType The type of the tap. + * @param numberOfTaps Number of times the element should be tapped. + * @param duration The duration of the tap event if applicable. + * @param tapLocation The location of the tap relative to the element recieving the touch + * event. + * + * @return An initialized (to the given parameters) instance of GREYTapAction. + */ +- (instancetype)initWithType:(GREYTapType)tapType + numberOfTaps:(NSUInteger)numberOfTaps + duration:(CFTimeInterval)duration + location:(CGPoint)tapLocation NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYTestCaseInvocation.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYTestCaseInvocation.h new file mode 100644 index 0000000000..770ce19aa4 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYTestCaseInvocation.h @@ -0,0 +1,23 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +/** + * Class used for invoking a test case method and updating the status of the test case + */ +@interface GREYTestCaseInvocation : NSInvocation +@end diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYTimedIdlingResource.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYTimedIdlingResource.h new file mode 100644 index 0000000000..394875ffd0 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYTimedIdlingResource.h @@ -0,0 +1,56 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * An idling resource that changes to busy state for a specified amount of time. + */ +@interface GREYTimedIdlingResource : NSObject + +/** + * An idling resouce for any @c object whose idleness is time-dependent. The resource reports + * busy until @c seconds has elapsed. + * + * This idling resource self-registers with GREYUIThreadExecutor on creation and deregisters when + * it idles or is forcefully stopped using GREYTimedIdlingResource::stopMonitoring. + * + * @param object The object to monitor. + * @param seconds The amount of time after which object will be in idle state. + * @param name A descriptive name for the idling resource. + * + * @return A new idling resource instance for @c object. + */ ++ (instancetype)resourceForObject:(NSObject *)object + thatIsBusyForDuration:(CFTimeInterval)seconds + name:(NSString *)name; + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * Forcefully stops monitoring. + * Subsequent invocations to GREYIdlingResource::isIdleNow return @c YES. + */ +- (void)stopMonitoring; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYTouchInfo.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYTouchInfo.h new file mode 100644 index 0000000000..4cc9d84b59 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYTouchInfo.h @@ -0,0 +1,82 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +/** + * An enum for what phase of a touch action a @c GREYTouchInfo object is in. + */ +typedef NS_ENUM(NSUInteger, GREYTouchInfoPhase) { + GREYTouchInfoPhaseTouchBegan, + GREYTouchInfoPhaseTouchMoved, + GREYTouchInfoPhaseTouchEnded, +}; + +NS_ASSUME_NONNULL_BEGIN + +/** + * An object to encapsulate essential information about a touch. + */ +@interface GREYTouchInfo : NSObject + +/** + * Points where touch should be delivered. + */ +@property(nonatomic, readonly) NSArray *points; + +/** + * The phase (began, moved etc) of the touch object. + */ +@property(nonatomic, assign) GREYTouchInfoPhase phase; + +/** + * Delays this touch for specified value since the last touch delivery. + */ +@property(nonatomic, readonly) NSTimeInterval deliveryTimeDeltaSinceLastTouch; +/** + * Indicates that this touch can be dropped if system delivering the touches experiences a + * lag causing it to miss the expected delivery time. + */ +@property(nonatomic, readonly, getter=isExpendable) BOOL expendable; + +/** + * Initializes this object to represent a touch at the the given @c points. + * + * @param points The CGPoints where the touches are to be delivered. + * @param phase The current phase of each touch point. + * @param timeDeltaSinceLastTouchSeconds The relative injection time from the time last + * touch point was injected. It is also used as the + * expected delivery time. + * @param expendable Used for time sensitive touches, it specified if the + * touch can be dropped if system lag causes the system to + * miss the expected delivery time. If @c NO, then the touch + * will be delivered regardless. + * + * @return An instance of GREYTouchInfo, initialized with all required data. + */ +- (instancetype)initWithPoints:(NSArray *)points + phase:(GREYTouchInfoPhase)phase + deliveryTimeDeltaSinceLastTouch:(NSTimeInterval)timeDeltaSinceLastTouchSeconds + expendable:(BOOL)expendable NS_DESIGNATED_INITIALIZER; + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYTouchInjector.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYTouchInjector.h new file mode 100644 index 0000000000..2951edafc2 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYTouchInjector.h @@ -0,0 +1,96 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import +#import "Event/GREYTouchInfo.h" + +/** + * The frequency at which touches will be injected per second. Currently set to 60Hz. + */ +GREY_EXTERN const NSTimeInterval kGREYTouchInjectionFrequency; + +/** + * State for touch injector. + */ +typedef NS_ENUM(NSInteger, GREYTouchInjectorState) { + /** + * Touch injection hasn't started yet. + */ + kGREYTouchInjectorPendingStart, + /** + * Injection has started injecting touches. + */ + kGREYTouchInjectorStarted, + /** + * Touch injection has stopped. This state is reached when injector has + * finished injecting all the queued touches. + */ + kGREYTouchInjectorStopped, +}; + +NS_ASSUME_NONNULL_BEGIN + +/** + * A touch injector that delivers a complete touch sequence for single finger interactions. + * Buffers all touch events until @c startInjecting: is called. + * Once injection is complete, this injector should be discarded. + */ +@interface GREYTouchInjector : NSObject +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * Initializes with the @c window to which touches will be delivered. + * + * @param window The window that receives the touches. + * + * @return An instance of GREYSingleSequenceTouchInjector, initialized with the window to be + * touched. + */ +- (instancetype)initWithWindow:(UIWindow *)window NS_DESIGNATED_INITIALIZER; + +/** + * Enqueues @c touchInfo that will be materialized into a UITouch and delivered to application. + * + * @param touchInfo The info that is used to create the UITouch. If it represents a last touch + * in a sequence, the specified @c point value is ignored and injector + * automatically picks the previous point where touch occured to deliver + * the last touch. + */ +- (void)enqueueTouchInfoForDelivery:(GREYTouchInfo *)touchInfo; + +/** + * @return The state of this injector. + */ +- (GREYTouchInjectorState)state; + +/** + * Starts delivering touches to current application. + */ +- (void)startInjecting; + +/** + * Wait until the touch injection has stopped. + */ +- (void)waitUntilAllTouchesAreDeliveredUsingInjector; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYTraversal.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYTraversal.h new file mode 100644 index 0000000000..8450491913 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYTraversal.h @@ -0,0 +1,68 @@ +// +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A private wrapper used to store information that is essential for printing the UI hierarchy + * appropriately and in correct order. + */ +@interface GREYTraversalObject : NSObject + +/** + * An NSUInteger representing the number of parent-child relationships from the root element + * to the current element. + */ +@property(nonatomic) NSUInteger level; + +/** + * The UI element that the GREYHierarchyObject is wrapped around. + */ +@property(nonatomic, strong) id element; + +@end + +/** + * Private class to traverse the UI Hierarchy. + * Provides helper methods to access the various elements present in the hierarchy. + */ +@interface GREYTraversal : NSObject + +/** + * Instance method that returns the next object from the hierarchy. Needs to be implemented by + * subclasses. This class provides an empty implementation. + * + * @return An instance of the UI element that is next in the hierarchy. + */ +- (id _Nullable)nextObject NS_UNAVAILABLE; + +/** + * Explores the immediate children of the @c element that is passed in. + * + * @param element The UI element whose children are to be explored. + * + * @return Creates a new array that contains the immediate children of @c element. The children are + * ordered from front to back, meaning subviews that were added first are present later + * in the array. If no children exist, then an empty array is returned. + */ +- (NSArray *)exploreImmediateChildren:(id)element; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYTraversalBFS.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYTraversalBFS.h new file mode 100644 index 0000000000..cb62983b6b --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYTraversalBFS.h @@ -0,0 +1,51 @@ +// +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "Traversal/GREYTraversal.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface GREYTraversalBFS : GREYTraversal + +/** + * Instance method that returns the next object from the hierarchy in a Breadth First Search + * fashion. + * + * @return An instance of the UI element that is next in the hierarchy. + */ +- (id _Nullable)nextObject; + +/** + * Class method to initialize the object. The hierarchy is unrolled in a BFS fashion and + * an internal representation is created. + * + * @param element Single UI element whose UI hierarchy is to be parsed. + * + * @return An instance of GREYTraversalBFS. + */ ++ (instancetype)hierarchyForElementWithBFSTraversal:(id)element; + +/** + * Enumerates through the entire hierarchy and calls the @c block on each element in the hierarchy. + * This method enumerates through the hierarchy only once. + * + * @param block A completion block that will be invoked on each element. + */ +- (void)enumerateUsingBlock:(void (^)(id view, NSUInteger level))block; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYTraversalDFS.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYTraversalDFS.h new file mode 100644 index 0000000000..0ba856d737 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYTraversalDFS.h @@ -0,0 +1,50 @@ +// +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "Traversal/GREYTraversal.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface GREYTraversalDFS : GREYTraversal + +/** + * Instance method that returns the next object from the hierarchy in a Depth First Search fashion. + * + * @return An instance of the UI element that is next in the hierarchy. + */ +- (id _Nullable)nextObject; + +/** + * Class method to initialize the object. The hierarchy is unrolled in a DFS fashion and + * an internal represenation is created. + * + * @param element Single UI element whose UI hierarchy needs to be unrolled. + * + * @return An instance of the GREYTraversalDFS class. + */ ++ (instancetype)hierarchyForElementWithDFSTraversal:(id)element; + +/** + * Enumerates through the entire hierarchy and calls the @c block on each element in the hierarchy. + * This method enumerates through the hierarchy only once. + * + * @param block A completion block that will be invoked on each element. + */ +- (void)enumerateUsingBlock:(void (^)(id view, NSUInteger level))block; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYUIThreadExecutor+Internal.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYUIThreadExecutor+Internal.h new file mode 100644 index 0000000000..6d804d7457 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYUIThreadExecutor+Internal.h @@ -0,0 +1,53 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file GREYUIThreadExecutor+Internal.h + * @brief Exposes GREYUIThreadExecutor interfaces and methods that are otherwise private for + * testing purposes. + */ + +#import + +@protocol GREYIdlingResource; + +NS_ASSUME_NONNULL_BEGIN + +@interface GREYUIThreadExecutor (Internal) + +/** + * Register the specified @c resource to be checked for idling before executing test actions. + * A strong reference is held to @c resource until it is deregistered using + * @c deregisterIdlingResource. It is safe to call this from any thread. + * + * @param resource The idling resource to register. + * + * @remark This is available only for internal testing purposes. + */ +- (void)registerIdlingResource:(id)resource; + +/** + * Unregisters a previously registered @c resource. It is safe to call this from any thread. + * + * @param resource The resource to unregistered. + * + * @remark This is available only for internal testing purposes. + */ +- (void)deregisterIdlingResource:(id)resource; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYUIWebViewDelegate.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYUIWebViewDelegate.h new file mode 100644 index 0000000000..0d22da51a3 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYUIWebViewDelegate.h @@ -0,0 +1,43 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import "Delegate/GREYSurrogateDelegate.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * A UIWebView delegate proxy used to intercept load requests for syncing. + */ +@interface GREYUIWebViewDelegate : GREYSurrogateDelegate + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * Creates an instance of GREYUIWebViewDelegate backed by the provided delegate. + * + * @param originalDelegate The original delegate being proxied. + * @return an instance of GREYUIWebViewDelegate backed by the original delegate. + */ +- (instancetype)initWithOriginalUIWebViewDelegate:(id)originalDelegate; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYUIWindowProvider.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYUIWindowProvider.h new file mode 100644 index 0000000000..609d2fbb7b --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYUIWindowProvider.h @@ -0,0 +1,84 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A provider for UIApplication windows. By default, all application windows are returned unless + * this provider is initialized with custom windows. + */ +@interface GREYUIWindowProvider : NSObject + +/** + * Class method to get a provider with the specified @c windows. + * + * @param windows An array of UIApplication windows to populate the provider. + * + * @return A GREYUIWindowProvider instance populated with the UIApplication windows in @c windows. + */ ++ (instancetype)providerWithWindows:(NSArray *)windows; + +/** + * Class method to get a provider with all the windows currently registed with the app. + * + * @return A GREYUIWindowProvider instance populated by all windows currently + * registered with the app. + */ ++ (instancetype)providerWithAllWindows; + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * Designated Initializer. + * + * @param windows UIApplication windows to populate the provider with. If @c windows is @c nil, it + will initialize this provider with all windows currently registered with the + app. Use initWithAllWindows constructor instead to make your intention explicit. + * + * @return A GREYUIWindowProvider instance, populated with the specified windows. + */ +- (instancetype)initWithWindows:(NSArray *_Nullable)windows NS_DESIGNATED_INITIALIZER; + +/** + * Initializes this provider with all application windows. + * + * @return A GREYUIWindowProvider instance populated by all windows currently + * registered with the app. + */ +- (instancetype)initWithAllWindows; + +/** + * + * @return A set of all application windows ordered by window-level from back to front. + */ ++ (NSArray *)allWindows; + +#pragma mark - GREYProvider + +/** + * + * @return An enumerator for @c windows populating the window provider. + */ +- (NSEnumerator *)dataEnumerator; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYVisibilityChecker.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYVisibilityChecker.h new file mode 100644 index 0000000000..640a07020d --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYVisibilityChecker.h @@ -0,0 +1,152 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +/** + * The minimum number of points that must be visible on an UI element for EarlGrey to consider it + * as visible to the user. + */ +extern const NSUInteger kMinimumPointsVisibleForInteraction; + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - GREYVisibilityDiffBuffer + +/** + * Data structure that holds a buffer representing the visible pixels of a visibility check diff. + */ +typedef struct GREYVisibilityDiffBuffer { + BOOL *data; + size_t width; + size_t height; +} GREYVisibilityDiffBuffer; + +/** + * Creates a diff buffer with the specified width and height. This method allocates a buffer of + * size: width * height, which must be released with GREYVisibilityDiffBufferRelease after being + * used. + * + * @param width The width of the diff buffer. + * @param height The height of the diff buffer. + */ +GREYVisibilityDiffBuffer GREYVisibilityDiffBufferCreate(size_t width, size_t height); + +/** + * Releases the underlying storage for the diff buffer. + * + * @param buffer The buffer whose storage is to be released. + */ +void GREYVisibilityDiffBufferRelease(GREYVisibilityDiffBuffer buffer); + +/** + * Returns the visibility status for the point at the given x and y coordinates. Returns @c YES if + * the point is visible, or @c NO if the point isn't visible or lies outside the buffer's bounds. + * + * @param buffer The buffer that is to be queried. + * @param x The x coordinate of the search point. + * @param y The y coordinate of the search point. + */ +BOOL GREYVisibilityDiffBufferIsVisible(GREYVisibilityDiffBuffer buffer, size_t x, size_t y); + +/** + * Changes the visibility value for the {@c x, @c y} position. If @c isVisible is @c YES the point + * is marked as visible else it is marked as not visible. + * + * @param buffer The buffer whose visibility is to be updated. + * @param x The x coordinate of the target point. + * @param y The y coordinate of the target point. + * @param isVisible A boolean that indicates the new visibility status (@c YES for visible, + @c NO otherwise) for the target point. + */ +void GREYVisibilityDiffBufferSetVisibility(GREYVisibilityDiffBuffer buffer, + size_t x, + size_t y, + BOOL isVisible); + +#pragma mark - GREYVisibilityChecker + +/** + * Data structure to hold information about visible pixels. + */ +typedef struct GREYVisiblePixelData { + /** The number of visible pixels. */ + NSUInteger visiblePixelCount; + /** + * A default pixel that's visible. + * If no pixel is visible -- i.e. the visiblePixelCount = 0, then this is set to CGPointNull. + */ + CGPoint visiblePixel; +} GREYVisiblePixelData; + +/** + * Checker for assessing the visibility of elements on screen as they appear to the user. + */ +@interface GREYVisibilityChecker : NSObject + +/** + * @return @c YES if no part of the @c element is visible to the user. + */ ++ (BOOL)isNotVisible:(_Nullable id)element; + +/** + * @return The percentage ([0,1] inclusive) of the area visible on the screen compared to @c + * element's accessibility frame. + */ ++ (CGFloat)percentVisibleAreaOfElement:(_Nullable id)element; + +/** + * @return @c YES if at least 10 (@c kMinimumPointsVisibleForInteraction) points are visible @b and + * the activation point of the given element is also visible, @c NO otherwise. + */ ++ (BOOL)isVisibleForInteraction:(_Nullable id)element; + +/** + * @return A visible point where a user can tap to interact with specified @c element, or + * @c GREYCGPointNull if there's no such point. + * @remark The returned point is relative to @c element's bound. + */ ++ (CGPoint)visibleInteractionPointForElement:(_Nullable id)element; + +/** + * @return The smallest rectangle enclosing the entire visible area of @c element in screen + * coordinates. If no part of the element is visible, CGRectZero will be returned. The + * returned rect is always in points. + */ ++ (CGRect)rectEnclosingVisibleAreaOfElement:(_Nullable id)element; + +/** + * @return The last known original image used by the visibility checker. + * + * @remark This is available only for internal testing purposes. + */ ++ (UIImage *_Nullable)grey_lastActualBeforeImage; +/** + * @return The last known actual color shifted image used by visibility checker. + * + * @remark This is available only for internal testing purposes. + */ ++ (UIImage *_Nullable)grey_lastActualAfterImage; +/** + * @return The last known actual color shifted image used by visibility checker. + * + * @remark This is available only for internal testing purposes. + */ ++ (UIImage *_Nullable)grey_lastExpectedAfterImage; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYZeroToleranceTimer.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYZeroToleranceTimer.h new file mode 100644 index 0000000000..09a3bd53cb --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/GREYZeroToleranceTimer.h @@ -0,0 +1,80 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +@class GREYZeroToleranceTimer; + +NS_ASSUME_NONNULL_BEGIN + +/** + * Protocol expected to be implemented by @c GREYZeroToleranceTimer's targets, the timer fire + * event is indicated by sending the appropriate messages of this protocol to the target. + */ +@protocol GREYZeroToleranceTimerTarget + +/** + * Invoked by @c GREYZeroToleranceTimer object when timeout fires. + * + * @param timer The timer whose timeout fired. + */ +- (void)timerFiredWithZeroToleranceTimer:(GREYZeroToleranceTimer *)timer; + +@end + +/** + * A high fidelity timer implementation (for example, to be used for delivering touches with + * accurate timing). For example, the following code sets up the timer to fire every one second: + * @code + * self.timerForFoo = [[GREYZeroToleranceTimer alloc] initWithInterval:1.0 target:foo]; + * @endcode + * Note that @c GREYZeroToleranceTimer objects create strong references to the provided targets + * therefore the following is perfectly legal as well: + * @code + * [[GREYZeroToleranceTimer alloc] initWithInterval:1.0 target:[[FooClass alloc] init]]; + * @endcode + * The the timer and the created FooClass object acting as a target will remain in memory until it + * invalidates the timer (this can be done from the code that is invoked on the timer fire event). + * Once invalidated both the timer and the object will deallocate. + */ +@interface GREYZeroToleranceTimer : NSObject + +/** + * @remark init is not an available initializer. Use the other initializers. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * Initializes and schedules a new zero tolerance timer. + * + * @param interval The timeout interval in seconds. + * @param target The target that should handle the timeouts. Targets must implement + * @c GREYZeroToleranceTimerTarget protocol as every time timer fires + * appropriate methods from the protocol will be invoked. + * + * @return An initialized and scheduled timer. + */ +- (instancetype)initWithInterval:(CFTimeInterval)interval + target:(id)target; + +/** + * Invalidates the timer and cancels all future timeouts. + */ +- (void)invalidate; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/NSError+GREYAdditions.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/NSError+GREYAdditions.h new file mode 100644 index 0000000000..580ff7b040 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/NSError+GREYAdditions.h @@ -0,0 +1,37 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Additions to NSError to facilitate error logging. + */ +@interface NSError (GREYAdditions) + +/** + * For a given error, create a description dictionary of the error. + * The description includes error's domain, error code and error description. + * + * @return A description dictionary for the given @c error. + */ + +- (NSDictionary *)grey_descriptionDictionary; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/NSObject+GREYAdditions.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/NSObject+GREYAdditions.h new file mode 100644 index 0000000000..50d0e2edd6 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/NSObject+GREYAdditions.h @@ -0,0 +1,100 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Additions to NSObject for obtaining details for UI and Accessibility Elements. + */ +@interface NSObject (GREYAdditions) + +/** + * Traverses up the accessibility tree and returns the immediate ancestor UIView or @c nil if none + * exists. + * @remark In the case of web accessibility elements the container web view is returned instead. + * + * @return The containing UIView object or @c nil if none was found. + */ +- (UIView *)grey_viewContainingSelf; + +/** + * @return The direct container of the element or @c nil if the element has no container. + */ +- (id)grey_container; + +/** + * Traverses up the element hierarchy returning all containers of type @c klass. When called on a + * non-UIView accessibility element, the accessibility container tree is traversed until the first + * UIView is encountered, at which point it switches to traversing the view hierarchy. + * + * @param klass The class the container being searched for. + * + * @return An array of all container objects. + */ +- (NSArray *)grey_containersAssignableFromClass:(Class)klass; + +/** + * @return The element's accessibilityActivationPoint converted to window coordinates. + */ +- (CGPoint)grey_accessibilityActivationPointInWindowCoordinates; + +/** + * @return The element's accessibility point relative to its accessibility frame's origin. + */ +- (CGPoint)grey_accessibilityActivationPointRelativeToFrame; + +/** + * @return @c YES if @c self is an accessibility element within a UIWebView, @c NO otherwise. + */ +- (BOOL)grey_isWebAccessibilityElement; + +/** + * @return A detailed description of the element, including accessibility attributes. + */ +- (NSString *)grey_description; + +/** + * @return A short description of the element, including its class, accessibility ID and label. + */ +- (NSString *)grey_shortDescription; + +/** + * @return The recursive description of the UI hierarchy for the current element. This should be + * used only with objects that are UIViews or UIAccessibilityElements. + */ +- (NSString *)grey_recursiveDescription; + +/** + * Swizzle a selector with a particular object after a specified delay time interval in a + * specific run loop mode. + * + * @param aSelector The selector to be swizzled. + * @param anArgument The object to swizzle the selector with. + * @param delay The NSTimeInterval after which the swizzling is to be done. + * @param modes The run loop mode to perform the swizzling in. + * + * @remark This is available only for internal testing purposes. + */ +- (void)greyswizzled_performSelector:(SEL)aSelector + withObject:(id)anArgument + afterDelay:(NSTimeInterval)delay + inModes:(NSArray *)modes; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/NSRunLoop+GREYAdditions.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/NSRunLoop+GREYAdditions.h new file mode 100644 index 0000000000..c672d6d563 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/NSRunLoop+GREYAdditions.h @@ -0,0 +1,23 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +/** + * EarlGrey specific additions to NSRunLoop to track run loop timers. + */ +@interface NSRunLoop (GREYAdditions) +@end diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/NSString+GREYAdditions.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/NSString+GREYAdditions.h new file mode 100644 index 0000000000..beb52b2f24 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/NSString+GREYAdditions.h @@ -0,0 +1,43 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * EarlGrey specific additions to NSString. + */ +@interface NSString (GREYAdditions) + +/** + * Returns @c YES if the current string is @b not an empty string (length = 0) after being trimmed + * for whitespaces and newline characters. + * @remark Since it is valid to send this message to @c nil instances, we use @c isNonEmpty instead + * of @c isEmpty to return a valid result (@c NO). + * + * @return @c NO if current string is empty, @c YES otherwise. + */ +- (BOOL)grey_isNonEmptyAfterTrimming; + +/** + * @return A string with the MD5 hash of the given input @c string. + */ +- (NSString *)grey_md5String; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/NSTimer+GREYAdditions.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/NSTimer+GREYAdditions.h new file mode 100644 index 0000000000..99dfc160fc --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/NSTimer+GREYAdditions.h @@ -0,0 +1,23 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +/** + * EarlGrey specific additions to NSTimer to track timer events. + */ +@interface NSTimer (GREYAdditions) +@end diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/NSURL+GREYAdditions.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/NSURL+GREYAdditions.h new file mode 100644 index 0000000000..221fde4ec1 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/NSURL+GREYAdditions.h @@ -0,0 +1,37 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NSURL (GREYAdditions) + +/** + * Add @c regEx to the list of framework blacklisted URLs. + * + * @param regEx A regular expression representing a URL to blacklist from the tracking system. + */ ++ (void)grey_addBlacklistRegEx:(NSString *)regEx; + +/** + * @return @c YES if EarlGrey must synchronize with this url, @c NO otherwise. + */ +- (BOOL)grey_shouldSynchronize; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/NSURLConnection+GREYAdditions.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/NSURLConnection+GREYAdditions.h new file mode 100644 index 0000000000..28b05bbc3e --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/NSURLConnection+GREYAdditions.h @@ -0,0 +1,40 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Additions to NSURLConnection to allow EarlGrey to track status for every connection. By + * default, EarlGrey tracks all NSURLConnection's, to change this behavior update GREYConfiguration + * setting with @c kGREYConfigKeyURLBlacklistRegex key. + */ +@interface NSURLConnection (GREYAdditions) + +/** + * Tracks the current connection as pending in GREYAppStateTracker. + */ +- (void)grey_trackPending; + +/** + * Untracks the current connection from GREYAppStateTracker, marking it as completed. + */ +- (void)grey_untrackPending; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/NSURLSession+GREYAdditions.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/NSURLSession+GREYAdditions.h new file mode 100644 index 0000000000..c53e2f22b6 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/NSURLSession+GREYAdditions.h @@ -0,0 +1,24 @@ +// +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +/** + * Additions to NSURLSession to enable EarlGrey to synchronize with NSURLSessionTasks that execute + * network requests. + */ +@interface NSURLSession (GREYAdditions) +@end diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UIAnimation+GREYAdditions.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UIAnimation+GREYAdditions.h new file mode 100644 index 0000000000..71d8da12ca --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UIAnimation+GREYAdditions.h @@ -0,0 +1,24 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +/** + * EarlGrey additions for UIAnimation, UIKit's internal representation of animations used by some + * of its components, such as UIScrollView. + */ +@interface UIAnimation_GREYAdditions : NSObject +@end diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UIApplication+GREYAdditions.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UIApplication+GREYAdditions.h new file mode 100644 index 0000000000..6003cf79be --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UIApplication+GREYAdditions.h @@ -0,0 +1,34 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * EarlGrey specific additions for tracking runloop mode changes and user interaction events. + */ +@interface UIApplication (GREYAdditions) + +/** + * @return Active mode for the main runloop that was pushed by one of the push runloop methods. + * May return @c nil when no mode was pushed. + */ +- (NSString *_Nullable)grey_activeRunLoopMode; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UIGestureRecognizer+GREYAdditions.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UIGestureRecognizer+GREYAdditions.h new file mode 100644 index 0000000000..363c2bfcbc --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UIGestureRecognizer+GREYAdditions.h @@ -0,0 +1,23 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +/** + * Additions that allow EarlGrey to synchronize with UIGestureRecognizers. + */ +@interface UIGestureRecognizer (GREYAdditions) +@end diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UIScrollView+GREYAdditions.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UIScrollView+GREYAdditions.h new file mode 100644 index 0000000000..0b39a5ff46 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UIScrollView+GREYAdditions.h @@ -0,0 +1,38 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * EarlGrey specific additions for tracking UIScrollView events (like scrolling, bouncing etc). + */ +@interface UIScrollView (GREYAdditions) + +/** + * Returns @c YES if the scroll view is exerting resistance to scroll, since scroll views that do + * not have bounce enabled cannot detect resistance unless some scroll is applied, the output of + * this method only makes sense in the middle of a scroll action. + * @remark This method has limited accuracy when used with scroll views having bounce disabled, + * please see the implementation for more details. + * + * @return @c YES if the scroll view is exerting resistance to scroll, @c NO otherwise. + */ +- (BOOL)grey_hasScrollResistance; +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UISwitch+GREYAdditions.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UISwitch+GREYAdditions.h new file mode 100644 index 0000000000..22f126e848 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UISwitch+GREYAdditions.h @@ -0,0 +1,35 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Additions for the UISwitch class. + */ +@interface UISwitch (GREYAdditions) + +/** + * @param onState The specified switch state. + * + * @return A string representation of the specified switch state. + */ ++ (NSString *)grey_stringFromOnState:(BOOL)onState; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UITouch+GREYAdditions.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UITouch+GREYAdditions.h new file mode 100644 index 0000000000..68b3eb6d9a --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UITouch+GREYAdditions.h @@ -0,0 +1,35 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface UITouch (GREYAdditions) + +/** + * Creates a fake touch at @c point in window coordinates of the given @c window. + * + * @param point The location of this touch in window coordinates. + * @param window The reference window used for coordinates passed as @c point. + * + * @return An initialized UITouch object + */ +- (id)initAtPoint:(CGPoint)point relativeToWindow:(UIWindow *)window; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UIView+GREYAdditions.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UIView+GREYAdditions.h new file mode 100644 index 0000000000..f3feb60270 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UIView+GREYAdditions.h @@ -0,0 +1,70 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * EarlGrey specific additions for traversing and manipulating UIViews. + */ +@interface UIView (GREYAdditions) + +/** + * @param klass The target class of subviews. + * + * @return A breadth-first / level ordered array of subviews that can be safely casted to @c klass. + */ +- (NSArray *)grey_childrenAssignableFromClass:(Class)klass; + +/** + * Makes sure that subview @c view is always on top, even if other subviews are added in front of + * it. Also keeps the @c view's frame fixed to the current value so parent can't change it. + * + * @param view The view to keep as the top-most fixed subview. + */ +- (void)grey_keepSubviewOnTopAndFrameFixed:(UIView *)view; + +/** + * Makes this view and all its super view opaque. Successive calls to this method will replace + * the previously stored alpha value, causing any saved value to be lost. + * + * @remark Each invocation will save the current alpha value which can be restored by calling + * -[UIView grey_restoreOpacity] + */ +- (void)grey_recursivelyMakeOpaque; + +/** + * Restores the opacity of this view and it's super views if they were made opaque by calling + * -[UIView grey_recursivelyMakeOpaque]. If -[UIView grey_recursivelyMakeOpaque] was not + * called before, then this method will perform a no-op on each of the view's superviews. + */ +- (void)grey_restoreOpacity; + +/** + * Quick check to see if a view meets the basic criteria for visibility: + * 1) Not hidden + * 2) Visible with a minimum alpha + * 3) Valid accessibility frame. + * + * Also checks to if a view is not a subview of another view or window that has a + * translucent alpha value or is hidden. + */ +- (BOOL)grey_isVisible; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UIViewController+GREYAdditions.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UIViewController+GREYAdditions.h new file mode 100644 index 0000000000..aaafcb519f --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UIViewController+GREYAdditions.h @@ -0,0 +1,36 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface UIViewController (GREYAdditions) + +/** + * Tracks this view controller as the root view controller of @c window, setting up the desired + * states so that EarlGrey can decide when to wait for this view controller to appear. This method + * should be called each time window's @c hidden property changes. Passing @c nil for @c window + * indicates this view controller is no longer a root view controller. + * @todo Use KVO for the hidden property. + * + * @param window The window to which to associate this view controller as the root view controller. + */ +- (void)grey_trackAsRootViewControllerForWindow:(UIWindow *_Nullable)window; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UIWebView+GREYAdditions.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UIWebView+GREYAdditions.h new file mode 100644 index 0000000000..824c48ad5d --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UIWebView+GREYAdditions.h @@ -0,0 +1,63 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Additions that allow EarlGrey to sync with UIWebView load requests. + */ +@interface UIWebView (GREYAdditions) + +/** + * Explicitly clears the pending interaction state for UIWebViews. + */ +- (void)grey_clearPendingInteraction; + +/** + * Will mark the UIWebView's state as busy waiting for interaction until @c seconds have elapsed or + * UIWebView::grey_clearPendingInteraction is called (whichever comes first). + * + * @param seconds Time interval in seconds for which to mark the UIWebView as busy. + */ +- (void)grey_pendingInteractionForTime:(NSTimeInterval)seconds; + +/** + * Marks webview as pending load in GREYAppStateTracker. + */ +- (void)grey_trackAJAXLoading; + +/** + * Untracks webview loading state from GREYAppStateTracker. + */ +- (void)grey_untrackAJAXLoading; + +/** + * Sets the loading state for this webview. + * + * @param loading BOOL value indicating the new loading state of this webview. + */ +- (void)grey_setIsLoadingFrame:(BOOL)loading; + +/** + * @return the loading state for this webview. + */ +- (BOOL)grey_isLoadingFrame; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UIWindow+GREYAdditions.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UIWindow+GREYAdditions.h new file mode 100644 index 0000000000..1c660c6326 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/UIWindow+GREYAdditions.h @@ -0,0 +1,20 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +@interface UIWindow (GREYAdditions) +@end diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/XCTestCase+GREYAdditions.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/XCTestCase+GREYAdditions.h new file mode 100644 index 0000000000..d5633bac87 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/XCTestCase+GREYAdditions.h @@ -0,0 +1,134 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Posted immediately prior to XCTestCase::setUp. The @c userInfo dictionary contains + * the executing XCTestCase. + */ +UIKIT_EXTERN NSString *const kGREYXCTestCaseInstanceWillSetUp; + +/** + * Posted immediately after XCTestCase::setUp is called. The @c userInfo dictionary contains the + * executing XCTestCase. + */ +UIKIT_EXTERN NSString *const kGREYXCTestCaseInstanceDidSetUp; + +/** + * Posted immediately prior to XCTestCase::tearDown. The @c userInfo dictionary contains + * the executing XCTestCase. + */ +UIKIT_EXTERN NSString *const kGREYXCTestCaseInstanceWillTearDown; + +/** + * Posted immediately after XCTestCase::tearDown is called. The @c userInfo dictionary contains + * the executing XCTestCase. + */ +UIKIT_EXTERN NSString *const kGREYXCTestCaseInstanceDidTearDown; + +/** + * Posted immediately after XCTestCase::invokeTest is executed successfully, denoting that the + * test has passed. The @c userInfo dictionary contains the executing XCTestCase. + */ +UIKIT_EXTERN NSString *const kGREYXCTestCaseInstanceDidPass; + +/** + * Posted immediately after XCTestCase::invokeTest raises an Exception, denoting that the test has + * failed. The @c userInfo dictionary contains the executing XCTestCase. + */ +UIKIT_EXTERN NSString *const kGREYXCTestCaseInstanceDidFail; + +/** + * Posted immediately after a XCTestCase finishes, successfully or not. The @c userInfo dictionary + * contains the executing XCTestCase. + */ +UIKIT_EXTERN NSString *const kGREYXCTestCaseInstanceDidFinish; + +/** + * Key for retrieving the current XCTestCase from the @c userInfo of a notification. + */ +UIKIT_EXTERN NSString *const kGREYXCTestCaseNotificationKey; + +/** + * Enumeration with the possible statuses of an XCTestCase. + */ +typedef NS_ENUM(NSUInteger, GREYXCTestCaseStatus) { + kGREYXCTestCaseStatusUnknown = 0, + kGREYXCTestCaseStatusPassed, + kGREYXCTestCaseStatusFailed, +}; + +/** + * Extends XCTestCase with capabilities to return current testcase and allows observing various + * states of test execution. Also allows clearing various states that can leak across from one + * testcase to another. + */ +@interface XCTestCase (GREYAdditions) + +/** + * @return The current XCTestCase being executed or @c nil if called outside the context of a test + * method. + */ ++ (XCTestCase *)grey_currentTestCase; + +/** + * @return The name of the current test method being executed or @c nil if called outside the + * context of a test method. + */ +- (NSString *)grey_testMethodName; + +/** + * @return The name of the test class to which this message was sent. + */ +- (NSString *)grey_testClassName; + +/** + * @return The status (passed, failed, unknown) of this test. + */ +- (GREYXCTestCaseStatus)grey_status; + +/** + * Interrupts the current test case execution immediately and triggers XCTest's error handling + * mechanism to invoke the appropriate methods to tear down the test. + * + * @param line Line number at which the failure occured. + * @param file Name of the file in which the failure occured. + * @param description Full description of the failure. + */ +- (void)grey_markAsFailedAtLine:(NSUInteger)line + inFile:(NSString *)file + description:(NSString *)description; + +/** + * @return A unique test outputs directory for the current test. All test related outputs should be + * under this directory (and subdirectories). + */ +- (NSString *)grey_localizedTestOutputsDirectory; + +/** + * Sets the value for the test status. + * + * @param status The new object-association value for the test status. + */ +- (void)grey_setStatus:(GREYXCTestCaseStatus)status; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/_UIModalItemsPresentingViewController_GREYAdditions.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/_UIModalItemsPresentingViewController_GREYAdditions.h new file mode 100644 index 0000000000..172b6f71e4 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/_UIModalItemsPresentingViewController_GREYAdditions.h @@ -0,0 +1,26 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +/** + * Private iOS class that doesn't call through to @code [super viewWillDisappear:] @endcode. + * Without this, EarlGrey is unable to synchronize with disappearance of views of this controller. + * + * @remark This is fixed in iOS 9. + */ +@interface _UIModalItemsPresentingViewController_GREYAdditions : NSObject +@end diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/__NSCFLocalDataTask_GREYAdditions.h b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/__NSCFLocalDataTask_GREYAdditions.h new file mode 100644 index 0000000000..33e297315c --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/PrivateHeaders/__NSCFLocalDataTask_GREYAdditions.h @@ -0,0 +1,45 @@ +// +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Additions to NSURLSessionTask to allow EarlGrey to track status for every network request. By + * default EarlGrey tracks all URLs. To change this behavior, add blacklisted URL regex's to + * @c GREYConfiguration with key @c kGREYConfigKeyURLBlacklistRegex. + */ +@interface __NSCFLocalDataTask_GREYAdditions : NSObject + +/** + * Tracks the network task so that EarlGrey waits for its completion. + */ +- (void)grey_track; + +/** + * Un-tracks the network task so that EarlGrey does not wait for it anymore. + */ +- (void)grey_untrack; + +/** + * Marks the network task as an ignored request so that EarlGrey does not wait on it. + */ +- (void)grey_neverTrack; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/_CodeSignature/CodeResources b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/_CodeSignature/CodeResources new file mode 100644 index 0000000000..52ac45a440 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/EarlGrey.framework/_CodeSignature/CodeResources @@ -0,0 +1,1891 @@ + + + + + files + + Headers/EarlGrey.h + + u/N7PXpoL6KDGUXHG9CZ4F9NgU8= + + Headers/EarlGreyImpl.h + + Z0pRP3yP3cqFS6lUhhMMPJ+uDjo= + + Headers/GREYAction.h + + ofCDUTLXE3PWXzqCXmLJjFQqiYY= + + Headers/GREYActionBlock.h + + 1Yfqd+56feO4hvc41uYw3xOYg1M= + + Headers/GREYActions.h + + iebEFM6U5oElUbP2LgwCnqrihf0= + + Headers/GREYAllOf.h + + KAUu8k5Zji4EP4wElKdeY7cdalI= + + Headers/GREYAnyOf.h + + MYHz3aXwG4SiuNHd8nsF8RHyybY= + + Headers/GREYAssertion.h + + haEFAIr3uoCcYdgTORc1g6zdsik= + + Headers/GREYAssertionBlock.h + + MI27j9Skp7L+I2VGjtt0SS/F8Fc= + + Headers/GREYAssertionDefines.h + + lD8bmNBx/ixp0CmgZqu4WOC8vwM= + + Headers/GREYAssertions.h + + rB1Lxuskfr9xQY3AqXjDX+Dsg4A= + + Headers/GREYBaseAction.h + + EChl/NxZYfYCXBja5f1gIfwETuA= + + Headers/GREYBaseMatcher.h + + gwKPWxAElvWAqKaE45afa1LZ2yQ= + + Headers/GREYCondition.h + + 9ckqk15ZpohKMPtWfE1kO4dG3ws= + + Headers/GREYConfiguration.h + + fRWv3hsNEAWP8cstF8GbPt00P34= + + Headers/GREYConstants.h + + 9apjZAxy6v8aZTP5GH3WrIV3d9Y= + + Headers/GREYDataEnumerator.h + + iCg8QFCjxeFEflPcFrt4wjxUbqM= + + Headers/GREYDefines.h + + XnZ2EXBD68YZHMQDpsfsEpwyCF4= + + Headers/GREYDescription.h + + m/sDvnWc4a8q7a8LtfpZHZ5tM48= + + Headers/GREYDispatchQueueIdlingResource.h + + lHq2cJ4RQNjWpbP1I1bwiPVXUSY= + + Headers/GREYElementFinder.h + + rC/0nb/2lY+OpwUg1o4Grmh6cvI= + + Headers/GREYElementHierarchy.h + + cMiPnS43FNiZO7qXXGgtyqjRCUQ= + + Headers/GREYElementInteraction.h + + wajQJHMA4/ISywVB59E4UcKAaiQ= + + Headers/GREYElementMatcherBlock.h + + cLEM9WcQDBlOYNgZzG5641jEKmE= + + Headers/GREYFailureHandler.h + + hIPCdLZkYBiuViRtUc4Sc8qFDO4= + + Headers/GREYFrameworkException.h + + +juebaDYjJEo9i7gFvZuDU5Dexk= + + Headers/GREYIdlingResource.h + + IyOH81wc/yp9pvs2uAbmlJduwwQ= + + Headers/GREYInteraction.h + + 1De2+d0IxBIGLDJgT3lJMV/O5+w= + + Headers/GREYLayoutConstraint.h + + t+eGWv43AXeRLQ+IQPlnpuoI9Mg= + + Headers/GREYManagedObjectContextIdlingResource.h + + L/QDcRC/4EyAvQofEWnTjN5r39U= + + Headers/GREYMatcher.h + + CAMueQYt3xizNb0t+sKJz3e1dJQ= + + Headers/GREYMatchers.h + + UDkXORSvz9BYce6Rl0STjhXqkJo= + + Headers/GREYNSTimerIdlingResource.h + + v0+vDNj3L0hRtsttHAx0oy54B4c= + + Headers/GREYNot.h + + TS0nBp36HsOvzu3fCkKrStYHy1w= + + Headers/GREYOperationQueueIdlingResource.h + + aUcXbXHM2irAYU0AomMHhB9WrrI= + + Headers/GREYProvider.h + + rCqYagyW62sUDG7pqhZ+cI126KQ= + + Headers/GREYScreenshotUtil.h + + vcK/gpEzmSVFOBRgifLwibea2OA= + + Headers/GREYScrollActionError.h + + JVuWV54MjqejOz+foBP4euLSAPk= + + Headers/GREYSyncAPI.h + + sQAbPBWWJmTIdxwynwq0f+TtVTw= + + Headers/GREYTestHelper.h + + sxa8xt8gFVZcZscjKY1NaDbuTjE= + + Headers/GREYUIThreadExecutor.h + + IX0lcwuGnN2BBRgKntz4UeAUSN0= + + Info.plist + + kp7WkbPTSlJ1v6H/ySzOLVIJ+NE= + + Modules/module.modulemap + + VSBF30YAA7ws/xF/KgbL5CmWI+E= + + PrivateHeaders/CAAnimation+GREYAdditions.h + + hyHN5VJwsZHtZtFiBlhWiknUwQs= + + PrivateHeaders/CALayer+GREYAdditions.h + + DrbBo1P45BJwghXif6cLY0ID+RY= + + PrivateHeaders/CGGeometry+GREYAdditions.h + + tt/9Fc0Rr2OY0oD/cwFooPr+V+4= + + PrivateHeaders/GREYActions+Internal.h + + XbF0VjVWyriz15G8Mn+UScL/kaQ= + + PrivateHeaders/GREYAnalytics.h + + 9rhiEB0OLgmG9Vh7H0LUNkICJ+M= + + PrivateHeaders/GREYAnalyticsDelegate.h + + vs0XUlK6IDwiRpCdo9O5wEM0thw= + + PrivateHeaders/GREYAppStateTracker.h + + r/HjO1b6iCkf6vSmrhdJU1jEZXk= + + PrivateHeaders/GREYAppStateTrackerObject.h + + 6uWfWgO3RvnaMHR3Q91e/Knui2E= + + PrivateHeaders/GREYAppleInternals.h + + ngObJXcoLT+zoPUulksCfjFfSws= + + PrivateHeaders/GREYAssertions+Internal.h + + 0EMLB1HUan26fKceVS9enwcEmbA= + + PrivateHeaders/GREYCAAnimationDelegate.h + + pVjo18c9joHUkrB8uitEoI+PGZg= + + PrivateHeaders/GREYChangeStepperAction.h + + hfztKpDfxh6u6D1GM5pzH/ISgBM= + + PrivateHeaders/GREYDispatchQueueTracker.h + + X6IdLgLmqTsRRAMSE083rWdFO7U= + + PrivateHeaders/GREYElementInteraction+Internal.h + + eiE6abWRD2rpdQJLlrptI+9h8Sw= + + PrivateHeaders/GREYElementProvider.h + + +jm5+GpI+s3cK7AWd1DJyuvKZs8= + + PrivateHeaders/GREYError+Internal.h + + MAPdLs2w27nJfCylnAuyZT1tNR8= + + PrivateHeaders/GREYError.h + + yg5+lc17ZEJx6u2DZ2u75CRWJZ8= + + PrivateHeaders/GREYErrorConstants.h + + smT2nN+9Z/42etrQHoaIbytauIg= + + PrivateHeaders/GREYFailureFormatter.h + + bgk3GOACqxfiDYxCisL1NRGs3qc= + + PrivateHeaders/GREYFailureScreenshotter.h + + X9kQxlrbQ3aqHs3dhzbXgyanL3Q= + + PrivateHeaders/GREYInteractionDataSource.h + + 88H2rHBwkwOTf9GFVlHtdkaFs/M= + + PrivateHeaders/GREYKeyboard.h + + sKnZGGq0h/dh3hI6jGRvoSAd+cg= + + PrivateHeaders/GREYLogger.h + + +BOiQ//4jrGNc+P75BYDQm3fIdU= + + PrivateHeaders/GREYMultiFingerSwipeAction.h + + 75Vc3HuPveNem3Rj1L2BbApKWk4= + + PrivateHeaders/GREYNSURLConnectionDelegate.h + + yLzIw9MZytRxHNdlDOtwTQJm5oE= + + PrivateHeaders/GREYObjcRuntime.h + + vYosx7+Bk6606SQXxC9jHQ7f+Tw= + + PrivateHeaders/GREYObjectDeallocationTracker.h + + wH8Rt30Em5YAstmTUaBdA0CkBAk= + + PrivateHeaders/GREYObjectFormatter.h + + EqT/az4Ni3JSFpXerExHezvUWzs= + + PrivateHeaders/GREYPathGestureUtils.h + + b6YPyGUGy3e0C2FyahkDUwRqRJA= + + PrivateHeaders/GREYPickerAction.h + + JGkkwgOtDCoFiLdtkA9ibvToU8Y= + + PrivateHeaders/GREYPinchAction.h + + 4ceJ8OkYU2j2+V0wocsAI8lUATc= + + PrivateHeaders/GREYRunLoopSpinner.h + + I4TL8ijbBLCJvmtyHn/hGuRQiFE= + + PrivateHeaders/GREYScreenshotUtil+Internal.h + + bh09uClpC/+jZ+FqQIB4YJGGeh8= + + PrivateHeaders/GREYScrollAction.h + + YqYfBVbVUV9jI9BYTIIx5aKIEMY= + + PrivateHeaders/GREYScrollToContentEdgeAction.h + + xJq30ebBFQaQjVrwUieeJpBL1Q0= + + PrivateHeaders/GREYSlideAction.h + + ikpFqhSqlETAsgQS9k59tAIUrKk= + + PrivateHeaders/GREYStopwatch.h + + 45lmv1rkwKSz+MXUgvGbnGnqbvg= + + PrivateHeaders/GREYStringDescription.h + + LZ4YHUJsZ0GBAFoLqh52Ku0a5+E= + + PrivateHeaders/GREYSurrogateDelegate.h + + T1zefgnsKS2cU0AfvxmbFL6aMqg= + + PrivateHeaders/GREYSwipeAction.h + + ORooqPFb+Z4/z/cbxizBbyZMlVA= + + PrivateHeaders/GREYSwizzler.h + + A1YScxqciQnCNdEg/awvHt6r+UU= + + PrivateHeaders/GREYSyntheticEvents.h + + 7wWfv4QI4YN9F5JMgdZPsb/gL2U= + + PrivateHeaders/GREYTapAction.h + + ZSBpMaOq5/ddza2r1QoPxKptX4M= + + PrivateHeaders/GREYTestCaseInvocation.h + + tnuX4BzrnE0v9iRLNuz/lCHUMSI= + + PrivateHeaders/GREYTimedIdlingResource.h + + 331HuPKdzLPxzb9Hm2DHOn3SGFs= + + PrivateHeaders/GREYTouchInfo.h + + 4DRNyA+KkHJWIiTB4ohWcozeJeQ= + + PrivateHeaders/GREYTouchInjector.h + + Zej1xAdkaeHMdE+E0B+j77OGxgQ= + + PrivateHeaders/GREYTraversal.h + + wzTNGqszktAO18lUYpT20upw/d4= + + PrivateHeaders/GREYTraversalBFS.h + + Ava89zTGIHQQqNEQdGgdr0I9oE0= + + PrivateHeaders/GREYTraversalDFS.h + + CZ6CBifTvuuy4382KQQhgH3jER8= + + PrivateHeaders/GREYUIThreadExecutor+Internal.h + + oMjm4Q7Ev7swhKzN2w1UHzH53u0= + + PrivateHeaders/GREYUIWebViewDelegate.h + + sPDhZLBQ2tCx1GqLJmpSpl9WzpY= + + PrivateHeaders/GREYUIWindowProvider.h + + ouqic3bv57sPLFj/s/+8nhVMnD4= + + PrivateHeaders/GREYVisibilityChecker.h + + 4yrfctRQ6pj5UZSbLtfzCV56xho= + + PrivateHeaders/GREYZeroToleranceTimer.h + + dWnY8aWbAHzXYoYkcpONs/ZAlkQ= + + PrivateHeaders/NSError+GREYAdditions.h + + cHRrUi2UFknRO0NkpACC56XLHtI= + + PrivateHeaders/NSObject+GREYAdditions.h + + hVH8HA6vtt8wiWoY1eQUFh7C+jE= + + PrivateHeaders/NSRunLoop+GREYAdditions.h + + JGAXDlvL3EKQH4Wyzqrcn9eHIV4= + + PrivateHeaders/NSString+GREYAdditions.h + + ZiU2GaaqlklwfbtS2h1rhiHKF44= + + PrivateHeaders/NSTimer+GREYAdditions.h + + VxQDN4X+sHQXCrGis4zlCH1Vm9Y= + + PrivateHeaders/NSURL+GREYAdditions.h + + YJ8d1OWqW1Du6nCO0xO6/MnTUgo= + + PrivateHeaders/NSURLConnection+GREYAdditions.h + + dMd2sAWeUmHlXj1DVoI/f2cQcZU= + + PrivateHeaders/NSURLSession+GREYAdditions.h + + vgHLKMZ38RaygzS8xxkMO0qA+7I= + + PrivateHeaders/UIAnimation+GREYAdditions.h + + UUohwVgp7Y7vU5Bqfl78Yu/iHUA= + + PrivateHeaders/UIApplication+GREYAdditions.h + + 8+uctukvHJjafkkwhuQMJV82MUM= + + PrivateHeaders/UIGestureRecognizer+GREYAdditions.h + + jpZjBAYe5mllIyIQ+IilQgACjcU= + + PrivateHeaders/UIScrollView+GREYAdditions.h + + 7rfFZgitTzT8GtHI0C3v78ieqyM= + + PrivateHeaders/UISwitch+GREYAdditions.h + + xvb4kCBQLLFMh3dfE+GalK9UMFo= + + PrivateHeaders/UITouch+GREYAdditions.h + + ypoC3kZPi2cIUg2XdQ/GDq72xtc= + + PrivateHeaders/UIView+GREYAdditions.h + + Jy1IVTeWGFBuuGazdV8aK9dmbVg= + + PrivateHeaders/UIViewController+GREYAdditions.h + + jAQvW8LxB8lh0JL7Dy1fk0LKWJ8= + + PrivateHeaders/UIWebView+GREYAdditions.h + + I1KljzRASrqkESKEXgYpC5R5rgw= + + PrivateHeaders/UIWindow+GREYAdditions.h + + zHfrdFLkIk3OEzvb5X116vrk9es= + + PrivateHeaders/XCTestCase+GREYAdditions.h + + om1dVcUouigo2WWhWTbsA3Qddb8= + + PrivateHeaders/_UIModalItemsPresentingViewController_GREYAdditions.h + + mhL8447azlxmehD057J/J8IE+nE= + + PrivateHeaders/__NSCFLocalDataTask_GREYAdditions.h + + JP+etF8YrlmpT19Kifpo92ST9O0= + + + files2 + + Headers/EarlGrey.h + + hash + + u/N7PXpoL6KDGUXHG9CZ4F9NgU8= + + hash2 + + +djQ+WWYcFxYwzTEuGU9TU4s9h4m/EI90yukssCnOsE= + + + Headers/EarlGreyImpl.h + + hash + + Z0pRP3yP3cqFS6lUhhMMPJ+uDjo= + + hash2 + + OMOuuy7jRsq3Bpt9lQeE6pYIMEc+m6G95wEzox1nZXc= + + + Headers/GREYAction.h + + hash + + ofCDUTLXE3PWXzqCXmLJjFQqiYY= + + hash2 + + xWHcDSZQNbj+tMGsJ5ovIGEO6wiqA0yGlJMjjgBOhdM= + + + Headers/GREYActionBlock.h + + hash + + 1Yfqd+56feO4hvc41uYw3xOYg1M= + + hash2 + + 09qqv0w1PUBl5UiIFSLzi/sM3CPs+oScE6krPQ0M/8Q= + + + Headers/GREYActions.h + + hash + + iebEFM6U5oElUbP2LgwCnqrihf0= + + hash2 + + a3WNNj01jDIdLpj1piIr0XA26rtozKeqmv0oHqB0EtA= + + + Headers/GREYAllOf.h + + hash + + KAUu8k5Zji4EP4wElKdeY7cdalI= + + hash2 + + 3sTOTqrB2VYy0zcVA6M+AwBVj7HFGDC4zGbLdhTQMYw= + + + Headers/GREYAnyOf.h + + hash + + MYHz3aXwG4SiuNHd8nsF8RHyybY= + + hash2 + + W3Sr/sfImgQUkGaNFkSd0YFBdYpwO7TDMbDUDrZuoSM= + + + Headers/GREYAssertion.h + + hash + + haEFAIr3uoCcYdgTORc1g6zdsik= + + hash2 + + Pm0/Ulu6ThSHFgMAVy30GJzprzSfw9/EXCzPNW9Fh9M= + + + Headers/GREYAssertionBlock.h + + hash + + MI27j9Skp7L+I2VGjtt0SS/F8Fc= + + hash2 + + DhklEyjLjaTrTWAcfgXEddr6VYSVtp/JpByrXd7yovc= + + + Headers/GREYAssertionDefines.h + + hash + + lD8bmNBx/ixp0CmgZqu4WOC8vwM= + + hash2 + + q7040D1ilTXRwIZ85G6NLhY/yXKOF+66ndj1/irTatE= + + + Headers/GREYAssertions.h + + hash + + rB1Lxuskfr9xQY3AqXjDX+Dsg4A= + + hash2 + + h5cC7ylsSz+s8dZfMN6EGpi+2ULCRMWpwghB9vQNC20= + + + Headers/GREYBaseAction.h + + hash + + EChl/NxZYfYCXBja5f1gIfwETuA= + + hash2 + + 7JRNzMGUnCgaErHkBhrN9p25o/AHVm82EpkajUVhVuE= + + + Headers/GREYBaseMatcher.h + + hash + + gwKPWxAElvWAqKaE45afa1LZ2yQ= + + hash2 + + 9r4Vevr/+V2DhhS9lAQreblKTAkAOpRFLl+QU2I06N0= + + + Headers/GREYCondition.h + + hash + + 9ckqk15ZpohKMPtWfE1kO4dG3ws= + + hash2 + + NW6gvc75fwPjAjS3nF4vHh8iLzYiZJEaSmJTjYRynnI= + + + Headers/GREYConfiguration.h + + hash + + fRWv3hsNEAWP8cstF8GbPt00P34= + + hash2 + + s5l7vJX03KxB/vRcFsuIDpkcbcGStNbpwwXcdqNb01w= + + + Headers/GREYConstants.h + + hash + + 9apjZAxy6v8aZTP5GH3WrIV3d9Y= + + hash2 + + iElRnn4HA2Wqob+YGq3WtAHK1fBAPec/13fjw7mXi+8= + + + Headers/GREYDataEnumerator.h + + hash + + iCg8QFCjxeFEflPcFrt4wjxUbqM= + + hash2 + + iQFbN+OXrDoRZaqS7njHSaICiOhplR/jnxB8cgeRPUM= + + + Headers/GREYDefines.h + + hash + + XnZ2EXBD68YZHMQDpsfsEpwyCF4= + + hash2 + + f1gMaq2W3AnoOM64t9/SVuuwFf1Lzxd2e0nzCxJFdfM= + + + Headers/GREYDescription.h + + hash + + m/sDvnWc4a8q7a8LtfpZHZ5tM48= + + hash2 + + 699XTDqE+Pc3kl8/kjb6kinRWxnr4iEDlMzcAqvp89o= + + + Headers/GREYDispatchQueueIdlingResource.h + + hash + + lHq2cJ4RQNjWpbP1I1bwiPVXUSY= + + hash2 + + DNKVyTHJ96jmHkELOLTQp9q6RiNeXK1Z9oK5gpAjhfo= + + + Headers/GREYElementFinder.h + + hash + + rC/0nb/2lY+OpwUg1o4Grmh6cvI= + + hash2 + + iSKr6sInYWsZIfsGKCJvIhpxqq9c1vcduETEaordaSc= + + + Headers/GREYElementHierarchy.h + + hash + + cMiPnS43FNiZO7qXXGgtyqjRCUQ= + + hash2 + + 1xSiQSkTLNYXOibPTwWUnlQ0649kkUGL3Hdo0PUMtUc= + + + Headers/GREYElementInteraction.h + + hash + + wajQJHMA4/ISywVB59E4UcKAaiQ= + + hash2 + + +1zkcauppIHCv5ve06MP16/Kr/pE//AsbBjppNkNWSw= + + + Headers/GREYElementMatcherBlock.h + + hash + + cLEM9WcQDBlOYNgZzG5641jEKmE= + + hash2 + + IBUj7HZK3ZG6Eq1YNhmMfaicsgGft1otNPBQ+w5oQaE= + + + Headers/GREYFailureHandler.h + + hash + + hIPCdLZkYBiuViRtUc4Sc8qFDO4= + + hash2 + + 9dG5YtiVEDZ/2XNXJLUTxFrvAVG4O6yMUgMZEQaz4+Q= + + + Headers/GREYFrameworkException.h + + hash + + +juebaDYjJEo9i7gFvZuDU5Dexk= + + hash2 + + 8exe+q1EP7gCqchgNTIQSlVnLWRVaWTr80x/RXhjWyQ= + + + Headers/GREYIdlingResource.h + + hash + + IyOH81wc/yp9pvs2uAbmlJduwwQ= + + hash2 + + pC55vR9dqjFarOA5C81xdiagVmXcd5idWUk8d8nyufI= + + + Headers/GREYInteraction.h + + hash + + 1De2+d0IxBIGLDJgT3lJMV/O5+w= + + hash2 + + zVpcV/b5XBe7JyMZuOk0ILOBhLedLHYbKIIkLTd39DY= + + + Headers/GREYLayoutConstraint.h + + hash + + t+eGWv43AXeRLQ+IQPlnpuoI9Mg= + + hash2 + + hc8UPcRohai/1/ZOuNKnFSMk1FCZJu5O+7UyuPkHUpE= + + + Headers/GREYManagedObjectContextIdlingResource.h + + hash + + L/QDcRC/4EyAvQofEWnTjN5r39U= + + hash2 + + sa8niGqqDaCBJRU3ip4rSLmtmUbSadH6DlEMid/zvoU= + + + Headers/GREYMatcher.h + + hash + + CAMueQYt3xizNb0t+sKJz3e1dJQ= + + hash2 + + UfdT/HFg8E4vCjWngGp8iLmEuGnhFJHWz499NFNo3Gc= + + + Headers/GREYMatchers.h + + hash + + UDkXORSvz9BYce6Rl0STjhXqkJo= + + hash2 + + 1zRDX1kHv70q/SMk3mbL4QHdjETmhkmQOq9KYpms9lI= + + + Headers/GREYNSTimerIdlingResource.h + + hash + + v0+vDNj3L0hRtsttHAx0oy54B4c= + + hash2 + + b5/xAsx6sPTMBtesytrASDowy57y2TBQ2HzOcVHko1M= + + + Headers/GREYNot.h + + hash + + TS0nBp36HsOvzu3fCkKrStYHy1w= + + hash2 + + SdE/r9qwuKp1KxThiYdunFjEXaSmyEBSfvD7jovBx3M= + + + Headers/GREYOperationQueueIdlingResource.h + + hash + + aUcXbXHM2irAYU0AomMHhB9WrrI= + + hash2 + + nExiA83/d5uEbFKpGedqx/ReFGh8w9hrncj1C285OKo= + + + Headers/GREYProvider.h + + hash + + rCqYagyW62sUDG7pqhZ+cI126KQ= + + hash2 + + fyWmO0Y+c2r7wlu1+ndbIjfZVg5hSV5oBezdGexMnqI= + + + Headers/GREYScreenshotUtil.h + + hash + + vcK/gpEzmSVFOBRgifLwibea2OA= + + hash2 + + EvaT71pmZTpibaWCDfyE5lDeUwalERTUqqhJd2cX0V4= + + + Headers/GREYScrollActionError.h + + hash + + JVuWV54MjqejOz+foBP4euLSAPk= + + hash2 + + K9UzlAgJvzqAeh+ywLz+gvwaGvveTbTmD++bLUXohPQ= + + + Headers/GREYSyncAPI.h + + hash + + sQAbPBWWJmTIdxwynwq0f+TtVTw= + + hash2 + + yRG8EsCwgmPRocTswXk1hvC7a9nGP76NYEPAUWzR6hI= + + + Headers/GREYTestHelper.h + + hash + + sxa8xt8gFVZcZscjKY1NaDbuTjE= + + hash2 + + 2rmgpexdxS2RZsRGmQHxXNNh3G8kdBAdr17c8QPEwnI= + + + Headers/GREYUIThreadExecutor.h + + hash + + IX0lcwuGnN2BBRgKntz4UeAUSN0= + + hash2 + + PpNVqiTZDJZbSbM2G+BDSR4vWWEC6nG1f83vq2WpG/8= + + + Modules/module.modulemap + + hash + + VSBF30YAA7ws/xF/KgbL5CmWI+E= + + hash2 + + KgqndMuOEt/PfHmRcx0++g8sCF5CWsM4bQVNUlBT+XU= + + + PrivateHeaders/CAAnimation+GREYAdditions.h + + hash + + hyHN5VJwsZHtZtFiBlhWiknUwQs= + + hash2 + + G0yCSQf6XlRnJyqBsmOjfRotx6ELIXiln8nrWRFcdyM= + + + PrivateHeaders/CALayer+GREYAdditions.h + + hash + + DrbBo1P45BJwghXif6cLY0ID+RY= + + hash2 + + YjJz9f3Q9MsGIbNtCO9Z/FSzQaGgGvChxHlrHyK11+g= + + + PrivateHeaders/CGGeometry+GREYAdditions.h + + hash + + tt/9Fc0Rr2OY0oD/cwFooPr+V+4= + + hash2 + + MQxF74DeZKvf227v3ITSuE9irsGKMIQOnMm6OnFNGRo= + + + PrivateHeaders/GREYActions+Internal.h + + hash + + XbF0VjVWyriz15G8Mn+UScL/kaQ= + + hash2 + + r8NPsn8y7Fuo1w7amIMemi6GKDiSjkXg+QZreQ6Q3JA= + + + PrivateHeaders/GREYAnalytics.h + + hash + + 9rhiEB0OLgmG9Vh7H0LUNkICJ+M= + + hash2 + + +z+IletDpOk3RvrcBDnE7rb9uH4EhSfXEkkx6+rI5Cg= + + + PrivateHeaders/GREYAnalyticsDelegate.h + + hash + + vs0XUlK6IDwiRpCdo9O5wEM0thw= + + hash2 + + DizVlDa3j01nHIpJnoYBJf0DntLXDQ/PKVVVZ24lgMY= + + + PrivateHeaders/GREYAppStateTracker.h + + hash + + r/HjO1b6iCkf6vSmrhdJU1jEZXk= + + hash2 + + eHxD9XvPw2SenYPNONuXgQRI/dhPWxKH7ChAdYf3k7M= + + + PrivateHeaders/GREYAppStateTrackerObject.h + + hash + + 6uWfWgO3RvnaMHR3Q91e/Knui2E= + + hash2 + + q3JbSBS8uEezjcZZ0/744PIae5saUcj+DJDqNeVuT04= + + + PrivateHeaders/GREYAppleInternals.h + + hash + + ngObJXcoLT+zoPUulksCfjFfSws= + + hash2 + + UI0okCdN7S5IzgpqqSjA4R/+Yga7DDGDWgrK91e8ojI= + + + PrivateHeaders/GREYAssertions+Internal.h + + hash + + 0EMLB1HUan26fKceVS9enwcEmbA= + + hash2 + + pLjGG1JvcYqrgjkhjjIsVQltji7NbbHPc5NzkHH1VUg= + + + PrivateHeaders/GREYCAAnimationDelegate.h + + hash + + pVjo18c9joHUkrB8uitEoI+PGZg= + + hash2 + + BLzmRq+5INTEyaDKlW6IE8onifFE7kL/b6uZAbyEnME= + + + PrivateHeaders/GREYChangeStepperAction.h + + hash + + hfztKpDfxh6u6D1GM5pzH/ISgBM= + + hash2 + + xrqs3cuvxLAyZTe49z4C+vjT+QHD8EOVVwC/PwFP7nQ= + + + PrivateHeaders/GREYDispatchQueueTracker.h + + hash + + X6IdLgLmqTsRRAMSE083rWdFO7U= + + hash2 + + mbWYo62B3pRPMNGLlF9xrBA9fr2M9jOdx0VN0G6V2TQ= + + + PrivateHeaders/GREYElementInteraction+Internal.h + + hash + + eiE6abWRD2rpdQJLlrptI+9h8Sw= + + hash2 + + IeltpzRKzvfbGpWqQPrT/N/3eKdyCsApYrVrVn2UCn8= + + + PrivateHeaders/GREYElementProvider.h + + hash + + +jm5+GpI+s3cK7AWd1DJyuvKZs8= + + hash2 + + gBAfw6TqzPZK8vWv/QAtCVf+KIR75rhqn+jPWazFfk8= + + + PrivateHeaders/GREYError+Internal.h + + hash + + MAPdLs2w27nJfCylnAuyZT1tNR8= + + hash2 + + Em4aOf737pxyXVGjEWnjzT+HIfKkj80BKK6kgcPhPqY= + + + PrivateHeaders/GREYError.h + + hash + + yg5+lc17ZEJx6u2DZ2u75CRWJZ8= + + hash2 + + MsDbWbTg7z6qBDNG7xLAcG5LebjPFI868381OeLwLzg= + + + PrivateHeaders/GREYErrorConstants.h + + hash + + smT2nN+9Z/42etrQHoaIbytauIg= + + hash2 + + +DPXyzJvc/S59jJ9JISkfACj4MRhEexha4ndh3z4dY0= + + + PrivateHeaders/GREYFailureFormatter.h + + hash + + bgk3GOACqxfiDYxCisL1NRGs3qc= + + hash2 + + D9TTZHmI1x0uodiw3w2fdvypCkgUV8XJ6r1iDlYyb5Q= + + + PrivateHeaders/GREYFailureScreenshotter.h + + hash + + X9kQxlrbQ3aqHs3dhzbXgyanL3Q= + + hash2 + + EZ8q16OYOPK+9TEp5ORbuDgVlOXR9ncK4UGBmrZA1II= + + + PrivateHeaders/GREYInteractionDataSource.h + + hash + + 88H2rHBwkwOTf9GFVlHtdkaFs/M= + + hash2 + + 4HfQcPx1VV5lh2PBzgH8zPuuLMxXjJwuLfkEO9lIZHk= + + + PrivateHeaders/GREYKeyboard.h + + hash + + sKnZGGq0h/dh3hI6jGRvoSAd+cg= + + hash2 + + CZx5U1wtBuc25o6AsDbBKz0h8pt7WftH4qE0QTuDEsM= + + + PrivateHeaders/GREYLogger.h + + hash + + +BOiQ//4jrGNc+P75BYDQm3fIdU= + + hash2 + + 2WGuC621AXP+eV3yTbUrnTQIj4CGBHPE2R8Pf28pzmk= + + + PrivateHeaders/GREYMultiFingerSwipeAction.h + + hash + + 75Vc3HuPveNem3Rj1L2BbApKWk4= + + hash2 + + Gp1cXUfhA2W2TA/qYpDH+cVn7NxPFM07uL4QYiUn4Vw= + + + PrivateHeaders/GREYNSURLConnectionDelegate.h + + hash + + yLzIw9MZytRxHNdlDOtwTQJm5oE= + + hash2 + + tkeCgxS/NVVpzTP2RZIS/jlrxyJF2MxaaaHSoHX3x9s= + + + PrivateHeaders/GREYObjcRuntime.h + + hash + + vYosx7+Bk6606SQXxC9jHQ7f+Tw= + + hash2 + + 1lQQFETFmfn5+LQEAlYFdRq+TnJRndT913fOUTVXNgA= + + + PrivateHeaders/GREYObjectDeallocationTracker.h + + hash + + wH8Rt30Em5YAstmTUaBdA0CkBAk= + + hash2 + + 4jrBlXeHrrhk6GPffDAQnEe0+1EcGD+c0wTNCbqJrVE= + + + PrivateHeaders/GREYObjectFormatter.h + + hash + + EqT/az4Ni3JSFpXerExHezvUWzs= + + hash2 + + CGaxKzOMa4B3icHGFjgn0OkhuMeTBDHPSMKS7X9oB40= + + + PrivateHeaders/GREYPathGestureUtils.h + + hash + + b6YPyGUGy3e0C2FyahkDUwRqRJA= + + hash2 + + f58A26GRZBg/Dwh6NUoippqDsEPKu+6baJWNfAXNw60= + + + PrivateHeaders/GREYPickerAction.h + + hash + + JGkkwgOtDCoFiLdtkA9ibvToU8Y= + + hash2 + + kK3NjlTzkcGEJcT5JOOscDRYOQ49loSJ6nwO8pASXf0= + + + PrivateHeaders/GREYPinchAction.h + + hash + + 4ceJ8OkYU2j2+V0wocsAI8lUATc= + + hash2 + + MUKg/fq6z+XEKvfVqoZp/WI+jgcGujYmNAPHWz19uNI= + + + PrivateHeaders/GREYRunLoopSpinner.h + + hash + + I4TL8ijbBLCJvmtyHn/hGuRQiFE= + + hash2 + + i2yGWbvGGCMW8aFDc63APhU7cjkL5Jx1c/iVYHEYw4o= + + + PrivateHeaders/GREYScreenshotUtil+Internal.h + + hash + + bh09uClpC/+jZ+FqQIB4YJGGeh8= + + hash2 + + 3K/3yq0W5m4km2WEhN03U068bNuAmBwOXkdJSHJDa4I= + + + PrivateHeaders/GREYScrollAction.h + + hash + + YqYfBVbVUV9jI9BYTIIx5aKIEMY= + + hash2 + + TyBpAD4xD5+fmWGPYD0uSm22EK1x+CHQNzhUSTkWLVo= + + + PrivateHeaders/GREYScrollToContentEdgeAction.h + + hash + + xJq30ebBFQaQjVrwUieeJpBL1Q0= + + hash2 + + 0URx/HdccOvXvv8ku3SvJfLeJCUQBz/s9DsDZdYSmXY= + + + PrivateHeaders/GREYSlideAction.h + + hash + + ikpFqhSqlETAsgQS9k59tAIUrKk= + + hash2 + + nz7IdwuoqEAChr9ovj9EVZP7W0W89injWotWy2mgZR0= + + + PrivateHeaders/GREYStopwatch.h + + hash + + 45lmv1rkwKSz+MXUgvGbnGnqbvg= + + hash2 + + F+vuybgwfZcB/zluOto8t7Bj2uh1ITudEkxbaPHUBv4= + + + PrivateHeaders/GREYStringDescription.h + + hash + + LZ4YHUJsZ0GBAFoLqh52Ku0a5+E= + + hash2 + + +K2hDAaoN+HpwvNZut/HhsrGb7FDOdz9OxhVCNfJQC8= + + + PrivateHeaders/GREYSurrogateDelegate.h + + hash + + T1zefgnsKS2cU0AfvxmbFL6aMqg= + + hash2 + + wcb5hyb0Ai5ii2/fdyhQ98uDYWOPJLRY1LzVrclNr84= + + + PrivateHeaders/GREYSwipeAction.h + + hash + + ORooqPFb+Z4/z/cbxizBbyZMlVA= + + hash2 + + 6cg+gJ+HLmWQiB3mqX1OgFiY84T6quD5LWMj2UvNKg4= + + + PrivateHeaders/GREYSwizzler.h + + hash + + A1YScxqciQnCNdEg/awvHt6r+UU= + + hash2 + + 81m4tgjPm9+AAnBVd2UWkLKvXID3K9Io6Gi4Lc753Uk= + + + PrivateHeaders/GREYSyntheticEvents.h + + hash + + 7wWfv4QI4YN9F5JMgdZPsb/gL2U= + + hash2 + + X5CfnZ2jsZ1NEj//Wr947CXv2lPmhNdz7qqB2LRnPFk= + + + PrivateHeaders/GREYTapAction.h + + hash + + ZSBpMaOq5/ddza2r1QoPxKptX4M= + + hash2 + + bgb7iJe5wGtveVyPZB9Z/thbKzs3wTjoX6h0eO3UJ8g= + + + PrivateHeaders/GREYTestCaseInvocation.h + + hash + + tnuX4BzrnE0v9iRLNuz/lCHUMSI= + + hash2 + + HczvIXvAdxKMfi8hg9+af5ewnjWpYQGx6iVruRdU+Yc= + + + PrivateHeaders/GREYTimedIdlingResource.h + + hash + + 331HuPKdzLPxzb9Hm2DHOn3SGFs= + + hash2 + + 023uTL3AN5nGL/5amltCiA/53RerdWy7YZYB88bs2GI= + + + PrivateHeaders/GREYTouchInfo.h + + hash + + 4DRNyA+KkHJWIiTB4ohWcozeJeQ= + + hash2 + + GxX4KLjB5OI6DA/Kg/Wy64BCoj1RcIn8f79U3HeeAAU= + + + PrivateHeaders/GREYTouchInjector.h + + hash + + Zej1xAdkaeHMdE+E0B+j77OGxgQ= + + hash2 + + nRg2vxmGek8kDGfsgKDa7QMQ4JCxHH+aGbQzhRWXfDE= + + + PrivateHeaders/GREYTraversal.h + + hash + + wzTNGqszktAO18lUYpT20upw/d4= + + hash2 + + afqEUQsqGs14LcUNkRcnv5jmkJSiAtueD4esQFrKUAE= + + + PrivateHeaders/GREYTraversalBFS.h + + hash + + Ava89zTGIHQQqNEQdGgdr0I9oE0= + + hash2 + + 4coHjeWLLGJBFGU7t/DHMz6imJaRSJX6scOFLVEx0ps= + + + PrivateHeaders/GREYTraversalDFS.h + + hash + + CZ6CBifTvuuy4382KQQhgH3jER8= + + hash2 + + kSKb9KQGrQL7YFGbrKczCSYzUE5iig+9Dwq9lkCYPCk= + + + PrivateHeaders/GREYUIThreadExecutor+Internal.h + + hash + + oMjm4Q7Ev7swhKzN2w1UHzH53u0= + + hash2 + + xEhAiFLr7KlTNNC4/YhbYfvWjg0GTFCuGcHb1nq/txo= + + + PrivateHeaders/GREYUIWebViewDelegate.h + + hash + + sPDhZLBQ2tCx1GqLJmpSpl9WzpY= + + hash2 + + Ua8GOGQC1WunNjTHrTd5IUZQnUos+VhKf2LJ1rxMLxg= + + + PrivateHeaders/GREYUIWindowProvider.h + + hash + + ouqic3bv57sPLFj/s/+8nhVMnD4= + + hash2 + + D0ycjK0I9DuiQ5cVb+SpKXZznzJdQk3u1/Wmy4MXXwo= + + + PrivateHeaders/GREYVisibilityChecker.h + + hash + + 4yrfctRQ6pj5UZSbLtfzCV56xho= + + hash2 + + CyfJtgwkBmj+9w4CMdRO6PCmAD9MIroA2jHLZw/+QlM= + + + PrivateHeaders/GREYZeroToleranceTimer.h + + hash + + dWnY8aWbAHzXYoYkcpONs/ZAlkQ= + + hash2 + + 2AmF02MrylkrfXufup7YzIsofDwZjpoBsRVufSe9Krk= + + + PrivateHeaders/NSError+GREYAdditions.h + + hash + + cHRrUi2UFknRO0NkpACC56XLHtI= + + hash2 + + mh3MxR1LtAUEd/tByI3vfRRKLk5gGjWgcD9pLxOW9KE= + + + PrivateHeaders/NSObject+GREYAdditions.h + + hash + + hVH8HA6vtt8wiWoY1eQUFh7C+jE= + + hash2 + + ZnY8EYntofNoqCCUJKbb1e+/Pi6XgnOBqah5RGnWniw= + + + PrivateHeaders/NSRunLoop+GREYAdditions.h + + hash + + JGAXDlvL3EKQH4Wyzqrcn9eHIV4= + + hash2 + + Hjxyf6u6aS09Y4mUvrLQ8wrTetNccAn4vKcXlJ/LwR4= + + + PrivateHeaders/NSString+GREYAdditions.h + + hash + + ZiU2GaaqlklwfbtS2h1rhiHKF44= + + hash2 + + uahDNFIjsvApx/JWVGS6JM1z7GgtxhZoVKZxr1Hx7m4= + + + PrivateHeaders/NSTimer+GREYAdditions.h + + hash + + VxQDN4X+sHQXCrGis4zlCH1Vm9Y= + + hash2 + + clkMQzZWrBcjDg4DJaSAMVc9GNMhmXtDtY06GxbyeZ0= + + + PrivateHeaders/NSURL+GREYAdditions.h + + hash + + YJ8d1OWqW1Du6nCO0xO6/MnTUgo= + + hash2 + + pz/TlV/PvCLCh0/WunTk1z5Q/WzyY7VYW4K+ty5G7Ig= + + + PrivateHeaders/NSURLConnection+GREYAdditions.h + + hash + + dMd2sAWeUmHlXj1DVoI/f2cQcZU= + + hash2 + + m0zRbdLimcxg7k9m+7oWB6L7MKUU2qKA/KY2Y5ESw3w= + + + PrivateHeaders/NSURLSession+GREYAdditions.h + + hash + + vgHLKMZ38RaygzS8xxkMO0qA+7I= + + hash2 + + s7mXsce0ij8oaRRVqLAUlHbf+zLWgABGwQc7vvMF824= + + + PrivateHeaders/UIAnimation+GREYAdditions.h + + hash + + UUohwVgp7Y7vU5Bqfl78Yu/iHUA= + + hash2 + + 3GUeLsW8IUqx/b2PtLKJmXw4zD+8UwNpIAXodZL81/I= + + + PrivateHeaders/UIApplication+GREYAdditions.h + + hash + + 8+uctukvHJjafkkwhuQMJV82MUM= + + hash2 + + lPgAeYuC4DHE3AYFXkDlqdffWmSRhxvZZ1wTQgoWXu8= + + + PrivateHeaders/UIGestureRecognizer+GREYAdditions.h + + hash + + jpZjBAYe5mllIyIQ+IilQgACjcU= + + hash2 + + zWPGRhNQ5bwVC37DqKA5+2WUqJlfrzl6CrNOLs04Mko= + + + PrivateHeaders/UIScrollView+GREYAdditions.h + + hash + + 7rfFZgitTzT8GtHI0C3v78ieqyM= + + hash2 + + NvyK7fDd4rLZodFf1WaZcWsRinOFHhf7ZZvtpBSFfxk= + + + PrivateHeaders/UISwitch+GREYAdditions.h + + hash + + xvb4kCBQLLFMh3dfE+GalK9UMFo= + + hash2 + + 3LmQoVC+4e9RRRZhzBfTCN0FIDWDi7GjSmg40b0nrts= + + + PrivateHeaders/UITouch+GREYAdditions.h + + hash + + ypoC3kZPi2cIUg2XdQ/GDq72xtc= + + hash2 + + Na8sJp83c9b+9KT8EkN36PVf7ARUrsrvEaW2kvSSiCs= + + + PrivateHeaders/UIView+GREYAdditions.h + + hash + + Jy1IVTeWGFBuuGazdV8aK9dmbVg= + + hash2 + + sMgcXWLudWmdicSuIPc0nF5N9fkTDWAmXVwuc6v7U98= + + + PrivateHeaders/UIViewController+GREYAdditions.h + + hash + + jAQvW8LxB8lh0JL7Dy1fk0LKWJ8= + + hash2 + + +/0cJ0+5W7HsbnGpt09KF3HvVt7MuNLy5shqp7z3jsE= + + + PrivateHeaders/UIWebView+GREYAdditions.h + + hash + + I1KljzRASrqkESKEXgYpC5R5rgw= + + hash2 + + 1mhKoXp88espNZMubp6+9Seiu/GwglNTB7JZm0m78s4= + + + PrivateHeaders/UIWindow+GREYAdditions.h + + hash + + zHfrdFLkIk3OEzvb5X116vrk9es= + + hash2 + + kI5JV2cRaDo6oOxW/DYEJDvry96sTIpWKDDx/jRhwqo= + + + PrivateHeaders/XCTestCase+GREYAdditions.h + + hash + + om1dVcUouigo2WWhWTbsA3Qddb8= + + hash2 + + pKmJe6z7SGd12lHezm3XrFZyBdNxkbn1evfc7iJ17g4= + + + PrivateHeaders/_UIModalItemsPresentingViewController_GREYAdditions.h + + hash + + mhL8447azlxmehD057J/J8IE+nE= + + hash2 + + 6T2uHSH48WxpEl7KSERVYfTD+xAv55uI6Ncmj1HHOaw= + + + PrivateHeaders/__NSCFLocalDataTask_GREYAdditions.h + + hash + + JP+etF8YrlmpT19Kifpo92ST9O0= + + hash2 + + pFPudHP2lO1EB/3S+kUwntNcnDNBpAfEYbtcOkXgLQc= + + + + rules + + ^ + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^ + + weight + 20 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ + + nested + + weight + 10 + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^[^/]+$ + + nested + + weight + 10 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/LICENSE b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/LICENSE new file mode 100644 index 0000000000..05e999985a --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/LICENSE @@ -0,0 +1,598 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +-------------------------------------------------------------------------------------------- + +Attribution 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More_considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution 4.0 International Public License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution 4.0 International Public License ("Public License"). To the +extent this Public License may be interpreted as a contract, You are +granted the Licensed Rights in consideration of Your acceptance of +these terms and conditions, and the Licensor grants You such rights in +consideration of benefits the Licensor receives from making the +Licensed Material available under these terms and conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + d. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + e. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + f. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + g. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + h. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + i. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + j. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + k. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + 4. If You Share Adapted Material You produce, the Adapter's + License You apply must not prevent recipients of the Adapted + Material from complying with this Public License. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material; and + + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public licenses. +Notwithstanding, Creative Commons may elect to apply one of its public +licenses to material it publishes and in those instances will be +considered the "Licensor." Except for the limited purpose of indicating +that material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the public +licenses. + +Creative Commons may be contacted at creativecommons.org. diff --git a/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/README.md b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/README.md new file mode 100644 index 0000000000..b73812b3e6 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/EarlGrey/EarlGrey/README.md @@ -0,0 +1,108 @@ +# EarlGrey +[![Apache License](https://img.shields.io/badge/license-Apache%202-lightgrey.svg?style=flat)](https://github.com/google/EarlGrey/blob/master/LICENSE) +[![CC-BY 4.0 License](https://img.shields.io/badge/license-CC%20BY%204.0-lightgrey.svg)](https://github.com/google/EarlGrey/blob/master/LICENSE) +[![Build Status](https://travis-ci.org/google/EarlGrey.svg?branch=master)](https://travis-ci.org/google/EarlGrey) +[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) +[![CocoaPods](https://img.shields.io/cocoapods/v/EarlGrey.svg?maxAge=2592000)](https://cocoapods.org/pods/EarlGrey) +[![Gem Version](https://badge.fury.io/rb/earlgrey.svg)](https://rubygems.org/gems/earlgrey) + +EarlGrey is a native iOS UI automation test framework that enables you to write +clear, concise tests. + +With the EarlGrey framework, you have access to enhanced synchronization +features. EarlGrey automatically synchronizes with the UI, network requests, +and various queues; but still allows you to manually implement customized +timings, if needed. + +EarlGrey’s synchronization features help to ensure that the UI is in a steady +state before actions are performed. This greatly increases test stability and +makes tests highly repeatable. + +EarlGrey works in conjunction with the XCTest framework and integrates with +Xcode’s Test Navigator so you can run tests directly from Xcode or the command +line (using xcodebuild). + +## Getting Started + +The EarlGrey documentation for users is located in the +[EarlGrey/docs](https://github.com/google/EarlGrey/tree/master/docs) folder. +To get started, review the EarlGrey features, check for backward compatibility, +and then install/run EarlGrey with your test target. After everything is +configured, take a look at the EarlGrey API and start writing your own tests. + + * [Features](https://github.com/google/EarlGrey/tree/master/docs/features.md) + * [Backward Compatibility](https://github.com/google/EarlGrey/tree/master/docs/backward-compatibility.md) + * [Install and Run](https://github.com/google/EarlGrey/tree/master/docs/install-and-run.md) + * [API](https://github.com/google/EarlGrey/tree/master/docs/api.md) + * [Cheat Sheet](https://github.com/google/EarlGrey/tree/master/docs/cheatsheet/cheatsheet.png) + +## Getting Help + +If you need help, several resources are available. First check the [FAQ](https://github.com/google/EarlGrey/tree/master/docs/faq.md). +If you have more questions after reading the FAQ, see [Known Issues](https://github.com/google/EarlGrey/tree/master/docs/known-issues.md). +You can bring more specific issues to our attention by asking them on +[stackoverflow.com](http://stackoverflow.com/) using the [#earlgrey tag](http://stackoverflow.com/questions/tagged/earlgrey). +You can also start new discussions with us on our [Google group](https://groups.google.com/forum/#!forum/earlgrey-discuss) +or request to join our [slack channel](https://googleoss.slack.com/messages/earlgrey). + + * [FAQ - Frequently Asked Questions](https://github.com/google/EarlGrey/tree/master/docs/faq.md) + * [IFAQ - Infrequently Asked Questions](https://github.com/google/EarlGrey/tree/master/docs/ifaq.md) + * [Known Issues](https://github.com/google/EarlGrey/tree/master/docs/known-issues.md) + * [Stack Overflow](http://stackoverflow.com/questions/tagged/earlgrey) + * [Slack](https://googleoss.slack.com/messages/earlgrey) + * [Google Group](https://groups.google.com/forum/#!forum/earlgrey-discuss) + +## Analytics + +To prioritize and improve EarlGrey, the framework collects usage data and +uploads it to Google Analytics. More specifically, the framework collects the +**MD5 hash** of *Bundle ID*, *Test Class Names* and *Test Method Names*. This +information allows us to measure the volume of usage. For more detailed +information about our analytics collection, please peruse the +[GREYAnalytics.m](https://github.com/google/EarlGrey/tree/master/EarlGrey/Common/GREYAnalytics.m) +file which contains the implementation details. If they wish, users can choose +to opt out by disabling the Analytics config setting in their test’s +`- (void)setUp` method: + +In Objective-C: + +```objc +// Disable analytics. +[[GREYConfiguration sharedInstance] setValue:@(NO) forConfigKey:kGREYConfigKeyAnalyticsEnabled]; +``` + +In Swift: + +```swift +// Disable analytics. +GREYConfiguration.sharedInstance().setValue(false, forConfigKey: kGREYConfigKeyAnalyticsEnabled) +``` + +## For Contributors + +Please make sure you’ve followed the guidelines in +[CONTRIBUTING.md](https://github.com/google/EarlGrey/tree/master/CONTRIBUTING.md) before making any contributions. + +### Setup an EarlGrey Project + + 1. Clone the EarlGrey repository from GitHub: + + git clone https://github.com/google/EarlGrey.git + + 2. After you have cloned the EarlGrey repository, download all the dependencies +using [**setup-earlgrey.sh**](https://github.com/google/EarlGrey/tree/master/Scripts/setup-earlgrey.sh). + 3. After the script completes successfully, open `EarlGrey.xcodeproj` and ensure that all +the targets build. + 4. You can now use `EarlGrey.xcodeproj` to make changes to the framework. + +### Add and Run Tests + +#### Unit Tests + +To add unit tests for EarlGrey, use `UnitTests.xcodeproj` located at +`Tests/UnitTests`. To run all unit tests, select the **UnitTests** Scheme and press Cmd+U. + +#### Functional Tests + +To add functional tests for EarlGrey, use the `FunctionalTests.xcodeproj` located +at `Tests/FunctionalTests`. To run all functional tests, select the **FunctionalTests** Scheme and press Cmd+U. diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Private/FlutterPluginRegistrant/GeneratedPluginRegistrant.h b/dev/integration_tests/ios_add2app/Pods/Headers/Private/FlutterPluginRegistrant/GeneratedPluginRegistrant.h new file mode 120000 index 0000000000..4d9ce56545 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Private/FlutterPluginRegistrant/GeneratedPluginRegistrant.h @@ -0,0 +1 @@ +../../../../flutterapp/.ios/Flutter/FlutterPluginRegistrant/Classes/GeneratedPluginRegistrant.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/EarlGrey.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/EarlGrey.h new file mode 120000 index 0000000000..61137b670b --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/EarlGrey.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/EarlGrey.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/EarlGreyImpl.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/EarlGreyImpl.h new file mode 120000 index 0000000000..ee6702aae3 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/EarlGreyImpl.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/EarlGreyImpl.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYAction.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYAction.h new file mode 120000 index 0000000000..5e3d070514 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYAction.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYAction.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYActionBlock.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYActionBlock.h new file mode 120000 index 0000000000..4fe81fef47 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYActionBlock.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYActionBlock.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYActions.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYActions.h new file mode 120000 index 0000000000..ced2af095d --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYActions.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYActions.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYAllOf.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYAllOf.h new file mode 120000 index 0000000000..afd998a9b7 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYAllOf.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYAllOf.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYAnyOf.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYAnyOf.h new file mode 120000 index 0000000000..67336dcfc6 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYAnyOf.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYAnyOf.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYAssertion.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYAssertion.h new file mode 120000 index 0000000000..7d42b69a3c --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYAssertion.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYAssertion.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYAssertionBlock.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYAssertionBlock.h new file mode 120000 index 0000000000..7daa9a2094 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYAssertionBlock.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYAssertionBlock.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYAssertionDefines.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYAssertionDefines.h new file mode 120000 index 0000000000..b343aa05b2 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYAssertionDefines.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYAssertionDefines.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYAssertions.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYAssertions.h new file mode 120000 index 0000000000..d383a4cbaf --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYAssertions.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYAssertions.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYBaseAction.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYBaseAction.h new file mode 120000 index 0000000000..24b7a186cb --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYBaseAction.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYBaseAction.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYBaseMatcher.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYBaseMatcher.h new file mode 120000 index 0000000000..7351ee84c1 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYBaseMatcher.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYBaseMatcher.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYCondition.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYCondition.h new file mode 120000 index 0000000000..468f16e1d3 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYCondition.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYCondition.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYConfiguration.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYConfiguration.h new file mode 120000 index 0000000000..079ce4ae4f --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYConfiguration.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYConfiguration.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYConstants.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYConstants.h new file mode 120000 index 0000000000..8a46a988a6 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYConstants.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYConstants.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYDataEnumerator.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYDataEnumerator.h new file mode 120000 index 0000000000..4235ba1de1 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYDataEnumerator.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYDataEnumerator.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYDefines.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYDefines.h new file mode 120000 index 0000000000..f61f2d09ba --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYDefines.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYDefines.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYDescription.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYDescription.h new file mode 120000 index 0000000000..388c7ea03a --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYDescription.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYDescription.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYDispatchQueueIdlingResource.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYDispatchQueueIdlingResource.h new file mode 120000 index 0000000000..040256ccd0 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYDispatchQueueIdlingResource.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYDispatchQueueIdlingResource.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYElementFinder.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYElementFinder.h new file mode 120000 index 0000000000..2219d9d4d5 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYElementFinder.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYElementFinder.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYElementHierarchy.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYElementHierarchy.h new file mode 120000 index 0000000000..9e414fe97c --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYElementHierarchy.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYElementHierarchy.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYElementInteraction.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYElementInteraction.h new file mode 120000 index 0000000000..463cb9a764 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYElementInteraction.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYElementInteraction.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYElementMatcherBlock.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYElementMatcherBlock.h new file mode 120000 index 0000000000..67caabcf0a --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYElementMatcherBlock.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYElementMatcherBlock.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYFailureHandler.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYFailureHandler.h new file mode 120000 index 0000000000..99e3ded38c --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYFailureHandler.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYFailureHandler.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYFrameworkException.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYFrameworkException.h new file mode 120000 index 0000000000..679e98e6b2 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYFrameworkException.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYFrameworkException.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYIdlingResource.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYIdlingResource.h new file mode 120000 index 0000000000..6e78e4fe0d --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYIdlingResource.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYIdlingResource.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYInteraction.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYInteraction.h new file mode 120000 index 0000000000..b95d2bb35b --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYInteraction.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYInteraction.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYLayoutConstraint.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYLayoutConstraint.h new file mode 120000 index 0000000000..6965514e89 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYLayoutConstraint.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYLayoutConstraint.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYManagedObjectContextIdlingResource.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYManagedObjectContextIdlingResource.h new file mode 120000 index 0000000000..d10920a0f5 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYManagedObjectContextIdlingResource.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYManagedObjectContextIdlingResource.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYMatcher.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYMatcher.h new file mode 120000 index 0000000000..9684150da8 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYMatcher.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYMatcher.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYMatchers.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYMatchers.h new file mode 120000 index 0000000000..c369f461e1 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYMatchers.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYMatchers.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYNSTimerIdlingResource.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYNSTimerIdlingResource.h new file mode 120000 index 0000000000..ead20107ee --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYNSTimerIdlingResource.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYNSTimerIdlingResource.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYNot.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYNot.h new file mode 120000 index 0000000000..d961bdbeb2 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYNot.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYNot.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYOperationQueueIdlingResource.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYOperationQueueIdlingResource.h new file mode 120000 index 0000000000..a0735161b7 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYOperationQueueIdlingResource.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYOperationQueueIdlingResource.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYProvider.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYProvider.h new file mode 120000 index 0000000000..412e97b221 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYProvider.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYProvider.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYScreenshotUtil.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYScreenshotUtil.h new file mode 120000 index 0000000000..d27a1f2280 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYScreenshotUtil.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYScreenshotUtil.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYScrollActionError.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYScrollActionError.h new file mode 120000 index 0000000000..d468e65459 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYScrollActionError.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYScrollActionError.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYSyncAPI.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYSyncAPI.h new file mode 120000 index 0000000000..2d779b9bb9 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYSyncAPI.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYSyncAPI.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYTestHelper.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYTestHelper.h new file mode 120000 index 0000000000..a924c67aab --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYTestHelper.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYTestHelper.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYUIThreadExecutor.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYUIThreadExecutor.h new file mode 120000 index 0000000000..3b74f8b1bb --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/EarlGrey/EarlGrey/GREYUIThreadExecutor.h @@ -0,0 +1 @@ +../../../../EarlGrey/EarlGrey/EarlGrey.framework/Headers/GREYUIThreadExecutor.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/Flutter.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/Flutter.h new file mode 120000 index 0000000000..6b436d5bcd --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/Flutter.h @@ -0,0 +1 @@ +../../../../../flutterapp/.ios/Flutter/engine/Flutter.framework/Headers/Flutter.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterAppDelegate.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterAppDelegate.h new file mode 120000 index 0000000000..c0b8e97a08 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterAppDelegate.h @@ -0,0 +1 @@ +../../../../../flutterapp/.ios/Flutter/engine/Flutter.framework/Headers/FlutterAppDelegate.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterBinaryMessenger.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterBinaryMessenger.h new file mode 120000 index 0000000000..6f8dbb8f80 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterBinaryMessenger.h @@ -0,0 +1 @@ +../../../../../flutterapp/.ios/Flutter/engine/Flutter.framework/Headers/FlutterBinaryMessenger.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterCallbackCache.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterCallbackCache.h new file mode 120000 index 0000000000..d33ed50ce2 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterCallbackCache.h @@ -0,0 +1 @@ +../../../../../flutterapp/.ios/Flutter/engine/Flutter.framework/Headers/FlutterCallbackCache.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterChannels.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterChannels.h new file mode 120000 index 0000000000..42663c780d --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterChannels.h @@ -0,0 +1 @@ +../../../../../flutterapp/.ios/Flutter/engine/Flutter.framework/Headers/FlutterChannels.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterCodecs.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterCodecs.h new file mode 120000 index 0000000000..750d36bd85 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterCodecs.h @@ -0,0 +1 @@ +../../../../../flutterapp/.ios/Flutter/engine/Flutter.framework/Headers/FlutterCodecs.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterDartProject.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterDartProject.h new file mode 120000 index 0000000000..6f1fe0babb --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterDartProject.h @@ -0,0 +1 @@ +../../../../../flutterapp/.ios/Flutter/engine/Flutter.framework/Headers/FlutterDartProject.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterEngine.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterEngine.h new file mode 120000 index 0000000000..1cd44f3a99 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterEngine.h @@ -0,0 +1 @@ +../../../../../flutterapp/.ios/Flutter/engine/Flutter.framework/Headers/FlutterEngine.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterHeadlessDartRunner.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterHeadlessDartRunner.h new file mode 120000 index 0000000000..91dc204945 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterHeadlessDartRunner.h @@ -0,0 +1 @@ +../../../../../flutterapp/.ios/Flutter/engine/Flutter.framework/Headers/FlutterHeadlessDartRunner.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterMacros.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterMacros.h new file mode 120000 index 0000000000..864bd03fb0 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterMacros.h @@ -0,0 +1 @@ +../../../../../flutterapp/.ios/Flutter/engine/Flutter.framework/Headers/FlutterMacros.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterPlatformViews.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterPlatformViews.h new file mode 120000 index 0000000000..303df6b84b --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterPlatformViews.h @@ -0,0 +1 @@ +../../../../../flutterapp/.ios/Flutter/engine/Flutter.framework/Headers/FlutterPlatformViews.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterPlugin.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterPlugin.h new file mode 120000 index 0000000000..23d25ee1f8 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterPlugin.h @@ -0,0 +1 @@ +../../../../../flutterapp/.ios/Flutter/engine/Flutter.framework/Headers/FlutterPlugin.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterPluginAppLifeCycleDelegate.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterPluginAppLifeCycleDelegate.h new file mode 120000 index 0000000000..bc7072345a --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterPluginAppLifeCycleDelegate.h @@ -0,0 +1 @@ +../../../../../flutterapp/.ios/Flutter/engine/Flutter.framework/Headers/FlutterPluginAppLifeCycleDelegate.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterTexture.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterTexture.h new file mode 120000 index 0000000000..9be648eb4c --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterTexture.h @@ -0,0 +1 @@ +../../../../../flutterapp/.ios/Flutter/engine/Flutter.framework/Headers/FlutterTexture.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterViewController.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterViewController.h new file mode 120000 index 0000000000..d54adb365e --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/Flutter/Flutter/FlutterViewController.h @@ -0,0 +1 @@ +../../../../../flutterapp/.ios/Flutter/engine/Flutter.framework/Headers/FlutterViewController.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Headers/Public/FlutterPluginRegistrant/GeneratedPluginRegistrant.h b/dev/integration_tests/ios_add2app/Pods/Headers/Public/FlutterPluginRegistrant/GeneratedPluginRegistrant.h new file mode 120000 index 0000000000..4d9ce56545 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Headers/Public/FlutterPluginRegistrant/GeneratedPluginRegistrant.h @@ -0,0 +1 @@ +../../../../flutterapp/.ios/Flutter/FlutterPluginRegistrant/Classes/GeneratedPluginRegistrant.h \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/Pods/Local Podspecs/Flutter.podspec.json b/dev/integration_tests/ios_add2app/Pods/Local Podspecs/Flutter.podspec.json new file mode 100644 index 0000000000..0a8331b392 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Local Podspecs/Flutter.podspec.json @@ -0,0 +1,21 @@ +{ + "name": "Flutter", + "version": "1.0.0", + "summary": "High-performance, high-fidelity mobile apps.", + "description": "Flutter provides an easy and productive way to build and deploy high-performance mobile apps for Android and iOS.", + "homepage": "https://flutter.io", + "license": { + "type": "MIT" + }, + "authors": { + "Flutter Dev Team": "flutter-dev@googlegroups.com" + }, + "source": { + "git": "https://github.com/flutter/engine", + "tag": "1.0.0" + }, + "platforms": { + "ios": "7.0" + }, + "vendored_frameworks": "Flutter.framework" +} diff --git a/dev/integration_tests/ios_add2app/Pods/Local Podspecs/FlutterPluginRegistrant.podspec.json b/dev/integration_tests/ios_add2app/Pods/Local Podspecs/FlutterPluginRegistrant.podspec.json new file mode 100644 index 0000000000..45d68a8ff0 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Local Podspecs/FlutterPluginRegistrant.podspec.json @@ -0,0 +1,29 @@ +{ + "name": "FlutterPluginRegistrant", + "version": "0.0.1", + "summary": "Registers plugins with your flutter app", + "description": "Depends on all your plugins, and provides a function to register them.", + "homepage": "https://flutter.io", + "license": { + "type": "BSD" + }, + "authors": { + "Flutter Dev Team": "flutter-dev@googlegroups.com" + }, + "platforms": { + "ios": "8.0" + }, + "source_files": [ + "Classes", + "Classes/**/*.{h,m}" + ], + "source": { + "path": "." + }, + "public_header_files": "./Classes/**/*.h", + "dependencies": { + "Flutter": [ + + ] + } +} diff --git a/dev/integration_tests/ios_add2app/Pods/Pods.xcodeproj/project.pbxproj b/dev/integration_tests/ios_add2app/Pods/Pods.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..cbadf097d4 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Pods.xcodeproj/project.pbxproj @@ -0,0 +1,695 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 90623EE0DFC611ECA79061CA2D8358A4 /* FlutterPluginRegistrant-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 59C4454C6208CA53988E29FFF1F03C2E /* FlutterPluginRegistrant-dummy.m */; }; + A456B826DFE59B7675BB489F26BDB8D0 /* GeneratedPluginRegistrant.h in Headers */ = {isa = PBXBuildFile; fileRef = AB2A3338AA26CE231BE2B5342F69B46B /* GeneratedPluginRegistrant.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D804971E28E8BBE38C2C989D16D071FF /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = A1930A36E88812FFBF49A0804CCA939D /* GeneratedPluginRegistrant.m */; }; + D9239CC7E38BEDF9A8E18AED0B76007B /* Pods-ios_add2app-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 1402A9B5E7D2CCA622A4477C694702C1 /* Pods-ios_add2app-dummy.m */; }; + FC54914589BC06AB28064A2DEA23DE91 /* Pods-ios_add2appTests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 257FB6DC96D82E7F5C127C5F1567927A /* Pods-ios_add2appTests-dummy.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + A2795B72F9E5BDBFA6D2F5A7866DFA2A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 77F3683E8268E2B8342BFBD47DFF6870; + remoteInfo = FlutterPluginRegistrant; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 0340BEC47E654F7ED86700BF354C1097 /* Pods-ios_add2appTests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-ios_add2appTests-acknowledgements.plist"; sourceTree = ""; }; + 095DFDEB7FE9B91E35B295B1D565C66C /* Pods-ios_add2app-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-ios_add2app-frameworks.sh"; sourceTree = ""; }; + 0A41E61C0D6BDA480DD4B0208BD5B175 /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Flutter.framework; sourceTree = ""; }; + 0ED9CDB538F5B1479A4EC18C9079BEB4 /* Flutter.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; lastKnownFileType = text; path = Flutter.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + 1402A9B5E7D2CCA622A4477C694702C1 /* Pods-ios_add2app-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-ios_add2app-dummy.m"; sourceTree = ""; }; + 257FB6DC96D82E7F5C127C5F1567927A /* Pods-ios_add2appTests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-ios_add2appTests-dummy.m"; sourceTree = ""; }; + 2C0024CD594254894D306A9E8CCE0310 /* Pods-ios_add2appTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-ios_add2appTests.release.xcconfig"; sourceTree = ""; }; + 34739A3100C03B6AD2FBA1A69208E33D /* FlutterPluginRegistrant-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FlutterPluginRegistrant-prefix.pch"; sourceTree = ""; }; + 360ACA4CEA1700C0A10C94F07A808822 /* EarlGrey.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = EarlGrey.framework; path = EarlGrey/EarlGrey.framework; sourceTree = ""; }; + 4D8A8D61362290C0D5CE861F6DB999F5 /* Pods-ios_add2appTests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-ios_add2appTests-acknowledgements.markdown"; sourceTree = ""; }; + 59C4454C6208CA53988E29FFF1F03C2E /* FlutterPluginRegistrant-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "FlutterPluginRegistrant-dummy.m"; sourceTree = ""; }; + 67E3D3C739B797BDDF7DA74A5A189597 /* Pods-ios_add2appTests-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-ios_add2appTests-resources.sh"; sourceTree = ""; }; + 6ED487DA1A38AAB091787BC50CA53CF2 /* Pods-ios_add2appTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-ios_add2appTests.debug.xcconfig"; sourceTree = ""; }; + 83957C53D6ECFC875FCEFF92BA9F494A /* Pods-ios_add2app-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-ios_add2app-acknowledgements.markdown"; sourceTree = ""; }; + 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + 95A58B9FAEAAC2794AECDC4F86C3C326 /* FlutterPluginRegistrant.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FlutterPluginRegistrant.xcconfig; sourceTree = ""; }; + A1930A36E88812FFBF49A0804CCA939D /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GeneratedPluginRegistrant.m; path = Classes/GeneratedPluginRegistrant.m; sourceTree = ""; }; + A1F9F94AEC6A3BC9E49D902FD400521C /* libFlutterPluginRegistrant.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libFlutterPluginRegistrant.a; path = libFlutterPluginRegistrant.a; sourceTree = BUILT_PRODUCTS_DIR; }; + AA66559E7B7855C135D54DA2C7A8CFF8 /* Pods-ios_add2app-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-ios_add2app-resources.sh"; sourceTree = ""; }; + AB2A3338AA26CE231BE2B5342F69B46B /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GeneratedPluginRegistrant.h; path = Classes/GeneratedPluginRegistrant.h; sourceTree = ""; }; + BA4A2FB788C185125BDA5CC68BB62189 /* Pods-ios_add2app-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-ios_add2app-acknowledgements.plist"; sourceTree = ""; }; + D88A982BBB84C6B4C9872862D0EA56AB /* Pods-ios_add2app.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-ios_add2app.release.xcconfig"; sourceTree = ""; }; + DE615DCA4A153537D97493FF8CED6982 /* libPods-ios_add2appTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libPods-ios_add2appTests.a"; path = "libPods-ios_add2appTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + E2FBD6F148E9F090879D1A4094328CA6 /* Pods-ios_add2app.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-ios_add2app.debug.xcconfig"; sourceTree = ""; }; + E9AD77BA6BE092262F6BE7483850E439 /* FlutterPluginRegistrant.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; lastKnownFileType = text; path = FlutterPluginRegistrant.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + F53D202D53B129D9043C5D20C63F7C5B /* libPods-ios_add2app.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libPods-ios_add2app.a"; path = "libPods-ios_add2app.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + F9A891A28EAB9CDA94DEE37408924ED3 /* Pods-ios_add2appTests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-ios_add2appTests-frameworks.sh"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 6679E7A93060530BFD746AEAC2636162 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 681B3B3876DD05F1333B71E0E036F736 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6FF13AA8FBCF04AD68E0EDA79DE8EBB2 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 0835BCB13E09235F999AF8DD8A1EE029 /* Pods */ = { + isa = PBXGroup; + children = ( + 7E4324F15200446DFC05780A204B3D03 /* EarlGrey */, + ); + name = Pods; + sourceTree = ""; + }; + 0F8D2E47FE03D3B91B51069F7C273AF4 /* Frameworks */ = { + isa = PBXGroup; + children = ( + ); + name = Frameworks; + sourceTree = ""; + }; + 1EBFFD5FB3D486ECD0B0D83E0728FE0A /* Support Files */ = { + isa = PBXGroup; + children = ( + 95A58B9FAEAAC2794AECDC4F86C3C326 /* FlutterPluginRegistrant.xcconfig */, + 59C4454C6208CA53988E29FFF1F03C2E /* FlutterPluginRegistrant-dummy.m */, + 34739A3100C03B6AD2FBA1A69208E33D /* FlutterPluginRegistrant-prefix.pch */, + ); + name = "Support Files"; + path = "../../../../Pods/Target Support Files/FlutterPluginRegistrant"; + sourceTree = ""; + }; + 2A095FE51150CE555F02CAFBB7B582D5 /* Pods-ios_add2appTests */ = { + isa = PBXGroup; + children = ( + 4D8A8D61362290C0D5CE861F6DB999F5 /* Pods-ios_add2appTests-acknowledgements.markdown */, + 0340BEC47E654F7ED86700BF354C1097 /* Pods-ios_add2appTests-acknowledgements.plist */, + 257FB6DC96D82E7F5C127C5F1567927A /* Pods-ios_add2appTests-dummy.m */, + F9A891A28EAB9CDA94DEE37408924ED3 /* Pods-ios_add2appTests-frameworks.sh */, + 67E3D3C739B797BDDF7DA74A5A189597 /* Pods-ios_add2appTests-resources.sh */, + 6ED487DA1A38AAB091787BC50CA53CF2 /* Pods-ios_add2appTests.debug.xcconfig */, + 2C0024CD594254894D306A9E8CCE0310 /* Pods-ios_add2appTests.release.xcconfig */, + ); + name = "Pods-ios_add2appTests"; + path = "Target Support Files/Pods-ios_add2appTests"; + sourceTree = ""; + }; + 2A7B06CCA5DC69E75CF079420142397E /* Pods-ios_add2app */ = { + isa = PBXGroup; + children = ( + 83957C53D6ECFC875FCEFF92BA9F494A /* Pods-ios_add2app-acknowledgements.markdown */, + BA4A2FB788C185125BDA5CC68BB62189 /* Pods-ios_add2app-acknowledgements.plist */, + 1402A9B5E7D2CCA622A4477C694702C1 /* Pods-ios_add2app-dummy.m */, + 095DFDEB7FE9B91E35B295B1D565C66C /* Pods-ios_add2app-frameworks.sh */, + AA66559E7B7855C135D54DA2C7A8CFF8 /* Pods-ios_add2app-resources.sh */, + E2FBD6F148E9F090879D1A4094328CA6 /* Pods-ios_add2app.debug.xcconfig */, + D88A982BBB84C6B4C9872862D0EA56AB /* Pods-ios_add2app.release.xcconfig */, + ); + name = "Pods-ios_add2app"; + path = "Target Support Files/Pods-ios_add2app"; + sourceTree = ""; + }; + 3451391EF88B6DE45CBECCADE541029C /* Frameworks */ = { + isa = PBXGroup; + children = ( + 360ACA4CEA1700C0A10C94F07A808822 /* EarlGrey.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 3527515EC30B454E896065F8868F22A7 /* Targets Support Files */ = { + isa = PBXGroup; + children = ( + 2A7B06CCA5DC69E75CF079420142397E /* Pods-ios_add2app */, + 2A095FE51150CE555F02CAFBB7B582D5 /* Pods-ios_add2appTests */, + ); + name = "Targets Support Files"; + sourceTree = ""; + }; + 41C4622842085EEBE7FE720209B65B45 /* Products */ = { + isa = PBXGroup; + children = ( + A1F9F94AEC6A3BC9E49D902FD400521C /* libFlutterPluginRegistrant.a */, + F53D202D53B129D9043C5D20C63F7C5B /* libPods-ios_add2app.a */, + DE615DCA4A153537D97493FF8CED6982 /* libPods-ios_add2appTests.a */, + ); + name = Products; + sourceTree = ""; + }; + 476E843886ACFE1E69B95F9D6E8C149D /* Flutter */ = { + isa = PBXGroup; + children = ( + 6A10680CFFBCF02A3CC075D128288703 /* Frameworks */, + A3575C9037E6869E63A356955F90FD6C /* Pod */, + ); + name = Flutter; + path = ../flutterapp/.ios/Flutter/engine; + sourceTree = ""; + }; + 6A10680CFFBCF02A3CC075D128288703 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 0A41E61C0D6BDA480DD4B0208BD5B175 /* Flutter.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 7DB346D0F39D3F0E887471402A8071AB = { + isa = PBXGroup; + children = ( + 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */, + E763F4A298776E6596B4DAEF7F7C9522 /* Development Pods */, + 0F8D2E47FE03D3B91B51069F7C273AF4 /* Frameworks */, + 0835BCB13E09235F999AF8DD8A1EE029 /* Pods */, + 41C4622842085EEBE7FE720209B65B45 /* Products */, + 3527515EC30B454E896065F8868F22A7 /* Targets Support Files */, + ); + sourceTree = ""; + }; + 7E4324F15200446DFC05780A204B3D03 /* EarlGrey */ = { + isa = PBXGroup; + children = ( + 3451391EF88B6DE45CBECCADE541029C /* Frameworks */, + ); + name = EarlGrey; + path = EarlGrey; + sourceTree = ""; + }; + A2FAC780F9C1566317BFB5848CA33440 /* FlutterPluginRegistrant */ = { + isa = PBXGroup; + children = ( + AB2A3338AA26CE231BE2B5342F69B46B /* GeneratedPluginRegistrant.h */, + A1930A36E88812FFBF49A0804CCA939D /* GeneratedPluginRegistrant.m */, + E77F9B8863B56865EB4729CB37765AA3 /* Pod */, + 1EBFFD5FB3D486ECD0B0D83E0728FE0A /* Support Files */, + ); + name = FlutterPluginRegistrant; + path = ../flutterapp/.ios/Flutter/FlutterPluginRegistrant; + sourceTree = ""; + }; + A3575C9037E6869E63A356955F90FD6C /* Pod */ = { + isa = PBXGroup; + children = ( + 0ED9CDB538F5B1479A4EC18C9079BEB4 /* Flutter.podspec */, + ); + name = Pod; + sourceTree = ""; + }; + E763F4A298776E6596B4DAEF7F7C9522 /* Development Pods */ = { + isa = PBXGroup; + children = ( + 476E843886ACFE1E69B95F9D6E8C149D /* Flutter */, + A2FAC780F9C1566317BFB5848CA33440 /* FlutterPluginRegistrant */, + ); + name = "Development Pods"; + sourceTree = ""; + }; + E77F9B8863B56865EB4729CB37765AA3 /* Pod */ = { + isa = PBXGroup; + children = ( + E9AD77BA6BE092262F6BE7483850E439 /* FlutterPluginRegistrant.podspec */, + ); + name = Pod; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 60A1622C71527E3F86523F3D30A82882 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 842ED9696E0F3095C702710833F78810 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FFA5376E650470CCD3E3DA405BEA55B6 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + A456B826DFE59B7675BB489F26BDB8D0 /* GeneratedPluginRegistrant.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 77F3683E8268E2B8342BFBD47DFF6870 /* FlutterPluginRegistrant */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7B31E5D9E892DEA54641309236981CBF /* Build configuration list for PBXNativeTarget "FlutterPluginRegistrant" */; + buildPhases = ( + FFA5376E650470CCD3E3DA405BEA55B6 /* Headers */, + CAF8D2F25C0CC8CD320A468F71B0B044 /* Sources */, + 6679E7A93060530BFD746AEAC2636162 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = FlutterPluginRegistrant; + productName = FlutterPluginRegistrant; + productReference = A1F9F94AEC6A3BC9E49D902FD400521C /* libFlutterPluginRegistrant.a */; + productType = "com.apple.product-type.library.static"; + }; + B2D9A26FE01FF2D9F6A10726FB523980 /* Pods-ios_add2app */ = { + isa = PBXNativeTarget; + buildConfigurationList = 76F4A3C1B5375FECF77997994AED822E /* Build configuration list for PBXNativeTarget "Pods-ios_add2app" */; + buildPhases = ( + 60A1622C71527E3F86523F3D30A82882 /* Headers */, + 2FA65D065EA93180829C661B95210079 /* Sources */, + 6FF13AA8FBCF04AD68E0EDA79DE8EBB2 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 6007895EDAFFFF19F2CF303EFCF90031 /* PBXTargetDependency */, + ); + name = "Pods-ios_add2app"; + productName = "Pods-ios_add2app"; + productReference = F53D202D53B129D9043C5D20C63F7C5B /* libPods-ios_add2app.a */; + productType = "com.apple.product-type.library.static"; + }; + C3B23FDAB1DED3C2A533EA8D97EFD75E /* Pods-ios_add2appTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7A16CE8B3E5329D27B240AA7679555B1 /* Build configuration list for PBXNativeTarget "Pods-ios_add2appTests" */; + buildPhases = ( + 842ED9696E0F3095C702710833F78810 /* Headers */, + 2A296D668E10670E35587DCD1CDDB0D3 /* Sources */, + 681B3B3876DD05F1333B71E0E036F736 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Pods-ios_add2appTests"; + productName = "Pods-ios_add2appTests"; + productReference = DE615DCA4A153537D97493FF8CED6982 /* libPods-ios_add2appTests.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + D41D8CD98F00B204E9800998ECF8427E /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0930; + LastUpgradeCheck = 0930; + }; + buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 7DB346D0F39D3F0E887471402A8071AB; + productRefGroup = 41C4622842085EEBE7FE720209B65B45 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 77F3683E8268E2B8342BFBD47DFF6870 /* FlutterPluginRegistrant */, + B2D9A26FE01FF2D9F6A10726FB523980 /* Pods-ios_add2app */, + C3B23FDAB1DED3C2A533EA8D97EFD75E /* Pods-ios_add2appTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 2A296D668E10670E35587DCD1CDDB0D3 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FC54914589BC06AB28064A2DEA23DE91 /* Pods-ios_add2appTests-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2FA65D065EA93180829C661B95210079 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D9239CC7E38BEDF9A8E18AED0B76007B /* Pods-ios_add2app-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + CAF8D2F25C0CC8CD320A468F71B0B044 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 90623EE0DFC611ECA79061CA2D8358A4 /* FlutterPluginRegistrant-dummy.m in Sources */, + D804971E28E8BBE38C2C989D16D071FF /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 6007895EDAFFFF19F2CF303EFCF90031 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FlutterPluginRegistrant; + target = 77F3683E8268E2B8342BFBD47DFF6870 /* FlutterPluginRegistrant */; + targetProxy = A2795B72F9E5BDBFA6D2F5A7866DFA2A /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 2D2C2AB4DD797F369011151C52081587 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 95A58B9FAEAAC2794AECDC4F86C3C326 /* FlutterPluginRegistrant.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + ENABLE_BITCODE = NO; + GCC_PREFIX_HEADER = "Target Support Files/FlutterPluginRegistrant/FlutterPluginRegistrant-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_MODULE_NAME = FlutterPluginRegistrant; + PRODUCT_NAME = FlutterPluginRegistrant; + PUBLIC_HEADERS_FOLDER_PATH = ""; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 40B45BB3CF3EE4476259302A7FAAD78F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGNING_ALLOWED = NO; + CODE_SIGNING_REQUIRED = NO; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_RELEASE=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRIP_INSTALLED_PRODUCT = NO; + SYMROOT = "${SRCROOT}/../build"; + }; + name = Release; + }; + 6F33B40DD5D27E9CF55BCFF00DB3C9C9 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 95A58B9FAEAAC2794AECDC4F86C3C326 /* FlutterPluginRegistrant.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + ENABLE_BITCODE = NO; + GCC_PREFIX_HEADER = "Target Support Files/FlutterPluginRegistrant/FlutterPluginRegistrant-prefix.pch"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_MODULE_NAME = FlutterPluginRegistrant; + PRODUCT_NAME = FlutterPluginRegistrant; + PUBLIC_HEADERS_FOLDER_PATH = ""; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 85ED3013A635C27F8B7FAF51362B108C /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGNING_ALLOWED = NO; + CODE_SIGNING_REQUIRED = NO; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_DEBUG=1", + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRIP_INSTALLED_PRODUCT = NO; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SYMROOT = "${SRCROOT}/../build"; + }; + name = Debug; + }; + 8960A0D527446655B249ECFACB336CA0 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E2FBD6F148E9F090879D1A4094328CA6 /* Pods-ios_add2app.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + ENABLE_BITCODE = NO; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MACH_O_TYPE = staticlib; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + A7C785B3AC959D2EFE2D88CE317298F8 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2C0024CD594254894D306A9E8CCE0310 /* Pods-ios_add2appTests.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + ENABLE_BITCODE = NO; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MACH_O_TYPE = staticlib; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + A9A5DCFF2EFEAF8C16074FF68A8D3869 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D88A982BBB84C6B4C9872862D0EA56AB /* Pods-ios_add2app.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + ENABLE_BITCODE = NO; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MACH_O_TYPE = staticlib; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + C52A2186FF5AB939EE047B9A9C920563 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 6ED487DA1A38AAB091787BC50CA53CF2 /* Pods-ios_add2appTests.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + ENABLE_BITCODE = NO; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MACH_O_TYPE = staticlib; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 85ED3013A635C27F8B7FAF51362B108C /* Debug */, + 40B45BB3CF3EE4476259302A7FAAD78F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 76F4A3C1B5375FECF77997994AED822E /* Build configuration list for PBXNativeTarget "Pods-ios_add2app" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8960A0D527446655B249ECFACB336CA0 /* Debug */, + A9A5DCFF2EFEAF8C16074FF68A8D3869 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7A16CE8B3E5329D27B240AA7679555B1 /* Build configuration list for PBXNativeTarget "Pods-ios_add2appTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C52A2186FF5AB939EE047B9A9C920563 /* Debug */, + A7C785B3AC959D2EFE2D88CE317298F8 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7B31E5D9E892DEA54641309236981CBF /* Build configuration list for PBXNativeTarget "FlutterPluginRegistrant" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6F33B40DD5D27E9CF55BCFF00DB3C9C9 /* Debug */, + 2D2C2AB4DD797F369011151C52081587 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = D41D8CD98F00B204E9800998ECF8427E /* Project object */; +} diff --git a/dev/integration_tests/ios_add2app/Pods/Target Support Files/FlutterPluginRegistrant/FlutterPluginRegistrant-dummy.m b/dev/integration_tests/ios_add2app/Pods/Target Support Files/FlutterPluginRegistrant/FlutterPluginRegistrant-dummy.m new file mode 100644 index 0000000000..e6bdef1cfa --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Target Support Files/FlutterPluginRegistrant/FlutterPluginRegistrant-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_FlutterPluginRegistrant : NSObject +@end +@implementation PodsDummy_FlutterPluginRegistrant +@end diff --git a/dev/integration_tests/ios_add2app/Pods/Target Support Files/FlutterPluginRegistrant/FlutterPluginRegistrant-prefix.pch b/dev/integration_tests/ios_add2app/Pods/Target Support Files/FlutterPluginRegistrant/FlutterPluginRegistrant-prefix.pch new file mode 100644 index 0000000000..beb2a24418 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Target Support Files/FlutterPluginRegistrant/FlutterPluginRegistrant-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/dev/integration_tests/ios_add2app/Pods/Target Support Files/FlutterPluginRegistrant/FlutterPluginRegistrant.xcconfig b/dev/integration_tests/ios_add2app/Pods/Target Support Files/FlutterPluginRegistrant/FlutterPluginRegistrant.xcconfig new file mode 100644 index 0000000000..a5cdf85cce --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Target Support Files/FlutterPluginRegistrant/FlutterPluginRegistrant.xcconfig @@ -0,0 +1,12 @@ +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FlutterPluginRegistrant +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../flutterapp/.ios/Flutter/engine" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/FlutterPluginRegistrant" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Flutter" "${PODS_ROOT}/Headers/Public/FlutterPluginRegistrant" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/../flutterapp/.ios/Flutter/FlutterPluginRegistrant +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +#include "/Users/dnfield/src/flutter/dev/integration_tests/ios_add2app/flutterapp/.ios/Flutter/Generated.xcconfig" +#include "/Users/dnfield/src/flutter/dev/integration_tests/ios_add2app/flutterapp/.ios/Flutter/Generated.xcconfig" diff --git a/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app-acknowledgements.markdown b/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app-acknowledgements.markdown new file mode 100644 index 0000000000..102af75385 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app-acknowledgements.markdown @@ -0,0 +1,3 @@ +# Acknowledgements +This application makes use of the following third party libraries: +Generated by CocoaPods - https://cocoapods.org diff --git a/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app-acknowledgements.plist b/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app-acknowledgements.plist new file mode 100644 index 0000000000..7acbad1eab --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app-acknowledgements.plist @@ -0,0 +1,29 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - https://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app-dummy.m b/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app-dummy.m new file mode 100644 index 0000000000..7d9ccceef9 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_ios_add2app : NSObject +@end +@implementation PodsDummy_Pods_ios_add2app +@end diff --git a/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app-frameworks.sh b/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app-frameworks.sh new file mode 100755 index 0000000000..90442cdc7a --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app-frameworks.sh @@ -0,0 +1,153 @@ +#!/bin/sh +set -e +set -u +set -o pipefail + +if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then + # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy + # frameworks to, so exit 0 (signalling the script phase was successful). + exit 0 +fi + +echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + +COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" +SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" + +# Used as a return value for each invocation of `strip_invalid_archs` function. +STRIP_BINARY_RETVAL=0 + +# This protects against multiple targets copying the same framework dependency at the same time. The solution +# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html +RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") + +# Copies and strips a vendored framework +install_framework() +{ + if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then + local source="${BUILT_PRODUCTS_DIR}/$1" + elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then + local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" + elif [ -r "$1" ]; then + local source="$1" + fi + + local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + + if [ -L "${source}" ]; then + echo "Symlinked..." + source="$(readlink "${source}")" + fi + + # Use filter instead of exclude so missing patterns don't throw errors. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" + + local basename + basename="$(basename -s .framework "$1")" + binary="${destination}/${basename}.framework/${basename}" + if ! [ -r "$binary" ]; then + binary="${destination}/${basename}" + fi + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then + strip_invalid_archs "$binary" + fi + + # Resign the code if required by the build settings to avoid unstable apps + code_sign_if_enabled "${destination}/$(basename "$1")" + + # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. + if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then + local swift_runtime_libs + swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) + for lib in $swift_runtime_libs; do + echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" + rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" + code_sign_if_enabled "${destination}/${lib}" + done + fi +} + +# Copies and strips a vendored dSYM +install_dsym() { + local source="$1" + if [ -r "$source" ]; then + # Copy the dSYM into a the targets temp dir. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" + + local basename + basename="$(basename -s .framework.dSYM "$source")" + binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}" + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"Mach-O dSYM companion"* ]]; then + strip_invalid_archs "$binary" + fi + + if [[ $STRIP_BINARY_RETVAL == 1 ]]; then + # Move the stripped file into its final destination. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}" + else + # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. + touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM" + fi + fi +} + +# Signs a framework with the provided identity +code_sign_if_enabled() { + if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then + # Use the current code_sign_identitiy + echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" + local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" + + if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + code_sign_cmd="$code_sign_cmd &" + fi + echo "$code_sign_cmd" + eval "$code_sign_cmd" + fi +} + +# Strip invalid architectures +strip_invalid_archs() { + binary="$1" + # Get architectures for current target binary + binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" + # Intersect them with the architectures we are building for + intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" + # If there are no archs supported by this binary then warn the user + if [[ -z "$intersected_archs" ]]; then + echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." + STRIP_BINARY_RETVAL=0 + return + fi + stripped="" + for arch in $binary_archs; do + if ! [[ "${ARCHS}" == *"$arch"* ]]; then + # Strip non-valid architectures in-place + lipo -remove "$arch" -output "$binary" "$binary" || exit 1 + stripped="$stripped $arch" + fi + done + if [[ "$stripped" ]]; then + echo "Stripped $binary of architectures:$stripped" + fi + STRIP_BINARY_RETVAL=1 +} + + +if [[ "$CONFIGURATION" == "Debug" ]]; then + install_framework "${PODS_ROOT}/../flutterapp/.ios/Flutter/engine/Flutter.framework" +fi +if [[ "$CONFIGURATION" == "Release" ]]; then + install_framework "${PODS_ROOT}/../flutterapp/.ios/Flutter/engine/Flutter.framework" +fi +if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + wait +fi diff --git a/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app-resources.sh b/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app-resources.sh new file mode 100755 index 0000000000..345301f2c5 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app-resources.sh @@ -0,0 +1,118 @@ +#!/bin/sh +set -e +set -u +set -o pipefail + +if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then + # If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy + # resources to, so exit 0 (signalling the script phase was successful). + exit 0 +fi + +mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + +RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt +> "$RESOURCES_TO_COPY" + +XCASSET_FILES=() + +# This protects against multiple targets copying the same framework dependency at the same time. The solution +# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html +RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") + +case "${TARGETED_DEVICE_FAMILY:-}" in + 1,2) + TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" + ;; + 1) + TARGET_DEVICE_ARGS="--target-device iphone" + ;; + 2) + TARGET_DEVICE_ARGS="--target-device ipad" + ;; + 3) + TARGET_DEVICE_ARGS="--target-device tv" + ;; + 4) + TARGET_DEVICE_ARGS="--target-device watch" + ;; + *) + TARGET_DEVICE_ARGS="--target-device mac" + ;; +esac + +install_resource() +{ + if [[ "$1" = /* ]] ; then + RESOURCE_PATH="$1" + else + RESOURCE_PATH="${PODS_ROOT}/$1" + fi + if [[ ! -e "$RESOURCE_PATH" ]] ; then + cat << EOM +error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. +EOM + exit 1 + fi + case $RESOURCE_PATH in + *.storyboard) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true + ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} + ;; + *.xib) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true + ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} + ;; + *.framework) + echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true + mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + ;; + *.xcdatamodel) + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true + xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" + ;; + *.xcdatamodeld) + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true + xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" + ;; + *.xcmappingmodel) + echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true + xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" + ;; + *.xcassets) + ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" + XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") + ;; + *) + echo "$RESOURCE_PATH" || true + echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" + ;; + esac +} + +mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then + mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi +rm -f "$RESOURCES_TO_COPY" + +if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ] +then + # Find all other xcassets (this unfortunately includes those of path pods and other targets). + OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) + while read line; do + if [[ $line != "${PODS_ROOT}*" ]]; then + XCASSET_FILES+=("$line") + fi + done <<<"$OTHER_XCASSETS" + + if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then + printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + else + printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_TEMP_DIR}/assetcatalog_generated_info_cocoapods.plist" + fi +fi diff --git a/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app.debug.xcconfig b/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app.debug.xcconfig new file mode 100644 index 0000000000..55056d17af --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app.debug.xcconfig @@ -0,0 +1,12 @@ +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../flutterapp/.ios/Flutter/engine" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/EarlGrey" "${PODS_ROOT}/Headers/Public/Flutter" "${PODS_ROOT}/Headers/Public/FlutterPluginRegistrant" +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FlutterPluginRegistrant" +OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/EarlGrey" -isystem "${PODS_ROOT}/Headers/Public/Flutter" -isystem "${PODS_ROOT}/Headers/Public/FlutterPluginRegistrant" +OTHER_LDFLAGS = $(inherited) -ObjC -l"FlutterPluginRegistrant" -framework "Flutter" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +#include "/Users/dnfield/src/flutter/dev/integration_tests/ios_add2app/flutterapp/.ios/Flutter/Generated.xcconfig" diff --git a/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app.release.xcconfig b/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app.release.xcconfig new file mode 100644 index 0000000000..55056d17af --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app.release.xcconfig @@ -0,0 +1,12 @@ +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../flutterapp/.ios/Flutter/engine" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/EarlGrey" "${PODS_ROOT}/Headers/Public/Flutter" "${PODS_ROOT}/Headers/Public/FlutterPluginRegistrant" +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FlutterPluginRegistrant" +OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/EarlGrey" -isystem "${PODS_ROOT}/Headers/Public/Flutter" -isystem "${PODS_ROOT}/Headers/Public/FlutterPluginRegistrant" +OTHER_LDFLAGS = $(inherited) -ObjC -l"FlutterPluginRegistrant" -framework "Flutter" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +#include "/Users/dnfield/src/flutter/dev/integration_tests/ios_add2app/flutterapp/.ios/Flutter/Generated.xcconfig" diff --git a/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests-acknowledgements.markdown b/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests-acknowledgements.markdown new file mode 100644 index 0000000000..ab1dcc2658 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests-acknowledgements.markdown @@ -0,0 +1,605 @@ +# Acknowledgements +This application makes use of the following third party libraries: + +## EarlGrey + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +-------------------------------------------------------------------------------------------- + +Attribution 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More_considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution 4.0 International Public License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution 4.0 International Public License ("Public License"). To the +extent this Public License may be interpreted as a contract, You are +granted the Licensed Rights in consideration of Your acceptance of +these terms and conditions, and the Licensor grants You such rights in +consideration of benefits the Licensor receives from making the +Licensed Material available under these terms and conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + d. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + e. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + f. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + g. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + h. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + i. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + j. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + k. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + 4. If You Share Adapted Material You produce, the Adapter's + License You apply must not prevent recipients of the Adapted + Material from complying with this Public License. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material; and + + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public licenses. +Notwithstanding, Creative Commons may elect to apply one of its public +licenses to material it publishes and in those instances will be +considered the "Licensor." Except for the limited purpose of indicating +that material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the public +licenses. + +Creative Commons may be contacted at creativecommons.org. + +Generated by CocoaPods - https://cocoapods.org diff --git a/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests-acknowledgements.plist b/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests-acknowledgements.plist new file mode 100644 index 0000000000..c6d031616e --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests-acknowledgements.plist @@ -0,0 +1,637 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +-------------------------------------------------------------------------------------------- + +Attribution 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More_considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution 4.0 International Public License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution 4.0 International Public License ("Public License"). To the +extent this Public License may be interpreted as a contract, You are +granted the Licensed Rights in consideration of Your acceptance of +these terms and conditions, and the Licensor grants You such rights in +consideration of benefits the Licensor receives from making the +Licensed Material available under these terms and conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + d. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + e. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + f. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + g. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + h. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + i. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + j. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + k. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + 4. If You Share Adapted Material You produce, the Adapter's + License You apply must not prevent recipients of the Adapted + Material from complying with this Public License. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material; and + + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public licenses. +Notwithstanding, Creative Commons may elect to apply one of its public +licenses to material it publishes and in those instances will be +considered the "Licensor." Except for the limited purpose of indicating +that material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the public +licenses. + +Creative Commons may be contacted at creativecommons.org. + + License + Apache 2.0, CC-BY 4.0 + Title + EarlGrey + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - https://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests-dummy.m b/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests-dummy.m new file mode 100644 index 0000000000..481870f2d0 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_ios_add2appTests : NSObject +@end +@implementation PodsDummy_Pods_ios_add2appTests +@end diff --git a/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests-frameworks.sh b/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests-frameworks.sh new file mode 100755 index 0000000000..5934ef58c1 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests-frameworks.sh @@ -0,0 +1,155 @@ +#!/bin/sh +set -e +set -u +set -o pipefail + +if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then + # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy + # frameworks to, so exit 0 (signalling the script phase was successful). + exit 0 +fi + +echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + +COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" +SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" + +# Used as a return value for each invocation of `strip_invalid_archs` function. +STRIP_BINARY_RETVAL=0 + +# This protects against multiple targets copying the same framework dependency at the same time. The solution +# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html +RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") + +# Copies and strips a vendored framework +install_framework() +{ + if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then + local source="${BUILT_PRODUCTS_DIR}/$1" + elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then + local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" + elif [ -r "$1" ]; then + local source="$1" + fi + + local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + + if [ -L "${source}" ]; then + echo "Symlinked..." + source="$(readlink "${source}")" + fi + + # Use filter instead of exclude so missing patterns don't throw errors. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" + + local basename + basename="$(basename -s .framework "$1")" + binary="${destination}/${basename}.framework/${basename}" + if ! [ -r "$binary" ]; then + binary="${destination}/${basename}" + fi + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then + strip_invalid_archs "$binary" + fi + + # Resign the code if required by the build settings to avoid unstable apps + code_sign_if_enabled "${destination}/$(basename "$1")" + + # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. + if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then + local swift_runtime_libs + swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) + for lib in $swift_runtime_libs; do + echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" + rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" + code_sign_if_enabled "${destination}/${lib}" + done + fi +} + +# Copies and strips a vendored dSYM +install_dsym() { + local source="$1" + if [ -r "$source" ]; then + # Copy the dSYM into a the targets temp dir. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" + + local basename + basename="$(basename -s .framework.dSYM "$source")" + binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}" + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"Mach-O dSYM companion"* ]]; then + strip_invalid_archs "$binary" + fi + + if [[ $STRIP_BINARY_RETVAL == 1 ]]; then + # Move the stripped file into its final destination. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}" + else + # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. + touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM" + fi + fi +} + +# Signs a framework with the provided identity +code_sign_if_enabled() { + if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then + # Use the current code_sign_identitiy + echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" + local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" + + if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + code_sign_cmd="$code_sign_cmd &" + fi + echo "$code_sign_cmd" + eval "$code_sign_cmd" + fi +} + +# Strip invalid architectures +strip_invalid_archs() { + binary="$1" + # Get architectures for current target binary + binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" + # Intersect them with the architectures we are building for + intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" + # If there are no archs supported by this binary then warn the user + if [[ -z "$intersected_archs" ]]; then + echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." + STRIP_BINARY_RETVAL=0 + return + fi + stripped="" + for arch in $binary_archs; do + if ! [[ "${ARCHS}" == *"$arch"* ]]; then + # Strip non-valid architectures in-place + lipo -remove "$arch" -output "$binary" "$binary" || exit 1 + stripped="$stripped $arch" + fi + done + if [[ "$stripped" ]]; then + echo "Stripped $binary of architectures:$stripped" + fi + STRIP_BINARY_RETVAL=1 +} + + +if [[ "$CONFIGURATION" == "Debug" ]]; then + install_framework "${PODS_ROOT}/../flutterapp/.ios/Flutter/engine/Flutter.framework" + install_framework "${PODS_ROOT}/EarlGrey/EarlGrey/EarlGrey.framework" +fi +if [[ "$CONFIGURATION" == "Release" ]]; then + install_framework "${PODS_ROOT}/../flutterapp/.ios/Flutter/engine/Flutter.framework" + install_framework "${PODS_ROOT}/EarlGrey/EarlGrey/EarlGrey.framework" +fi +if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + wait +fi diff --git a/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests-resources.sh b/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests-resources.sh new file mode 100755 index 0000000000..345301f2c5 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests-resources.sh @@ -0,0 +1,118 @@ +#!/bin/sh +set -e +set -u +set -o pipefail + +if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then + # If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy + # resources to, so exit 0 (signalling the script phase was successful). + exit 0 +fi + +mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + +RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt +> "$RESOURCES_TO_COPY" + +XCASSET_FILES=() + +# This protects against multiple targets copying the same framework dependency at the same time. The solution +# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html +RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") + +case "${TARGETED_DEVICE_FAMILY:-}" in + 1,2) + TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" + ;; + 1) + TARGET_DEVICE_ARGS="--target-device iphone" + ;; + 2) + TARGET_DEVICE_ARGS="--target-device ipad" + ;; + 3) + TARGET_DEVICE_ARGS="--target-device tv" + ;; + 4) + TARGET_DEVICE_ARGS="--target-device watch" + ;; + *) + TARGET_DEVICE_ARGS="--target-device mac" + ;; +esac + +install_resource() +{ + if [[ "$1" = /* ]] ; then + RESOURCE_PATH="$1" + else + RESOURCE_PATH="${PODS_ROOT}/$1" + fi + if [[ ! -e "$RESOURCE_PATH" ]] ; then + cat << EOM +error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. +EOM + exit 1 + fi + case $RESOURCE_PATH in + *.storyboard) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true + ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} + ;; + *.xib) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true + ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} + ;; + *.framework) + echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true + mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + ;; + *.xcdatamodel) + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true + xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" + ;; + *.xcdatamodeld) + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true + xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" + ;; + *.xcmappingmodel) + echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true + xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" + ;; + *.xcassets) + ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" + XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") + ;; + *) + echo "$RESOURCE_PATH" || true + echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" + ;; + esac +} + +mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then + mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi +rm -f "$RESOURCES_TO_COPY" + +if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ] +then + # Find all other xcassets (this unfortunately includes those of path pods and other targets). + OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) + while read line; do + if [[ $line != "${PODS_ROOT}*" ]]; then + XCASSET_FILES+=("$line") + fi + done <<<"$OTHER_XCASSETS" + + if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then + printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + else + printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_TEMP_DIR}/assetcatalog_generated_info_cocoapods.plist" + fi +fi diff --git a/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests.debug.xcconfig b/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests.debug.xcconfig new file mode 100644 index 0000000000..8a50e45ea9 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests.debug.xcconfig @@ -0,0 +1,11 @@ +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../flutterapp/.ios/Flutter/engine" "$(PLATFORM_DIR)/Developer/Library/Frameworks" "${PODS_ROOT}/EarlGrey/EarlGrey" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/EarlGrey" "${PODS_ROOT}/Headers/Public/Flutter" "${PODS_ROOT}/Headers/Public/FlutterPluginRegistrant" +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/EarlGrey" -isystem "${PODS_ROOT}/Headers/Public/Flutter" -isystem "${PODS_ROOT}/Headers/Public/FlutterPluginRegistrant" +OTHER_LDFLAGS = $(inherited) -ObjC -framework "CoreData" -framework "CoreFoundation" -framework "CoreGraphics" -framework "EarlGrey" -framework "Flutter" -framework "Foundation" -framework "IOKit" -framework "QuartzCore" -framework "UIKit" -framework "XCTest" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +#include "/Users/dnfield/src/flutter/dev/integration_tests/ios_add2app/flutterapp/.ios/Flutter/Generated.xcconfig" diff --git a/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests.release.xcconfig b/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests.release.xcconfig new file mode 100644 index 0000000000..8a50e45ea9 --- /dev/null +++ b/dev/integration_tests/ios_add2app/Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests.release.xcconfig @@ -0,0 +1,11 @@ +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../flutterapp/.ios/Flutter/engine" "$(PLATFORM_DIR)/Developer/Library/Frameworks" "${PODS_ROOT}/EarlGrey/EarlGrey" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/EarlGrey" "${PODS_ROOT}/Headers/Public/Flutter" "${PODS_ROOT}/Headers/Public/FlutterPluginRegistrant" +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/EarlGrey" -isystem "${PODS_ROOT}/Headers/Public/Flutter" -isystem "${PODS_ROOT}/Headers/Public/FlutterPluginRegistrant" +OTHER_LDFLAGS = $(inherited) -ObjC -framework "CoreData" -framework "CoreFoundation" -framework "CoreGraphics" -framework "EarlGrey" -framework "Flutter" -framework "Foundation" -framework "IOKit" -framework "QuartzCore" -framework "UIKit" -framework "XCTest" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +#include "/Users/dnfield/src/flutter/dev/integration_tests/ios_add2app/flutterapp/.ios/Flutter/Generated.xcconfig" diff --git a/dev/integration_tests/ios_add2app/README.md b/dev/integration_tests/ios_add2app/README.md new file mode 100644 index 0000000000..78037466b6 --- /dev/null +++ b/dev/integration_tests/ios_add2app/README.md @@ -0,0 +1,28 @@ +# iOS Add2App Test + +This application demonstrates some basic functionality for Add2App, +along with a native iOS ViewController as a baseline and to demonstrate +interaction. + +The following functionality is currently implemented: + +1. A regular iOS view controller (UIViewController), similar to the default + `flutter create` template (NativeViewController.m). +1. A FlutterViewController subclass that takes over full screen. Demos showing + this both from a cold/fresh engine state and a warm engine state + (FullScreenViewController.m). +1. A demo of pushing a FlutterViewController on as a child view. +1. A demo of showing both the native and the Flutter views using a platform + channel to to interact with each other (HybridViewController.m). +1. A demo of showing two FlutterViewControllers simultaneously + (DualViewController.m). + +A few key things are tested here (IntegrationTests.m): + +1. The ability to pre-warm the engine and attach/detatch a ViewController from + it. +1. The ability to use platform channels to communicate between views. +1. The ability to simultaneously run two instances of the engine. +1. That a FlutterViewController can be freed when no longer in use (also tested + from FlutterViewControllerTests.m). +1. That a FlutterEngine can be freed when no longer in use. \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/build_and_test.sh b/dev/integration_tests/ios_add2app/build_and_test.sh new file mode 100755 index 0000000000..50155ed09b --- /dev/null +++ b/dev/integration_tests/ios_add2app/build_and_test.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -e + +cd "$(dirname "$0")" + +pushd flutterapp +../../../../bin/flutter build ios --debug --no-codesign -v +popd + +pod install +os_version=$(xcrun --show-sdk-version --sdk iphonesimulator) +xcodebuild -workspace ios_add2app.xcworkspace -scheme ios_add2appTests -sdk "iphonesimulator$os_version" -destination "OS=$os_version,name=iPhone X" test \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/flutterapp/.gitignore b/dev/integration_tests/ios_add2app/flutterapp/.gitignore new file mode 100644 index 0000000000..cdecf14aaa --- /dev/null +++ b/dev/integration_tests/ios_add2app/flutterapp/.gitignore @@ -0,0 +1,41 @@ +.DS_Store +.dart_tool/ + +.packages +.pub/ + +.idea/ +.vagrant/ +.sconsign.dblite +.svn/ + +*.swp +profile + +DerivedData/ + +.generated/ + +*.pbxuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 + +!default.pbxuser +!default.mode1v3 +!default.mode2v3 +!default.perspectivev3 + +xcuserdata + +*.moved-aside + +*.pyc +*sync/ +Icon? +.tags* + +build/ +.android/ +.ios/ +.flutter-plugins diff --git a/dev/integration_tests/ios_add2app/flutterapp/.metadata b/dev/integration_tests/ios_add2app/flutterapp/.metadata new file mode 100644 index 0000000000..04ff028c3d --- /dev/null +++ b/dev/integration_tests/ios_add2app/flutterapp/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 06179457d553b96b4d7421a08ac90535ca2c9632 + channel: unknown + +project_type: module diff --git a/dev/integration_tests/ios_add2app/flutterapp/README.md b/dev/integration_tests/ios_add2app/flutterapp/README.md new file mode 100644 index 0000000000..a627bb57a9 --- /dev/null +++ b/dev/integration_tests/ios_add2app/flutterapp/README.md @@ -0,0 +1,8 @@ +# ios_add2app_flutter + +A new flutter module project. + +## Getting Started + +For help getting started with Flutter, view our online +[documentation](https://flutter.io/). diff --git a/dev/integration_tests/ios_add2app/flutterapp/lib/main.dart b/dev/integration_tests/ios_add2app/flutterapp/lib/main.dart new file mode 100644 index 0000000000..ea7fe54cb4 --- /dev/null +++ b/dev/integration_tests/ios_add2app/flutterapp/lib/main.dart @@ -0,0 +1,190 @@ +import 'dart:async'; +import 'dart:ui' as ui; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import 'marquee.dart'; + +/// Route names. (See [main] for more details.) +/// +/// The route names must match those sent by the platform-specific component. +const String greenMarqueeRouteName = 'marquee_green'; +const String purpleMarqueeRouteName = 'marquee_purple'; +const String fullscreenRouteName = 'full'; +const String hybridRouteName = 'hybrid'; + +/// Channel used to let the Flutter app know to reset the app to a specific +/// route. See the [run] method. +/// +/// Note that we shouldn't use the `setInitialRoute` method on the system +/// navigation channel, as that never gets propagated back to Flutter after the +/// initial call. +const String _kReloadChannelName = 'reload'; +const BasicMessageChannel _kReloadChannel = + BasicMessageChannel(_kReloadChannelName, StringCodec()); + +void main() { + // Start listening immediately for messages from the iOS side. ObjC calls + // will be made to let us know when we should be changing the app state. + _kReloadChannel.setMessageHandler(run); + // Start off with whatever the initial route is supposed to be. + run(ui.window.defaultRouteName); +} + +Future run(String name) async { + // The platform-specific component will call [setInitialRoute] on the Flutter + // view (or view controller for iOS) to set [ui.window.defaultRouteName]. + // We then dispatch based on the route names to show different Flutter + // widgets. + // Since we don't really care about Flutter-side navigation in this app, we're + // not using a regular routes map. + switch (name) { + case greenMarqueeRouteName: + runApp(Marquee(color: Colors.green[400])); + break; + case purpleMarqueeRouteName: + runApp(Marquee(color: Colors.purple[400])); + break; + case fullscreenRouteName: + case hybridRouteName: + default: + runApp(FlutterView(initialRoute: name)); + break; + } + return ''; +} + +class FlutterView extends StatelessWidget { + const FlutterView({@required this.initialRoute}); + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter View', + home: MyHomePage(initialRoute: initialRoute), + ); + } + + final String initialRoute; +} + +class MyHomePage extends StatefulWidget { + const MyHomePage({this.initialRoute}); + + @override + _MyHomePageState createState() => _MyHomePageState(); + + final String initialRoute; + + /// Whether we should display the home page in fullscreen mode. + /// + /// If in full screen mode, we will use an [AppBar] widget to show our own + /// title. + bool get isFullscreen => initialRoute == fullscreenRouteName; + + /// Whether tapping the Flutter button should notify an external source. + /// + /// If false, the button will increments our own internal counter. + bool get hasExternalTarget => initialRoute == hybridRouteName; +} + +class _MyHomePageState extends State { + // The name of the message channel used to communicate with the + // platform-specific component. + // + // This string must match the one used on the platform side. + static const String _channel = 'increment'; + + // The message to send to the platform-specific component when our button + // is tapped. + static const String _pong = 'pong'; + + // Used to pass messages between the platform-specific component and the + // Flutter component. + static const BasicMessageChannel _platform = + BasicMessageChannel(_channel, StringCodec()); + + // An internal count. Normally this represents the number of times that the + // button on the Flutter page has been tapped. + int _counter = 0; + + @override + void initState() { + super.initState(); + _platform.setMessageHandler(_handlePlatformIncrement); + } + + /// Directly increments our internal counter and rebuilds the UI. + void _incrementCounter() { + setState(() { + _counter++; + }); + } + + /// Callback for messages sent by the platform-specific component. + /// + /// Increments our internal counter. + Future _handlePlatformIncrement(String message) async { + // Normally we'd dispatch based on the value of [message], but in this + // sample, there is only one message that is sent to us. + _incrementCounter(); + return ''; + } + + /// Sends a message to the platform-specific component to increment its + /// counter. + void _sendFlutterIncrement() { + _platform.send(_pong); + } + + @override + Widget build(BuildContext context) { + final String buttonName = + widget.hasExternalTarget ? 'Platform button' : 'Button'; + return Scaffold( + appBar: widget.isFullscreen + ? AppBar(title: const Text('Fullscreen Flutter')) + : null, + body: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Center( + child: Text( + '$buttonName tapped $_counter time${_counter == 1 ? '' : 's'}.', + style: const TextStyle(fontSize: 17.0), + ), + ), + const FlatButton( + child: Text('POP'), + onPressed: SystemNavigator.pop, + ), + ], + ), + ), + Container( + padding: const EdgeInsets.only(bottom: 15.0, left: 5.0), + child: Row( + children: const [ + Text('Flutter', style: TextStyle(fontSize: 30.0)), + ], + ), + ), + ], + ), + floatingActionButton: Semantics( + label: 'Increment via Flutter', + child: FloatingActionButton( + onPressed: widget.hasExternalTarget + ? _sendFlutterIncrement + : _incrementCounter, + child: const Icon(Icons.add), + ), + ), + ); + } +} diff --git a/dev/integration_tests/ios_add2app/flutterapp/lib/marquee.dart b/dev/integration_tests/ios_add2app/flutterapp/lib/marquee.dart new file mode 100644 index 0000000000..934a04bb46 --- /dev/null +++ b/dev/integration_tests/ios_add2app/flutterapp/lib/marquee.dart @@ -0,0 +1,70 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/animation.dart'; +import 'package:flutter/services.dart'; + +class _MarqueeText extends AnimatedWidget { + const _MarqueeText({Key key, Animation animation}) + : super(key: key, listenable: animation); + + @override + Widget build(BuildContext context) { + final Animation animation = listenable; + return Container( + margin: EdgeInsets.only(left: animation.value), + child: const Text( + 'This is Marquee', + softWrap: false, + ), + ); + } +} + +class Marquee extends StatefulWidget { + const Marquee({this.color}); + + final Color color; + + @override + State createState() => MarqueeState(); +} + +class MarqueeState extends State with SingleTickerProviderStateMixin { + AnimationController controller; + Animation animation; + + @override + void initState() { + super.initState(); + controller = AnimationController( + duration: const Duration(milliseconds: 2000), + vsync: this, + ); + animation = Tween(begin: 0.0, end: 400.0).animate(controller); + controller.repeat(); + } + + @override + void dispose() { + controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Material( + color: widget.color, + child: Directionality( + textDirection: TextDirection.ltr, + child: Column( + children: [ + Align( + child: _MarqueeText(animation: animation), + alignment: Alignment.centerLeft, + ), + const FlatButton(child: Text('POP'), onPressed: SystemNavigator.pop), + ], + ), + ), + ); + } +} diff --git a/dev/integration_tests/ios_add2app/flutterapp/pubspec.yaml b/dev/integration_tests/ios_add2app/flutterapp/pubspec.yaml new file mode 100644 index 0000000000..02629b37fe --- /dev/null +++ b/dev/integration_tests/ios_add2app/flutterapp/pubspec.yaml @@ -0,0 +1,101 @@ +name: ios_add2app_flutter +description: A new flutter module project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# Read more about versioning at semver.org. +# +# This version is used _only_ for the Runner app, which is used if you just do +# a `flutter run` or a `flutter make-host-app-editable`. It has no impact +# on any other native host app that you embed your Flutter project into. +version: 1.0.0+1 + +environment: + sdk: ">=2.0.0-dev.68.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: 0.1.2 + + collection: 1.14.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + meta: 1.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + typed_data: 1.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + vector_math: 2.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + +dev_dependencies: + flutter_test: + sdk: flutter + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + + async: 2.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + boolean_selector: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + matcher: 0.12.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + path: 1.6.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + pedantic: 1.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + quiver: 2.0.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + source_span: 1.5.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + stream_channel: 1.6.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + string_scanner: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + term_glyph: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + test_api: 0.2.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + +flutter: + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add Flutter specific assets to your application, add an assets section, + # like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.io/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.io/assets-and-images/#from-packages + + # To add Flutter specific custom fonts to your application, add a fonts + # section here, in this "flutter" section. Each entry in this list should + # have a "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.io/custom-fonts/#from-packages + + # This section identifies your Flutter project as a module meant for + # embedding in a native host app. These identifiers should _not_ ordinarily + # be changed after generation - they are used to ensure that the tooling can + # maintain consistency when adding or modifying assets and plugins. + # They also do not have any bearing on your native host application's + # identifiers, which may be completely independent or the same as these. + module: + androidPackage: com.example.iosadd2appflutter + iosBundleIdentifier: com.example.iosAdd2appFlutter + +# PUBSPEC CHECKSUM: 3a66 diff --git a/dev/integration_tests/ios_add2app/flutterapp/test/widget_test.dart b/dev/integration_tests/ios_add2app/flutterapp/test/widget_test.dart new file mode 100644 index 0000000000..153f055660 --- /dev/null +++ b/dev/integration_tests/ios_add2app/flutterapp/test/widget_test.dart @@ -0,0 +1,3 @@ +void main() { + +} diff --git a/dev/integration_tests/ios_add2app/ios_add2app.xcodeproj/project.pbxproj b/dev/integration_tests/ios_add2app/ios_add2app.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..8ac6d94d7d --- /dev/null +++ b/dev/integration_tests/ios_add2app/ios_add2app.xcodeproj/project.pbxproj @@ -0,0 +1,651 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 09C65652A2B48A21C94FF831 /* EarlGrey.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DE1EF0F5719FBB45225A9EC3 /* EarlGrey.framework */; }; + 24D2933821A29628008787A5 /* IntegrationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 24D2933721A29628008787A5 /* IntegrationTests.m */; }; + 24E221BA21A28A0B008ADF09 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 24E221B921A28A0B008ADF09 /* AppDelegate.m */; }; + 24E221C821A28A0C008ADF09 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 24E221C721A28A0C008ADF09 /* main.m */; }; + 24E221DB21A28B23008ADF09 /* HybridViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 24E221D021A28B22008ADF09 /* HybridViewController.m */; }; + 24E221DC21A28B23008ADF09 /* DualFlutterViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 24E221D121A28B22008ADF09 /* DualFlutterViewController.m */; }; + 24E221DD21A28B23008ADF09 /* FullScreenViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 24E221D321A28B23008ADF09 /* FullScreenViewController.m */; }; + 24E221DE21A28B23008ADF09 /* MainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 24E221D421A28B23008ADF09 /* MainViewController.m */; }; + 24E221DF21A28B23008ADF09 /* NativeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 24E221D621A28B23008ADF09 /* NativeViewController.m */; }; + 24E221E021A28B23008ADF09 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 24E221D721A28B23008ADF09 /* Launch Screen.storyboard */; }; + 24E221E221A28B36008ADF09 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 24E221E121A28B36008ADF09 /* Assets.xcassets */; }; + 24E7A1FE21A2AF26003A7FAD /* FlutterViewControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 24E7A1FD21A2AF26003A7FAD /* FlutterViewControllerTests.m */; }; + 8BDD73EC12DFA6CD2AC4EEDA /* EarlGrey.framework in EarlGrey Copy Files */ = {isa = PBXBuildFile; fileRef = DE1EF0F5719FBB45225A9EC3 /* EarlGrey.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; + AE3B0A0EAE765C1EC16866BF /* libPods-ios_add2appTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 699900B7FF01268E98EC69ED /* libPods-ios_add2appTests.a */; }; + DB9A200AFEB7AAE22B4E12E4 /* libPods-ios_add2app.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A318514E0307AE0FF0EFC76 /* libPods-ios_add2app.a */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 24D2933A21A29628008787A5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 24E221AD21A28A0B008ADF09 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 24E221B421A28A0B008ADF09; + remoteInfo = ios_add2app; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + C155689B0EB46CB1FF251109 /* EarlGrey Copy Files */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "$(TEST_HOST)/../"; + dstSubfolderSpec = 0; + files = ( + 8BDD73EC12DFA6CD2AC4EEDA /* EarlGrey.framework in EarlGrey Copy Files */, + ); + name = "EarlGrey Copy Files"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 16D27B9BE77DC8804292A9A9 /* Pods-ios_add2appUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios_add2appUITests.release.xcconfig"; path = "Pods/Target Support Files/Pods-ios_add2appUITests/Pods-ios_add2appUITests.release.xcconfig"; sourceTree = ""; }; + 24D2933521A29627008787A5 /* ios_add2appTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ios_add2appTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 24D2933721A29628008787A5 /* IntegrationTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IntegrationTests.m; sourceTree = ""; }; + 24D2933921A29628008787A5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 24E221B521A28A0B008ADF09 /* ios_add2app.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ios_add2app.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 24E221B821A28A0B008ADF09 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 24E221B921A28A0B008ADF09 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 24E221C621A28A0C008ADF09 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 24E221C721A28A0C008ADF09 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 24E221CF21A28B22008ADF09 /* FullScreenViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FullScreenViewController.h; sourceTree = ""; }; + 24E221D021A28B22008ADF09 /* HybridViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HybridViewController.m; sourceTree = ""; }; + 24E221D121A28B22008ADF09 /* DualFlutterViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DualFlutterViewController.m; sourceTree = ""; }; + 24E221D221A28B23008ADF09 /* MainViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainViewController.h; sourceTree = ""; }; + 24E221D321A28B23008ADF09 /* FullScreenViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FullScreenViewController.m; sourceTree = ""; }; + 24E221D421A28B23008ADF09 /* MainViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainViewController.m; sourceTree = ""; }; + 24E221D521A28B23008ADF09 /* DualFlutterViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DualFlutterViewController.h; sourceTree = ""; }; + 24E221D621A28B23008ADF09 /* NativeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NativeViewController.m; sourceTree = ""; }; + 24E221D721A28B23008ADF09 /* Launch Screen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = "Launch Screen.storyboard"; sourceTree = ""; }; + 24E221D821A28B23008ADF09 /* HybridViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HybridViewController.h; sourceTree = ""; }; + 24E221D921A28B23008ADF09 /* NativeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeViewController.h; sourceTree = ""; }; + 24E221E121A28B36008ADF09 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 24E7A1FD21A2AF26003A7FAD /* FlutterViewControllerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FlutterViewControllerTests.m; sourceTree = ""; }; + 36DA6BEAA5127D74EC6E3E13 /* Pods-ios_add2appUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios_add2appUITests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ios_add2appUITests/Pods-ios_add2appUITests.debug.xcconfig"; sourceTree = ""; }; + 52EA0B290EEBC1D28BF6E803 /* libPods-ios_add2appUITests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ios_add2appUITests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 699900B7FF01268E98EC69ED /* libPods-ios_add2appTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ios_add2appTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 74266A4D94FA1C3157B5B560 /* Pods-ios_add2appTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios_add2appTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests.debug.xcconfig"; sourceTree = ""; }; + 7A318514E0307AE0FF0EFC76 /* libPods-ios_add2app.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ios_add2app.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 83017A33946358F55BAE24E1 /* Pods-ios_add2appTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios_add2appTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests.release.xcconfig"; sourceTree = ""; }; + A18D4CDABD6795975FD6B49F /* Pods-ios_add2app.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios_add2app.release.xcconfig"; path = "Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app.release.xcconfig"; sourceTree = ""; }; + CCFA174387D083C931FB85D0 /* Pods-ios_add2app.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios_add2app.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app.debug.xcconfig"; sourceTree = ""; }; + DE1EF0F5719FBB45225A9EC3 /* EarlGrey.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = EarlGrey.framework; path = Pods/EarlGrey/EarlGrey/EarlGrey.framework; sourceTree = SOURCE_ROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 24D2933221A29627008787A5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 09C65652A2B48A21C94FF831 /* EarlGrey.framework in Frameworks */, + AE3B0A0EAE765C1EC16866BF /* libPods-ios_add2appTests.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 24E221B221A28A0B008ADF09 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + DB9A200AFEB7AAE22B4E12E4 /* libPods-ios_add2app.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 24D2933621A29628008787A5 /* ios_add2appTests */ = { + isa = PBXGroup; + children = ( + 24D2933721A29628008787A5 /* IntegrationTests.m */, + 24E7A1FD21A2AF26003A7FAD /* FlutterViewControllerTests.m */, + 24D2933921A29628008787A5 /* Info.plist */, + ); + path = ios_add2appTests; + sourceTree = ""; + }; + 24E221AC21A28A0B008ADF09 = { + isa = PBXGroup; + children = ( + 24E221B721A28A0B008ADF09 /* ios_add2app */, + 24D2933621A29628008787A5 /* ios_add2appTests */, + 24E221B621A28A0B008ADF09 /* Products */, + F8E51775C9B1473BB9A1386D /* Pods */, + 8403FDDD872DC11EF3710BB4 /* Frameworks */, + ); + sourceTree = ""; + }; + 24E221B621A28A0B008ADF09 /* Products */ = { + isa = PBXGroup; + children = ( + 24E221B521A28A0B008ADF09 /* ios_add2app.app */, + 24D2933521A29627008787A5 /* ios_add2appTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 24E221B721A28A0B008ADF09 /* ios_add2app */ = { + isa = PBXGroup; + children = ( + 24E221E121A28B36008ADF09 /* Assets.xcassets */, + 24E221D521A28B23008ADF09 /* DualFlutterViewController.h */, + 24E221D121A28B22008ADF09 /* DualFlutterViewController.m */, + 24E221CF21A28B22008ADF09 /* FullScreenViewController.h */, + 24E221D321A28B23008ADF09 /* FullScreenViewController.m */, + 24E221D821A28B23008ADF09 /* HybridViewController.h */, + 24E221D021A28B22008ADF09 /* HybridViewController.m */, + 24E221D721A28B23008ADF09 /* Launch Screen.storyboard */, + 24E221D221A28B23008ADF09 /* MainViewController.h */, + 24E221D421A28B23008ADF09 /* MainViewController.m */, + 24E221D921A28B23008ADF09 /* NativeViewController.h */, + 24E221D621A28B23008ADF09 /* NativeViewController.m */, + 24E221B821A28A0B008ADF09 /* AppDelegate.h */, + 24E221B921A28A0B008ADF09 /* AppDelegate.m */, + 24E221C621A28A0C008ADF09 /* Info.plist */, + 24E221C721A28A0C008ADF09 /* main.m */, + ); + path = ios_add2app; + sourceTree = ""; + }; + 8403FDDD872DC11EF3710BB4 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 7A318514E0307AE0FF0EFC76 /* libPods-ios_add2app.a */, + DE1EF0F5719FBB45225A9EC3 /* EarlGrey.framework */, + 52EA0B290EEBC1D28BF6E803 /* libPods-ios_add2appUITests.a */, + 699900B7FF01268E98EC69ED /* libPods-ios_add2appTests.a */, + ); + name = Frameworks; + sourceTree = ""; + }; + F8E51775C9B1473BB9A1386D /* Pods */ = { + isa = PBXGroup; + children = ( + CCFA174387D083C931FB85D0 /* Pods-ios_add2app.debug.xcconfig */, + A18D4CDABD6795975FD6B49F /* Pods-ios_add2app.release.xcconfig */, + 36DA6BEAA5127D74EC6E3E13 /* Pods-ios_add2appUITests.debug.xcconfig */, + 16D27B9BE77DC8804292A9A9 /* Pods-ios_add2appUITests.release.xcconfig */, + 74266A4D94FA1C3157B5B560 /* Pods-ios_add2appTests.debug.xcconfig */, + 83017A33946358F55BAE24E1 /* Pods-ios_add2appTests.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 24D2933421A29627008787A5 /* ios_add2appTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 24D2933C21A29628008787A5 /* Build configuration list for PBXNativeTarget "ios_add2appTests" */; + buildPhases = ( + DE5CDCD8B3565EAB9F38F455 /* [CP] Check Pods Manifest.lock */, + 24D2933121A29627008787A5 /* Sources */, + 24D2933221A29627008787A5 /* Frameworks */, + 24D2933321A29627008787A5 /* Resources */, + C155689B0EB46CB1FF251109 /* EarlGrey Copy Files */, + E32E699BE7026038F5987095 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 24D2933B21A29628008787A5 /* PBXTargetDependency */, + ); + name = ios_add2appTests; + productName = ios_add2appTests; + productReference = 24D2933521A29627008787A5 /* ios_add2appTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 24E221B421A28A0B008ADF09 /* ios_add2app */ = { + isa = PBXNativeTarget; + buildConfigurationList = 24E221CB21A28A0C008ADF09 /* Build configuration list for PBXNativeTarget "ios_add2app" */; + buildPhases = ( + 4375EE880A727341E9C9A57D /* [CP] Check Pods Manifest.lock */, + 24E221E321A28B53008ADF09 /* ShellScript */, + 24E221B121A28A0B008ADF09 /* Sources */, + 24E221B221A28A0B008ADF09 /* Frameworks */, + 24E221B321A28A0B008ADF09 /* Resources */, + 7FADF19EC61F97E525982780 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ios_add2app; + productName = ios_add2app; + productReference = 24E221B521A28A0B008ADF09 /* ios_add2app.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 24E221AD21A28A0B008ADF09 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1000; + ORGANIZATIONNAME = Flutter.io; + TargetAttributes = { + 24D2933421A29627008787A5 = { + CreatedOnToolsVersion = 10.0; + TestTargetID = 24E221B421A28A0B008ADF09; + }; + 24E221B421A28A0B008ADF09 = { + CreatedOnToolsVersion = 10.0; + }; + }; + }; + buildConfigurationList = 24E221B021A28A0B008ADF09 /* Build configuration list for PBXProject "ios_add2app" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 24E221AC21A28A0B008ADF09; + productRefGroup = 24E221B621A28A0B008ADF09 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 24E221B421A28A0B008ADF09 /* ios_add2app */, + 24D2933421A29627008787A5 /* ios_add2appTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 24D2933321A29627008787A5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 24E221B321A28A0B008ADF09 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 24E221E021A28B23008ADF09 /* Launch Screen.storyboard in Resources */, + 24E221E221A28B36008ADF09 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 24E221E321A28B53008ADF09 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n\"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed\n"; + }; + 4375EE880A727341E9C9A57D /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-ios_add2app-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 7FADF19EC61F97E525982780 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app-frameworks.sh", + "${PODS_ROOT}/../flutterapp/.ios/Flutter/engine/Flutter.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + ); + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + DE5CDCD8B3565EAB9F38F455 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-ios_add2appTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + E32E699BE7026038F5987095 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests-frameworks.sh", + "${PODS_ROOT}/../flutterapp/.ios/Flutter/engine/Flutter.framework", + "${PODS_ROOT}/EarlGrey/EarlGrey/EarlGrey.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + ); + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/EarlGrey.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 24D2933121A29627008787A5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 24E7A1FE21A2AF26003A7FAD /* FlutterViewControllerTests.m in Sources */, + 24D2933821A29628008787A5 /* IntegrationTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 24E221B121A28A0B008ADF09 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 24E221C821A28A0C008ADF09 /* main.m in Sources */, + 24E221DE21A28B23008ADF09 /* MainViewController.m in Sources */, + 24E221DD21A28B23008ADF09 /* FullScreenViewController.m in Sources */, + 24E221DC21A28B23008ADF09 /* DualFlutterViewController.m in Sources */, + 24E221DB21A28B23008ADF09 /* HybridViewController.m in Sources */, + 24E221DF21A28B23008ADF09 /* NativeViewController.m in Sources */, + 24E221BA21A28A0B008ADF09 /* AppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 24D2933B21A29628008787A5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 24E221B421A28A0B008ADF09 /* ios_add2app */; + targetProxy = 24D2933A21A29628008787A5 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 24D2933D21A29628008787A5 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 74266A4D94FA1C3157B5B560 /* Pods-ios_add2appTests.debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = S8QB4VV633; + INFOPLIST_FILE = ios_add2appTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "org.test.ios-add2appTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ios_add2app.app/ios_add2app"; + }; + name = Debug; + }; + 24D2933E21A29628008787A5 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 83017A33946358F55BAE24E1 /* Pods-ios_add2appTests.release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = S8QB4VV633; + INFOPLIST_FILE = ios_add2appTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "org.test.ios-add2appTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ios_add2app.app/ios_add2app"; + }; + name = Release; + }; + 24E221C921A28A0C008ADF09 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_BITCODE = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 24E221CA21A28A0C008ADF09 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_BITCODE = NO; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 24E221CC21A28A0C008ADF09 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = CCFA174387D083C931FB85D0 /* Pods-ios_add2app.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = S8QB4VV633; + INFOPLIST_FILE = ios_add2app/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "org.test.ios-add2app"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 24E221CD21A28A0C008ADF09 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A18D4CDABD6795975FD6B49F /* Pods-ios_add2app.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = S8QB4VV633; + INFOPLIST_FILE = ios_add2app/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "org.test.ios-add2app"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 24D2933C21A29628008787A5 /* Build configuration list for PBXNativeTarget "ios_add2appTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 24D2933D21A29628008787A5 /* Debug */, + 24D2933E21A29628008787A5 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 24E221B021A28A0B008ADF09 /* Build configuration list for PBXProject "ios_add2app" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 24E221C921A28A0C008ADF09 /* Debug */, + 24E221CA21A28A0C008ADF09 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 24E221CB21A28A0C008ADF09 /* Build configuration list for PBXNativeTarget "ios_add2app" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 24E221CC21A28A0C008ADF09 /* Debug */, + 24E221CD21A28A0C008ADF09 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 24E221AD21A28A0B008ADF09 /* Project object */; +} diff --git a/dev/integration_tests/ios_add2app/ios_add2app.xcodeproj/xcshareddata/xcschemes/ios_add2appTests.xcscheme b/dev/integration_tests/ios_add2app/ios_add2app.xcodeproj/xcshareddata/xcschemes/ios_add2appTests.xcscheme new file mode 100644 index 0000000000..faa80f9f85 --- /dev/null +++ b/dev/integration_tests/ios_add2app/ios_add2app.xcodeproj/xcshareddata/xcschemes/ios_add2appTests.xcscheme @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/integration_tests/ios_add2app/ios_add2app.xcworkspace/contents.xcworkspacedata b/dev/integration_tests/ios_add2app/ios_add2app.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000..a22b612a0c --- /dev/null +++ b/dev/integration_tests/ios_add2app/ios_add2app.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/dev/integration_tests/ios_add2app/ios_add2app.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/dev/integration_tests/ios_add2app/ios_add2app.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000000..18d981003d --- /dev/null +++ b/dev/integration_tests/ios_add2app/ios_add2app.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/dev/integration_tests/ios_add2app/ios_add2app/AppDelegate.h b/dev/integration_tests/ios_add2app/ios_add2app/AppDelegate.h new file mode 100644 index 0000000000..816e424a55 --- /dev/null +++ b/dev/integration_tests/ios_add2app/ios_add2app/AppDelegate.h @@ -0,0 +1,14 @@ +// Copyright 2018 The Flutter 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 +#import + +@interface AppDelegate : FlutterAppDelegate + +@property(nonatomic, strong) FlutterEngine* engine; +@property(nonatomic, strong) UIWindow* window; +@property(nonatomic, strong) FlutterBasicMessageChannel* reloadMessageChannel; + +@end diff --git a/dev/integration_tests/ios_add2app/ios_add2app/AppDelegate.m b/dev/integration_tests/ios_add2app/ios_add2app/AppDelegate.m new file mode 100644 index 0000000000..b69c346846 --- /dev/null +++ b/dev/integration_tests/ios_add2app/ios_add2app/AppDelegate.m @@ -0,0 +1,53 @@ +// Copyright 2018 The Flutter 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 "AppDelegate.h" +#import "MainViewController.h" + +@interface AppDelegate () + +@end + +static NSString *_kReloadChannelName = @"reload"; + +@implementation AppDelegate { + MainViewController *_mainViewController; + UINavigationController *_navigationController; + FlutterEngine *_engine; + FlutterBasicMessageChannel *_reloadMessageChannel; +} + +- (FlutterEngine *)engine { + return _engine; +} + +- (FlutterBasicMessageChannel *)reloadMessabeChannel { + return _reloadMessageChannel; +} + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + + _mainViewController = [[MainViewController alloc] init]; + _navigationController = [[UINavigationController alloc] + initWithRootViewController:_mainViewController]; + + _navigationController.navigationBar.translucent = NO; + + _engine = [[FlutterEngine alloc] initWithName:@"test" project:nil]; + [_engine runWithEntrypoint:nil]; + + _reloadMessageChannel = [[FlutterBasicMessageChannel alloc] + initWithName:_kReloadChannelName + binaryMessenger:_engine + codec:[FlutterStringCodec sharedInstance]]; + + self.window.rootViewController = _navigationController; + [self.window makeKeyAndVisible]; + + return YES; +} + +@end diff --git a/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Contents.json b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000000..d36b1fab2d --- /dev/null +++ b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000000..3d43d11e66 Binary files /dev/null and b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000000..28c6bf0301 Binary files /dev/null and b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000000..2ccbfd967d Binary files /dev/null and b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000000..f091b6b0bc Binary files /dev/null and b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000000..4cde12118d Binary files /dev/null and b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000000..d0ef06e7ed Binary files /dev/null and b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000000..dcdc2306c2 Binary files /dev/null and b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000000..2ccbfd967d Binary files /dev/null and b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000000..c8f9ed8f5c Binary files /dev/null and b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000000..a6d6b8609d Binary files /dev/null and b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000000..a6d6b8609d Binary files /dev/null and b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000000..75b2d164a5 Binary files /dev/null and b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000000..c4df70d39d Binary files /dev/null and b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000000..6a84f41e14 Binary files /dev/null and b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000000..d0e1f58536 Binary files /dev/null and b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/Contents.json b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/Contents.json new file mode 100644 index 0000000000..da4a164c91 --- /dev/null +++ b/dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/dev/integration_tests/ios_add2app/ios_add2app/DualFlutterViewController.h b/dev/integration_tests/ios_add2app/ios_add2app/DualFlutterViewController.h new file mode 100644 index 0000000000..db75303f40 --- /dev/null +++ b/dev/integration_tests/ios_add2app/ios_add2app/DualFlutterViewController.h @@ -0,0 +1,16 @@ +// Copyright 2018 The Flutter 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 + +NS_ASSUME_NONNULL_BEGIN + +@interface DualFlutterViewController : UIViewController + +@property (readonly, strong, nonatomic) FlutterViewController* topFlutterViewController; +@property (readonly, strong, nonatomic) FlutterViewController* bottomFlutterViewController; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/ios_add2app/DualFlutterViewController.m b/dev/integration_tests/ios_add2app/ios_add2app/DualFlutterViewController.m new file mode 100644 index 0000000000..0d2d559a5d --- /dev/null +++ b/dev/integration_tests/ios_add2app/ios_add2app/DualFlutterViewController.m @@ -0,0 +1,40 @@ +// Copyright 2018 The Flutter 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 + +#import "DualFlutterViewController.h" + +@interface DualFlutterViewController () + +@end + +@implementation DualFlutterViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + self.title = @"Dual Flutter Views"; + + UIStackView* stackView = [[UIStackView alloc] initWithFrame:self.view.frame]; + stackView.axis = UILayoutConstraintAxisVertical; + stackView.distribution = UIStackViewDistributionFillEqually; + stackView.layoutMargins = UIEdgeInsetsMake(0, 0, 50, 0); + stackView.layoutMarginsRelativeArrangement = YES; + [self.view addSubview:stackView]; + + _topFlutterViewController = [[FlutterViewController alloc] init]; + _bottomFlutterViewController= [[FlutterViewController alloc] init]; + + [_topFlutterViewController setInitialRoute:@"marquee_green"]; + [self addChildViewController:_topFlutterViewController]; + [stackView addArrangedSubview:_topFlutterViewController.view]; + [_topFlutterViewController didMoveToParentViewController:self]; + + [_bottomFlutterViewController setInitialRoute:@"marquee_purple"]; + [self addChildViewController:_bottomFlutterViewController]; + [stackView addArrangedSubview:_bottomFlutterViewController.view]; + [_bottomFlutterViewController didMoveToParentViewController:self]; +} + +@end diff --git a/dev/integration_tests/ios_add2app/ios_add2app/FullScreenViewController.h b/dev/integration_tests/ios_add2app/ios_add2app/FullScreenViewController.h new file mode 100644 index 0000000000..f2a79aa36b --- /dev/null +++ b/dev/integration_tests/ios_add2app/ios_add2app/FullScreenViewController.h @@ -0,0 +1,13 @@ +// Copyright 2018 The Flutter 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 + +NS_ASSUME_NONNULL_BEGIN + +@interface FullScreenViewController : FlutterViewController + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/ios_add2app/FullScreenViewController.m b/dev/integration_tests/ios_add2app/ios_add2app/FullScreenViewController.m new file mode 100644 index 0000000000..ce612cf354 --- /dev/null +++ b/dev/integration_tests/ios_add2app/ios_add2app/FullScreenViewController.m @@ -0,0 +1,39 @@ +// Copyright 2018 The Flutter 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 "FullScreenViewController.h" + +@interface FullScreenViewController () + +@end + +@implementation FullScreenViewController + +-(void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + self.title = @"Full Screen Flutter"; + self.navigationController.navigationBarHidden = YES; + self.navigationController.hidesBarsOnSwipe = YES; +} + +-(void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + self.navigationController.navigationBarHidden = NO; + self.navigationController.hidesBarsOnSwipe = NO; + if (self.isMovingFromParentViewController) { + // Note that if we were doing things that might cause the VC + // to disappear (like using the image_picker plugin) + // we shouldn't do this. But in this case we know we're + // just going back to the navigation controller. + // If we needed Flutter to tell us when we could actually go away, + // we'd need to communicate over a method channel with it. + [self.engine setViewController:nil]; + } +} + +-(BOOL)prefersStatusBarHidden { + return true; +} + +@end diff --git a/dev/integration_tests/ios_add2app/ios_add2app/HybridViewController.h b/dev/integration_tests/ios_add2app/ios_add2app/HybridViewController.h new file mode 100644 index 0000000000..71bf48db16 --- /dev/null +++ b/dev/integration_tests/ios_add2app/ios_add2app/HybridViewController.h @@ -0,0 +1,17 @@ +// Copyright 2018 The Flutter 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 + +#import "NativeViewController.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface HybridViewController : UIViewController + +@property (readonly, strong, nonatomic) FlutterViewController* flutterViewController; + +@end + +NS_ASSUME_NONNULL_END diff --git a/dev/integration_tests/ios_add2app/ios_add2app/HybridViewController.m b/dev/integration_tests/ios_add2app/ios_add2app/HybridViewController.m new file mode 100644 index 0000000000..7dc85f726a --- /dev/null +++ b/dev/integration_tests/ios_add2app/ios_add2app/HybridViewController.m @@ -0,0 +1,71 @@ +// Copyright 2018 The Flutter 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 + +#import "AppDelegate.h" +#import "HybridViewController.h" + +@interface HybridViewController () + +@end + +static NSString *_kChannel = @"increment"; +static NSString *_kPing = @"ping"; + +@implementation HybridViewController { + FlutterBasicMessageChannel *_messageChannel; +} + +- (FlutterEngine *)engine { + return [(AppDelegate *)[[UIApplication sharedApplication] delegate] engine]; +} + +- (FlutterBasicMessageChannel *)reloadMessageChannel { + return [(AppDelegate *)[[UIApplication sharedApplication] delegate] + reloadMessageChannel]; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + self.title = @"Hybrid Flutter/Native"; + UIStackView *stackView = [[UIStackView alloc] initWithFrame:self.view.frame]; + stackView.axis = UILayoutConstraintAxisVertical; + stackView.distribution = UIStackViewDistributionFillEqually; + stackView.layoutMargins = UIEdgeInsetsMake(0, 0, 50, 0); + stackView.layoutMarginsRelativeArrangement = YES; + [self.view addSubview:stackView]; + + NativeViewController *nativeViewController = + [[NativeViewController alloc] initWithDelegate:self]; + [self addChildViewController:nativeViewController]; + [stackView addArrangedSubview:nativeViewController.view]; + [nativeViewController didMoveToParentViewController:self]; + + _flutterViewController = + [[FlutterViewController alloc] initWithEngine:[self engine] + nibName:nil + bundle:nil]; + [[self reloadMessageChannel] sendMessage:@"hybrid"]; + + _messageChannel = [[FlutterBasicMessageChannel alloc] + initWithName:_kChannel + binaryMessenger:_flutterViewController + codec:[FlutterStringCodec sharedInstance]]; + [self addChildViewController:_flutterViewController]; + [stackView addArrangedSubview:_flutterViewController.view]; + [_flutterViewController didMoveToParentViewController:self]; + + __weak NativeViewController *weakNativeViewController = nativeViewController; + [_messageChannel setMessageHandler:^(id message, FlutterReply reply) { + [weakNativeViewController didReceiveIncrement]; + reply(@""); + }]; +} + +- (void)didTapIncrementButton { + [_messageChannel sendMessage:_kPing]; +} + +@end diff --git a/dev/integration_tests/ios_add2app/ios_add2app/Info.plist b/dev/integration_tests/ios_add2app/ios_add2app/Info.plist new file mode 100644 index 0000000000..08cae2a8dc --- /dev/null +++ b/dev/integration_tests/ios_add2app/ios_add2app/Info.plist @@ -0,0 +1,43 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + Launch Screen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/dev/integration_tests/ios_add2app/ios_add2app/Launch Screen.storyboard b/dev/integration_tests/ios_add2app/ios_add2app/Launch Screen.storyboard new file mode 100644 index 0000000000..6a6b1b8249 --- /dev/null +++ b/dev/integration_tests/ios_add2app/ios_add2app/Launch Screen.storyboard @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/integration_tests/ios_add2app/ios_add2app/MainViewController.h b/dev/integration_tests/ios_add2app/ios_add2app/MainViewController.h new file mode 100644 index 0000000000..70ace15225 --- /dev/null +++ b/dev/integration_tests/ios_add2app/ios_add2app/MainViewController.h @@ -0,0 +1,10 @@ +// Copyright 2018 The Flutter 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 +#import + +@interface MainViewController : UIViewController + +@end diff --git a/dev/integration_tests/ios_add2app/ios_add2app/MainViewController.m b/dev/integration_tests/ios_add2app/ios_add2app/MainViewController.m new file mode 100644 index 0000000000..23c6e35f4a --- /dev/null +++ b/dev/integration_tests/ios_add2app/ios_add2app/MainViewController.m @@ -0,0 +1,124 @@ +// Copyright 2018 The Flutter 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 "MainViewController.h" + +#import "AppDelegate.h" +#import "DualFlutterViewController.h" +#import "FullScreenViewController.h" +#import "HybridViewController.h" +#import "NativeViewController.h" + +@interface MainViewController () + +@end + + +@implementation MainViewController { + UIStackView *_stackView; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + + [self.view setFrame:self.view.window.bounds]; + self.title = @"Flutter iOS Demos"; + self.view.backgroundColor = UIColor.whiteColor; + + _stackView = [[UIStackView alloc] initWithFrame:self.view.frame]; + _stackView.axis = UILayoutConstraintAxisVertical; + _stackView.distribution = UIStackViewDistributionEqualSpacing; + _stackView.alignment = UIStackViewAlignmentCenter; + _stackView.autoresizingMask = + UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + _stackView.layoutMargins = UIEdgeInsetsMake(0, 0, 50, 0); + _stackView.layoutMarginsRelativeArrangement = YES; + [self.view addSubview:_stackView]; + + [self addButton:@"Native iOS View" action:@selector(showNative)]; + [self addButton:@"Full Screen (Cold)" action:@selector(showFullScreenCold)]; + [self addButton:@"Full Screen (Warm)" action:@selector(showFullScreenWarm)]; + [self addButton:@"Flutter View (Warm)" action:@selector(showFlutterViewWarm)]; + [self addButton:@"Hybrid View (Warm)" action:@selector(showHybridView)]; + [self addButton:@"Dual Flutter View (Cold)" action:@selector(showDualView)]; +} + +- (FlutterEngine *)engine { + return [(AppDelegate *)[[UIApplication sharedApplication] delegate] engine]; +} + +- (FlutterBasicMessageChannel*)reloadMessageChannel { + return [(AppDelegate *)[[UIApplication sharedApplication] delegate] reloadMessageChannel]; +} + +- (void)showDualView { + DualFlutterViewController *dualViewController = + [[DualFlutterViewController alloc] init]; + [self.navigationController pushViewController:dualViewController + animated:YES]; +} + +- (void)showHybridView { + HybridViewController *hybridViewController = + [[HybridViewController alloc] init]; + [self.navigationController pushViewController:hybridViewController + animated:YES]; +} +- (void)showNative { + NativeViewController *nativeViewController = + [[NativeViewController alloc] init]; + [self.navigationController pushViewController:nativeViewController + animated:YES]; +} + +- (void)showFullScreenCold { + FullScreenViewController *flutterViewController = + [[FullScreenViewController alloc] init]; + [flutterViewController setInitialRoute:@"full"]; + [[self reloadMessageChannel] sendMessage:@"full"]; + [self.navigationController + pushViewController:flutterViewController + animated:NO]; // Animating this is janky because of + // transitions with header on the native side. + // It's especially bad with a cold engine. +} + +- (void)showFullScreenWarm { + [[self engine].navigationChannel invokeMethod:@"setInitialRoute" + arguments:@"full"]; + [[self reloadMessageChannel] sendMessage:@"full"]; + + FullScreenViewController *flutterViewController = + [[FullScreenViewController alloc] initWithEngine:[self engine] + nibName:nil + bundle:nil]; + [self.navigationController + pushViewController:flutterViewController + animated:NO]; // Animating this is problematic. +} + +- (void)showFlutterViewWarm { + [[self engine].navigationChannel invokeMethod:@"setInitialRoute" + arguments:@"/"]; + [[self reloadMessageChannel] sendMessage:@"/"]; + + + FlutterViewController *flutterViewController = + [[FlutterViewController alloc] initWithEngine:[self engine] + nibName:nil + bundle:nil]; + [self.navigationController pushViewController:flutterViewController + animated:YES]; +} + +- (void)addButton:(NSString *)title action:(SEL)action { + UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem]; + [button setTitle:title forState:UIControlStateNormal]; + [button addTarget:self + action:action + forControlEvents:UIControlEventTouchUpInside]; + [_stackView addArrangedSubview:button]; +} + +@end diff --git a/dev/integration_tests/ios_add2app/ios_add2app/NativeViewController.h b/dev/integration_tests/ios_add2app/ios_add2app/NativeViewController.h new file mode 100644 index 0000000000..e30f60ba53 --- /dev/null +++ b/dev/integration_tests/ios_add2app/ios_add2app/NativeViewController.h @@ -0,0 +1,22 @@ +// Copyright 2018 The Flutter 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 + +@protocol NativeViewControllerDelegate +/// Triggered when the increment button from the NativeViewController is tapped. +-(void)didTapIncrementButton; + +@end + +@interface NativeViewController : UIViewController + +- (instancetype)initWithDelegate:(id)delegate + NS_DESIGNATED_INITIALIZER; + +@property(nonatomic, weak) id delegate; + +-(void)didReceiveIncrement; + +@end diff --git a/dev/integration_tests/ios_add2app/ios_add2app/NativeViewController.m b/dev/integration_tests/ios_add2app/ios_add2app/NativeViewController.m new file mode 100644 index 0000000000..c585677aa4 --- /dev/null +++ b/dev/integration_tests/ios_add2app/ios_add2app/NativeViewController.m @@ -0,0 +1,139 @@ +// Copyright 2018 The Flutter 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 "NativeViewController.h" + +@interface NativeViewController () + +@end + +@implementation NativeViewController { + int _counter; + UILabel* _incrementLabel; +} + +- (instancetype)initWithDelegate:(id)delegate { + self = [super initWithNibName:nil bundle:nil]; + if (self) { + self.delegate = delegate; + } + return self; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + return [self initWithDelegate:nil]; +} + +-(instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { + return [self initWithDelegate:nil]; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + + self.title = @"Native iOS View"; + self.view.backgroundColor = UIColor.lightGrayColor; + + _incrementLabel = [self addIncrementLabel]; + UIStackView* footer = [self addFooter]; + + _incrementLabel.translatesAutoresizingMaskIntoConstraints = false; + footer.translatesAutoresizingMaskIntoConstraints = false; + UILayoutGuide* marginsGuide = self.view.layoutMarginsGuide; + NSMutableArray* array = [[NSMutableArray alloc] init]; + [array addObject:[_incrementLabel.centerXAnchor + constraintEqualToAnchor:self.view.centerXAnchor]]; + [array addObject:[_incrementLabel.centerYAnchor + constraintEqualToAnchor:self.view.centerYAnchor]]; + [array addObject:[footer.centerXAnchor + constraintEqualToAnchor:self.view.centerXAnchor]]; + [array addObject:[footer.widthAnchor + constraintEqualToAnchor:marginsGuide.widthAnchor]]; + [array addObject:[footer.bottomAnchor + constraintEqualToAnchor:marginsGuide.bottomAnchor]]; + + [NSLayoutConstraint activateConstraints:array]; + [self updateIncrementLabel]; +} + +/// Adds a label to the view that will contain the counter text. +/// +/// - Returns: The new label. +-(UILabel*) addIncrementLabel { + UILabel* incrementLabel = [[UILabel alloc] init]; + incrementLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody]; + incrementLabel.textColor = UIColor.blackColor; + incrementLabel.accessibilityIdentifier = @"counter_on_iOS"; + [self.view addSubview:incrementLabel]; + return incrementLabel; +} + +/// Adds a horizontal stack to the view, anchored to the bottom. +/// +/// - Returns: The new stack. +-(UIStackView*) addFooter { + UILabel* mainLabel = [self createMainLabel]; + UIButton* incrementButton = [self createIncrementButton]; + UIStackView* stackView = [[UIStackView alloc] initWithFrame:self.view.frame]; + [stackView addArrangedSubview:mainLabel]; + [stackView addArrangedSubview:incrementButton]; + stackView.axis = UILayoutConstraintAxisHorizontal; + stackView.alignment = UIStackViewAlignmentBottom; + [self.view addSubview:stackView]; + return stackView; +} + +/// Creates a label identifying this view. Does not add it to the view. +/// +/// - Returns: The new label. +-(UILabel*) createMainLabel { + UILabel* mainLabel = [[UILabel alloc] init]; + mainLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleTitle1]; + mainLabel.textColor = UIColor.blackColor; + mainLabel.text = @"Native"; + return mainLabel; +} + +/// Creates a button that will increment a counter. Does not add it to the view. +/// +/// - Returns: The new button. +-(UIButton*) createIncrementButton { + UIButton *incrementButton = [UIButton buttonWithType:UIButtonTypeSystem]; + incrementButton.titleLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleTitle2]; + [incrementButton setTitle:@"Add" forState:UIControlStateNormal]; + incrementButton.accessibilityLabel = @"Increment via iOS"; + incrementButton.layer.cornerRadius = 15.0; + [incrementButton addTarget:self + action:@selector(handleIncrement:) + forControlEvents:UIControlEventTouchUpInside]; + return incrementButton; +} + +// MARK: - Actions + +/// Action triggered from tapping on the increment button. Triggers a corresponding event in the +/// delegate if one is available, otherwise increments our internal counter. +-(void) handleIncrement:(UIButton*)sender { + if (self.delegate) { + [self.delegate didTapIncrementButton]; + } else { + [self didReceiveIncrement]; + } +} + +/// Updates the increment label text to match the increment counter. +-(void) updateIncrementLabel { + _incrementLabel.text = [NSString + stringWithFormat:@"%@ tapped %d %@.", + self.delegate == nil ? @"Button" : @"Flutter button", + _counter, _counter == 1 ? @"time" : @"times"]; +} + +/// Increments our internal counter and updates the view. +-(void) didReceiveIncrement { + _counter += 1; + [self updateIncrementLabel]; +} + +@end diff --git a/dev/integration_tests/ios_add2app/ios_add2app/main.m b/dev/integration_tests/ios_add2app/ios_add2app/main.m new file mode 100644 index 0000000000..01f25d2dee --- /dev/null +++ b/dev/integration_tests/ios_add2app/ios_add2app/main.m @@ -0,0 +1,12 @@ +// Copyright 2018 The Flutter 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 +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/dev/integration_tests/ios_add2app/ios_add2appTests/FlutterViewControllerTests.m b/dev/integration_tests/ios_add2app/ios_add2appTests/FlutterViewControllerTests.m new file mode 100644 index 0000000000..6aee224d0f --- /dev/null +++ b/dev/integration_tests/ios_add2app/ios_add2appTests/FlutterViewControllerTests.m @@ -0,0 +1,27 @@ +// Copyright 2018 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// TODO(dnfield): This belongs in the engine repo. +#import +#import + +@interface ViewControllerRelease : XCTestCase +@end + + +@implementation ViewControllerRelease + +- (void)testReleaseFlutterViewController { + __weak FlutterEngine* weakEngine; + @autoreleasepool { + FlutterViewController* viewController = [[FlutterViewController alloc] + init]; + weakEngine = viewController.engine; + [viewController viewWillAppear:NO]; + [viewController viewDidDisappear:NO]; + } + XCTAssertNil(weakEngine); +} + +@end diff --git a/dev/integration_tests/ios_add2app/ios_add2appTests/Info.plist b/dev/integration_tests/ios_add2app/ios_add2appTests/Info.plist new file mode 100644 index 0000000000..6c40a6cd0c --- /dev/null +++ b/dev/integration_tests/ios_add2app/ios_add2appTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/dev/integration_tests/ios_add2app/ios_add2appTests/IntegrationTests.m b/dev/integration_tests/ios_add2app/ios_add2appTests/IntegrationTests.m new file mode 100644 index 0000000000..6c6b36ec5e --- /dev/null +++ b/dev/integration_tests/ios_add2app/ios_add2appTests/IntegrationTests.m @@ -0,0 +1,210 @@ +// Copyright 2018 The Flutter 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 +#import + +#import "../ios_add2app/AppDelegate.h" +#import "../ios_add2app/DualFlutterViewController.h" +#import "../ios_add2app/FullScreenViewController.h" +#import "../ios_add2app/MainViewController.h" +#import "../ios_add2app/HybridViewController.h" + +static void waitForFlutterSemanticsTree(FlutterViewController *viewController) { + int tries = 10; + double delay = 1.0; + + // ensureSemanticsEnabled is a synchronous call, but only ensures that the + // semantics tree will be built on a subsequent frame (as opposed to being + // available at time it returns). + // To actually get the tree, we have to wait for the FlutterSemanticsUpdate + // notification, which lets us know that a semantics tree has been built; + // but we cannot block the main thread while waiting (so we use + // CFRunLoopRunInMode). + + __block BOOL semanticsAvailable = NO; + __block id observer = [[NSNotificationCenter defaultCenter] + addObserverForName:@"FlutterSemanticsUpdate" + object:viewController + queue:nil + usingBlock:^(NSNotification *notification) { + semanticsAvailable = YES; + [[NSNotificationCenter defaultCenter] removeObserver:observer]; + }]; + [viewController.engine ensureSemanticsEnabled]; + while (semanticsAvailable == NO && tries != 0) { + CFRunLoopRunInMode(kCFRunLoopDefaultMode, delay, false); + tries--; + [viewController.engine ensureSemanticsEnabled]; + } + GREYAssertTrue(semanticsAvailable, @"Semantics Tree did not build!"); +} + +@interface FlutterTests : XCTestCase +@end + +@implementation FlutterTests { + int _flutterWarmEngineTaps; +} + +- (instancetype)init { + self = [super init]; + + if (self) { + _flutterWarmEngineTaps = 0; + } + + return self; +} + +- (void)testFullScreenCanPop { + [[EarlGrey selectElementWithMatcher:grey_keyWindow()] + assertWithMatcher:grey_sufficientlyVisible()]; + + [[EarlGrey selectElementWithMatcher:grey_buttonTitle(@"Full Screen (Cold)")] + performAction:grey_tap()]; + + __weak FlutterViewController *weakViewController; + @autoreleasepool { + UINavigationController *navController = + (UINavigationController *)((AppDelegate *) + [[UIApplication sharedApplication] + delegate]) + .window.rootViewController; + weakViewController = + (FullScreenViewController *)navController.visibleViewController; + waitForFlutterSemanticsTree(weakViewController); + GREYAssertNotNil(weakViewController, + @"Expected non-nil FullScreenViewController."); + } + + [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(@"POP")] + performAction:grey_tap()]; + // EarlGrey v1 isn't good at detecting this yet - 2.0 will be able to do it + int tries = 10; + double delay = 1.0; + while (weakViewController != nil && tries != 0) { + CFRunLoopRunInMode(kCFRunLoopDefaultMode, delay, false); + tries--; + } + [[EarlGrey selectElementWithMatcher:grey_buttonTitle(@"Native iOS View")] + assertWithMatcher:grey_sufficientlyVisible()]; + GREYAssertNil(weakViewController, + @"Expected FullScreenViewController to be deallocated."); +} + +- (void)testDualFlutterView { + [[EarlGrey selectElementWithMatcher:grey_keyWindow()] + assertWithMatcher:grey_sufficientlyVisible()]; + + [[EarlGrey + selectElementWithMatcher:grey_buttonTitle(@"Dual Flutter View (Cold)")] + performAction:grey_tap()]; + + @autoreleasepool { + UINavigationController *navController = + (UINavigationController *)((AppDelegate *) + [[UIApplication sharedApplication] + delegate]) + .window.rootViewController; + DualFlutterViewController *viewController = + (DualFlutterViewController *)navController.visibleViewController; + GREYAssertNotNil(viewController, + @"Expected non-nil DualFlutterViewController."); + waitForFlutterSemanticsTree(viewController.topFlutterViewController); + waitForFlutterSemanticsTree(viewController.bottomFlutterViewController); + } + + // Verify that there are two Flutter views with the expected marquee text. + [[[EarlGrey + selectElementWithMatcher:grey_accessibilityLabel(@"This is Marquee")] + atIndex:0] assertWithMatcher:grey_notNil()]; + [[[EarlGrey + selectElementWithMatcher:grey_accessibilityLabel(@"This is Marquee")] + atIndex:1] assertWithMatcher:grey_notNil()]; + + [[EarlGrey selectElementWithMatcher:grey_buttonTitle(@"Back")] + performAction:grey_tap()]; + + [[EarlGrey selectElementWithMatcher:grey_buttonTitle(@"Native iOS View")] + assertWithMatcher:grey_sufficientlyVisible()]; +} + +- (void)testHybridView { + [[EarlGrey selectElementWithMatcher:grey_keyWindow()] + assertWithMatcher:grey_sufficientlyVisible()]; + + [[EarlGrey selectElementWithMatcher:grey_buttonTitle(@"Hybrid View (Warm)")] + performAction:grey_tap()]; + + @autoreleasepool { + UINavigationController *navController = + (UINavigationController *)((AppDelegate *) + [[UIApplication sharedApplication] + delegate]) + .window.rootViewController; + HybridViewController *viewController = + (HybridViewController *)navController.visibleViewController; + GREYAssertNotNil(viewController.flutterViewController, + @"Expected non-nil FlutterViewController."); + waitForFlutterSemanticsTree(viewController.flutterViewController); + } + + [self validateCountsFlutter:@"Platform" count:0]; + [self validateCountsPlatform:@"Flutter" count:_flutterWarmEngineTaps]; + + static const int platformTapCount = 4; + static const int flutterTapCount = 6; + + for (int i = _flutterWarmEngineTaps; i < flutterTapCount; + i++, _flutterWarmEngineTaps++) { + [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel( + @"Increment via Flutter")] + performAction:grey_tap()]; + } + + [self validateCountsFlutter:@"Platform" count:0]; + [self validateCountsPlatform:@"Flutter" count:_flutterWarmEngineTaps]; + + for (int i = 0; i < platformTapCount; i++) { + [[EarlGrey + selectElementWithMatcher:grey_accessibilityLabel(@"Increment via iOS")] + performAction:grey_tap()]; + } + + [self validateCountsFlutter:@"Platform" count:platformTapCount]; + [self validateCountsPlatform:@"Flutter" count:_flutterWarmEngineTaps]; + + [[EarlGrey selectElementWithMatcher:grey_buttonTitle(@"Back")] + performAction:grey_tap()]; + [[EarlGrey selectElementWithMatcher:grey_buttonTitle(@"Native iOS View")] + assertWithMatcher:grey_sufficientlyVisible()]; +} + +/** Validates that the text labels showing the number of button taps match the + * expected counts. */ +- (void)validateCountsFlutter:(NSString *)labelPrefix count:(int)flutterCount { + NSString *flutterCountStr = + [NSString stringWithFormat:@"%@ button tapped %d times.", labelPrefix, + flutterCount]; + + // TODO(https://github.com/flutter/flutter/issues/17988): Flutter doesn't + // expose accessibility IDs, so the best we can do is to search for an element + // with the text we expect. + [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(flutterCountStr)] + assertWithMatcher:grey_sufficientlyVisible()]; +} + +- (void)validateCountsPlatform:(NSString *)labelPrefix + count:(int)platformCount { + NSString *platformCountStr = + [NSString stringWithFormat:@"%@ button tapped %d times.", labelPrefix, + platformCount]; + + [[[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"counter_on_iOS")] + assertWithMatcher:grey_text(platformCountStr)] + assertWithMatcher:grey_sufficientlyVisible()]; +} + +@end diff --git a/dev/integration_tests/platform_interaction/pubspec.yaml b/dev/integration_tests/platform_interaction/pubspec.yaml index 0802feed9f..bc7c1aaf57 100644 --- a/dev/integration_tests/platform_interaction/pubspec.yaml +++ b/dev/integration_tests/platform_interaction/pubspec.yaml @@ -12,7 +12,7 @@ dependencies: sdk: flutter test: 1.5.3 - analyzer: 0.35.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + analyzer: 0.35.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" args: 1.5.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" async: 2.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -22,9 +22,9 @@ dependencies: crypto: 2.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.14.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" file: 5.0.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - front_end: 0.1.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + front_end: 0.1.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" glob: 1.1.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - html: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + html: 0.13.4+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http: 0.12.0+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_multi_server: 2.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_parser: 3.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -32,7 +32,7 @@ dependencies: io: 0.3.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" js: 0.6.1+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" json_rpc_2: 2.0.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - kernel: 0.3.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + kernel: 0.3.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" logging: 0.11.3+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" matcher: 0.12.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -40,9 +40,9 @@ dependencies: multi_server_socket: 1.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" node_preamble: 1.4.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" package_config: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - package_resolver: 1.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + package_resolver: 1.0.10 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path: 1.6.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - pedantic: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + pedantic: 1.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" plugin: 0.2.0+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pool: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pub_semver: 1.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -52,7 +52,7 @@ dependencies: shelf_web_socket: 0.2.2+4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" source_map_stack_trace: 1.1.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" source_maps: 0.10.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - source_span: 1.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + source_span: 1.5.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 1.6.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" string_scanner: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -70,4 +70,4 @@ dependencies: flutter: uses-material-design: true -# PUBSPEC CHECKSUM: c26c +# PUBSPEC CHECKSUM: 2b9e diff --git a/dev/integration_tests/simple_codegen/build.yaml b/dev/integration_tests/simple_codegen/build.yaml new file mode 100644 index 0000000000..b5a63635eb --- /dev/null +++ b/dev/integration_tests/simple_codegen/build.yaml @@ -0,0 +1,8 @@ +# Read about `build.yaml` at https://pub.dartlang.org/packages/build_config +builders: + simple: + import: "package:simple_codegen/builders.dart" + builder_factories: + - simpleBuilder + build_extensions: {'.spec':['.dart']} + auto_apply: all_packages diff --git a/dev/integration_tests/simple_codegen/lib/builders.dart b/dev/integration_tests/simple_codegen/lib/builders.dart new file mode 100644 index 0000000000..0f2199aee1 --- /dev/null +++ b/dev/integration_tests/simple_codegen/lib/builders.dart @@ -0,0 +1,18 @@ +import 'package:build/build.dart'; + +/// The builder factory used by the `build.yaml` script. +Builder simpleBuilder(BuilderOptions options) => SimpleBuilder(); + +/// A trivial builder which copies the contents of a `spec` file into a `dart` file. +class SimpleBuilder extends Builder { + @override + Map> get buildExtensions => const >{'.spec' : ['.dart']}; + + + @override + Future build(BuildStep buildStep) async { + final AssetId output = buildStep.inputId.changeExtension('.dart'); + final String contents = await buildStep.readAsString(buildStep.inputId); + buildStep.writeAsString(output, contents); + } +} diff --git a/packages/flutter_build/pubspec.yaml b/dev/integration_tests/simple_codegen/pubspec.yaml similarity index 58% rename from packages/flutter_build/pubspec.yaml rename to dev/integration_tests/simple_codegen/pubspec.yaml index eb88dadab8..eccfd9ce8d 100644 --- a/packages/flutter_build/pubspec.yaml +++ b/dev/integration_tests/simple_codegen/pubspec.yaml @@ -1,44 +1,28 @@ -name: flutter_build - -environment: - # The pub client defaults to an <2.0.0 sdk constraint which we need to explicitly overwrite. - sdk: ">=2.0.0-dev.68.0 <3.0.0" +name: simple_codegen +description: A package for testing codegen dependencies: - # To update these, use "flutter update-packages --force-upgrade". build: 1.1.1 - build_modules: 1.0.7 - package_config: 1.0.5 - path: 1.6.2 - analyzer: 0.35.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + analyzer: 0.35.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" args: 1.5.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" async: 2.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - bazel_worker: 0.1.20 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - build_config: 0.3.1+4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" collection: 1.14.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" convert: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" crypto: 2.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.14.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - fixnum: 0.10.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - front_end: 0.1.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + front_end: 0.1.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" glob: 1.1.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - graphs: 0.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - html: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - json_annotation: 2.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - kernel: 0.3.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + html: 0.13.4+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + kernel: 0.3.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" logging: 0.11.3+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - pedantic: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + package_config: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + path: 1.6.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" plugin: 0.2.0+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - pool: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - protobuf: 0.13.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pub_semver: 1.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - pubspec_parse: 0.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - scratch_space: 0.0.3+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - source_span: 1.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + source_span: 1.5.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" string_scanner: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" term_glyph: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -46,8 +30,8 @@ dependencies: watcher: 0.9.7+10 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 2.1.15 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" -dartdoc: - # Exclude this package from the hosted API docs. - nodoc: true +environment: + # The pub client defaults to an <2.0.0 sdk constraint which we need to explicitly overwrite. + sdk: ">=2.0.0-dev.68.0 <3.0.0" -# PUBSPEC CHECKSUM: 0361 +# PUBSPEC CHECKSUM: eed2 diff --git a/dev/integration_tests/ui/pubspec.yaml b/dev/integration_tests/ui/pubspec.yaml index 33f37b5f0d..916c28802a 100644 --- a/dev/integration_tests/ui/pubspec.yaml +++ b/dev/integration_tests/ui/pubspec.yaml @@ -13,7 +13,7 @@ dependencies: sdk: flutter test: 1.5.3 - analyzer: 0.35.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + analyzer: 0.35.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" archive: 2.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" args: 1.5.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" async: 2.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -24,9 +24,9 @@ dependencies: crypto: 2.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.14.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" file: 5.0.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - front_end: 0.1.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + front_end: 0.1.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" glob: 1.1.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - html: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + html: 0.13.4+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http: 0.12.0+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_multi_server: 2.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_parser: 3.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -34,7 +34,7 @@ dependencies: io: 0.3.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" js: 0.6.1+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" json_rpc_2: 2.0.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - kernel: 0.3.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + kernel: 0.3.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" logging: 0.11.3+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" matcher: 0.12.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -42,10 +42,10 @@ dependencies: multi_server_socket: 1.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" node_preamble: 1.4.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" package_config: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - package_resolver: 1.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + package_resolver: 1.0.10 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path: 1.6.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - pedantic: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - petitparser: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + pedantic: 1.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + petitparser: 2.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" plugin: 0.2.0+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pool: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" pub_semver: 1.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -55,7 +55,7 @@ dependencies: shelf_web_socket: 0.2.2+4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" source_map_stack_trace: 1.1.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" source_maps: 0.10.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - source_span: 1.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + source_span: 1.5.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 1.6.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" string_scanner: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -67,7 +67,7 @@ dependencies: vm_service_client: 0.2.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 0.9.7+10 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 1.0.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - xml: 3.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + xml: 3.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 2.1.15 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: @@ -80,4 +80,4 @@ dev_dependencies: flutter: uses-material-design: true -# PUBSPEC CHECKSUM: 1584 +# PUBSPEC CHECKSUM: aeb8 diff --git a/dev/integration_tests/web/lib/main.dart b/dev/integration_tests/web/lib/main.dart new file mode 100644 index 0000000000..49c544cb7c --- /dev/null +++ b/dev/integration_tests/web/lib/main.dart @@ -0,0 +1,13 @@ +// 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 'package:flutter/widgets.dart'; + +void main() { + runApp(Center( + // Can remove when https://github.com/dart-lang/sdk/issues/35801 is fixed. + // ignore: prefer_const_constructors + child: Text('Hello, World', textDirection: TextDirection.ltr), + )); +} diff --git a/dev/integration_tests/web/pubspec.yaml b/dev/integration_tests/web/pubspec.yaml new file mode 100644 index 0000000000..8749907e23 --- /dev/null +++ b/dev/integration_tests/web/pubspec.yaml @@ -0,0 +1,17 @@ +name: web_integration +description: Integration test for web compilation. + +environment: + # The pub client defaults to an <2.0.0 sdk constraint which we need to explicitly overwrite. + sdk: ">=2.0.0-dev.68.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + collection: 1.14.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + meta: 1.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + typed_data: 1.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + vector_math: 2.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + +# PUBSPEC CHECKSUM: d53c diff --git a/dev/integration_tests/web/web/index.html b/dev/integration_tests/web/web/index.html new file mode 100644 index 0000000000..9fa55fed16 --- /dev/null +++ b/dev/integration_tests/web/web/index.html @@ -0,0 +1,10 @@ + + + + + web_integration + + + + + diff --git a/dev/manual_tests/lib/card_collection.dart b/dev/manual_tests/lib/card_collection.dart index 896ec524d3..3c06421a06 100644 --- a/dev/manual_tests/lib/card_collection.dart +++ b/dev/manual_tests/lib/card_collection.dart @@ -56,14 +56,14 @@ class CardCollectionState extends State { (int i) { _cardModels[i].height = _editable ? max(_cardHeights[i], 60.0) : _cardHeights[i]; return _cardModels[i]; - } + }, ); } void _initVariableSizedCardModels() { _cardModels = List.generate( _cardHeights.length, - (int i) => CardModel(i, _editable ? max(_cardHeights[i], 60.0) : _cardHeights[i]) + (int i) => CardModel(i, _editable ? max(_cardHeights[i], 60.0) : _cardHeights[i]), ); } @@ -234,7 +234,7 @@ class CardCollectionState extends State { Widget _buildAppBar(BuildContext context) { return AppBar( actions: [ - Text(_dismissDirectionText(_dismissDirection)) + Text(_dismissDirectionText(_dismissDirection)), ], flexibleSpace: Container( padding: const EdgeInsets.only(left: 72.0), diff --git a/dev/manual_tests/lib/drag_and_drop.dart b/dev/manual_tests/lib/drag_and_drop.dart index cc27bf7d8c..d825c52a10 100644 --- a/dev/manual_tests/lib/drag_and_drop.dart +++ b/dev/manual_tests/lib/drag_and_drop.dart @@ -32,11 +32,11 @@ class ExampleDragTargetState extends State { color: data.isEmpty ? _color : Colors.grey.shade200, border: Border.all( width: 3.0, - color: data.isEmpty ? Colors.white : Colors.blue + color: data.isEmpty ? Colors.white : Colors.blue, ), - ) + ), ); - } + }, ); } } @@ -65,10 +65,10 @@ class DotState extends State { decoration: BoxDecoration( color: widget.color, border: Border.all(width: taps.toDouble()), - shape: BoxShape.circle + shape: BoxShape.circle, ), - child: widget.child - ) + child: widget.child, + ), ); } } @@ -79,7 +79,7 @@ class ExampleDragSource extends StatelessWidget { this.color, this.heavy = false, this.under = true, - this.child + this.child, }) : super(key: key); final Color color; @@ -103,13 +103,13 @@ class ExampleDragSource extends StatelessWidget { child: Dot( color: color, size: size, - child: Center(child: child) - ) + child: Center(child: child), + ), ); Widget feedback = Opacity( opacity: 0.75, - child: contents + child: contents, ); Offset feedbackOffset; @@ -118,7 +118,7 @@ class ExampleDragSource extends StatelessWidget { feedback = Transform( transform: Matrix4.identity() ..translate(-size / 2.0, -(size / 2.0 + kFingerSize)), - child: feedback + child: feedback, ); feedbackOffset = const Offset(0.0, -kFingerSize); anchor = DragAnchor.pointer; @@ -133,7 +133,7 @@ class ExampleDragSource extends StatelessWidget { child: contents, feedback: feedback, feedbackOffset: feedbackOffset, - dragAnchor: anchor + dragAnchor: anchor, ); } else { return Draggable( @@ -141,7 +141,7 @@ class ExampleDragSource extends StatelessWidget { child: contents, feedback: feedback, feedbackOffset: feedbackOffset, - dragAnchor: anchor + dragAnchor: anchor, ); } } @@ -193,15 +193,15 @@ class MovableBall extends StatelessWidget { color: Colors.blue.shade700, size: kBallSize, tappable: true, - child: const Center(child: Text('BALL')) - ) + child: const Center(child: Text('BALL')), + ), ); final Widget dashedBall = Container( width: kBallSize, height: kBallSize, child: const CustomPaint( painter: DashOutlineCirclePainter() - ) + ), ); if (position == ballPosition) { return Draggable( @@ -209,14 +209,14 @@ class MovableBall extends StatelessWidget { child: ball, childWhenDragging: dashedBall, feedback: ball, - maxSimultaneousDrags: 1 + maxSimultaneousDrags: 1, ); } else { return DragTarget( onAccept: (bool data) { callback(position); }, builder: (BuildContext context, List accepted, List rejected) { return dashedBall; - } + }, ); } } @@ -238,7 +238,7 @@ class DragAndDropAppState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: const Text('Drag and Drop Flutter Demo') + title: const Text('Drag and Drop Flutter Demo'), ), body: Column( children: [ @@ -251,22 +251,22 @@ class DragAndDropAppState extends State { color: Colors.yellow.shade300, under: true, heavy: false, - child: const Text('under') + child: const Text('under'), ), ExampleDragSource( color: Colors.green.shade300, under: false, heavy: true, - child: const Text('long-press above') + child: const Text('long-press above'), ), ExampleDragSource( color: Colors.indigo.shade300, under: false, heavy: false, - child: const Text('above') + child: const Text('above'), ), ], - ) + ), ), Expanded( child: Row( @@ -275,8 +275,8 @@ class DragAndDropAppState extends State { Expanded(child: ExampleDragTarget()), Expanded(child: ExampleDragTarget()), Expanded(child: ExampleDragTarget()), - ] - ) + ], + ), ), Expanded( child: Row( @@ -286,10 +286,10 @@ class DragAndDropAppState extends State { MovableBall(2, position, moveBall), MovableBall(3, position, moveBall), ], - ) + ), ), - ] - ) + ], + ), ); } } @@ -297,6 +297,6 @@ class DragAndDropAppState extends State { void main() { runApp(MaterialApp( title: 'Drag and Drop Flutter Demo', - home: DragAndDropApp() + home: DragAndDropApp(), )); } diff --git a/dev/manual_tests/lib/material_arc.dart b/dev/manual_tests/lib/material_arc.dart index 23fae24bef..5e16d6479c 100644 --- a/dev/manual_tests/lib/material_arc.dart +++ b/dev/manual_tests/lib/material_arc.dart @@ -48,7 +48,7 @@ class _IgnoreDrag extends Drag { class _PointDemoPainter extends CustomPainter { _PointDemoPainter({ Animation repaint, - this.arc + this.arc, }) : _repaint = repaint, super(repaint: repaint); final MaterialPointArcTween arc; @@ -202,7 +202,7 @@ class _PointDemoState extends State<_PointDemo> { key: _painterKey, foregroundPainter: _PointDemoPainter( repaint: _animation, - arc: arc + arc: arc, ), // Watch out: if this IgnorePointer is left out, then gestures that // fail _PointDemoPainter.hitTest() will still be recognized because @@ -213,12 +213,12 @@ class _PointDemoState extends State<_PointDemo> { child: Text( 'Tap the refresh button to run the animation. Drag the green ' "and red points to change the animation's path.", - style: Theme.of(context).textTheme.caption.copyWith(fontSize: 16.0) - ) - ) - ) - ) - ) + style: Theme.of(context).textTheme.caption.copyWith(fontSize: 16.0), + ), + ), + ), + ), + ), ); } } @@ -226,7 +226,7 @@ class _PointDemoState extends State<_PointDemo> { class _RectangleDemoPainter extends CustomPainter { _RectangleDemoPainter({ Animation repaint, - this.arc + this.arc, }) : _repaint = repaint, super(repaint: repaint); final MaterialRectArcTween arc; @@ -350,11 +350,11 @@ class _RectangleDemoState extends State<_RectangleDemo> { _screenSize = screenSize; _begin = Rect.fromLTWH( screenSize.width * 0.5, screenSize.height * 0.2, - screenSize.width * 0.4, screenSize.height * 0.2 + screenSize.width * 0.4, screenSize.height * 0.2, ); _end = Rect.fromLTWH( screenSize.width * 0.1, screenSize.height * 0.4, - screenSize.width * 0.3, screenSize.height * 0.3 + screenSize.width * 0.3, screenSize.height * 0.3, ); } @@ -375,7 +375,7 @@ class _RectangleDemoState extends State<_RectangleDemo> { key: _painterKey, foregroundPainter: _RectangleDemoPainter( repaint: _animation, - arc: arc + arc: arc, ), // Watch out: if this IgnorePointer is left out, then gestures that // fail _RectDemoPainter.hitTest() will still be recognized because @@ -386,12 +386,12 @@ class _RectangleDemoState extends State<_RectangleDemo> { child: Text( 'Tap the refresh button to run the animation. Drag the rectangles ' "to change the animation's path.", - style: Theme.of(context).textTheme.caption.copyWith(fontSize: 16.0) - ) - ) - ) - ) - ) + style: Theme.of(context).textTheme.caption.copyWith(fontSize: 16.0), + ), + ), + ), + ), + ), ); } } @@ -426,13 +426,13 @@ class _AnimationDemoState extends State with TickerProviderStateM _ArcDemo('POINT', (_ArcDemo demo) { return _PointDemo( key: demo.key, - controller: demo.controller + controller: demo.controller, ); }, this), _ArcDemo('RECTANGLE', (_ArcDemo demo) { return _RectangleDemo( key: demo.key, - controller: demo.controller + controller: demo.controller, ); }, this), ]; @@ -466,9 +466,9 @@ class _AnimationDemoState extends State with TickerProviderStateM }, ), body: TabBarView( - children: _allDemos.map((_ArcDemo demo) => demo.builder(demo)).toList() - ) - ) + children: _allDemos.map((_ArcDemo demo) => demo.builder(demo)).toList(), + ), + ), ); } } diff --git a/dev/manual_tests/lib/raw_keyboard.dart b/dev/manual_tests/lib/raw_keyboard.dart index 06ba889734..a2474eed56 100644 --- a/dev/manual_tests/lib/raw_keyboard.dart +++ b/dev/manual_tests/lib/raw_keyboard.dart @@ -92,6 +92,11 @@ class _HardwareKeyDemoState extends State { dataText.add(Text('codePoint: ${data.codePoint} (${_asHex(data.codePoint)})')); dataText.add(Text('hidUsage: ${data.hidUsage} (${_asHex(data.hidUsage)})')); dataText.add(Text('modifiers: ${data.modifiers} (${_asHex(data.modifiers)})')); + } else if (data is RawKeyEventDataMacOs) { + dataText.add(Text('keyCode: ${data.keyCode} (${_asHex(data.keyCode)})')); + dataText.add(Text('characters: ${data.characters}')); + dataText.add(Text('charactersIgnoringModifiers: ${data.charactersIgnoringModifiers}')); + dataText.add(Text('modifiers: ${data.modifiers} (${_asHex(data.modifiers)})')); } dataText.add(Text('logical: ${_event.logicalKey}')); dataText.add(Text('physical: ${_event.physicalKey}')); diff --git a/dev/manual_tests/lib/text.dart b/dev/manual_tests/lib/text.dart index 0244f3e6c0..6382fb3b8f 100644 --- a/dev/manual_tests/lib/text.dart +++ b/dev/manual_tests/lib/text.dart @@ -515,7 +515,7 @@ class _FuzzerState extends State with SingleTickerProviderStateMixin { debugPrint(_textSpan.toStringDeep()); } }); - } + }, ), ), ], @@ -573,7 +573,7 @@ class _UnderlinesState extends State { ), child: ListBody( children: lines, - ) + ), ), ), ), @@ -668,7 +668,7 @@ class _FallbackState extends State { child: ListBody( children: lines, ), - ) + ), ), ), ), @@ -1382,7 +1382,7 @@ String zalgo(math.Random random, int targetLength, { bool includeSpacingCombinin 0x16F7E, 0x1D165, 0x1D166, 0x1D16D, 0x1D16E, 0x1D16F, 0x1D170, 0x1D171, 0x1D172, ]; - final Set these = Set(); + final Set these = {}; int combiningCount = enclosingCombiningMarks.length + nonspacingCombiningMarks.length; if (includeSpacingCombiningMarks) combiningCount += spacingCombiningMarks.length; diff --git a/dev/manual_tests/pubspec.yaml b/dev/manual_tests/pubspec.yaml index ff8a380f75..54802c1f57 100644 --- a/dev/manual_tests/pubspec.yaml +++ b/dev/manual_tests/pubspec.yaml @@ -2,7 +2,7 @@ name: manual_tests environment: # The pub client defaults to an <2.0.0 sdk constraint which we need to explicitly overwrite. - sdk: ">=2.0.0-dev.68.0 <3.0.0" + sdk: ">=2.2.0 <3.0.0" dependencies: flutter: @@ -24,9 +24,9 @@ dev_dependencies: charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" matcher: 0.12.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path: 1.6.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - pedantic: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + pedantic: 1.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" quiver: 2.0.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - source_span: 1.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + source_span: 1.5.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 1.6.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" string_scanner: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -36,4 +36,4 @@ dev_dependencies: flutter: uses-material-design: true -# PUBSPEC CHECKSUM: f504 +# PUBSPEC CHECKSUM: 3806 diff --git a/dev/snippets/README.md b/dev/snippets/README.md index 0606877c7b..a1e7875ade 100644 --- a/dev/snippets/README.md +++ b/dev/snippets/README.md @@ -7,8 +7,9 @@ snippets. This takes code in dartdocs, like this: ```dart -/// The following is a skeleton of a stateless widget subclass called `GreenFrog`: /// {@tool snippet --template="stateless_widget"} +/// The following is a skeleton of a stateless widget subclass called `GreenFrog`. +/// ```dart /// class GreenFrog extends StatelessWidget { /// const GreenFrog({ Key key }) : super(key: key); /// @@ -17,6 +18,7 @@ This takes code in dartdocs, like this: /// return Container(color: const Color(0xFF2DBD3A)); /// } /// } +/// ``` /// {@end-tool} ``` diff --git a/dev/snippets/config/skeletons/application.html b/dev/snippets/config/skeletons/application.html index afe9c4c3d5..7d7e17bab4 100644 --- a/dev/snippets/config/skeletons/application.html +++ b/dev/snippets/config/skeletons/application.html @@ -1,26 +1,30 @@ {@inject-html}
- - + + +
-
+
{{description}}
{{code}}
-