From b05210c707cc5b9edb046304df407e6e0e8a57db Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Thu, 19 Mar 2020 16:27:41 -0700 Subject: [PATCH] Move ios screenshot test to flutter gold. (#52553) --- ...lutter_driver_screenshot_test_fuchsia.dart | 2 +- .../lib/tasks/integration_tests.dart | 10 +- .../flutter_driver_screenshot_test/README.md | 4 +- .../ios/Podfile | 87 +++++++++-------- .../test_driver/driver_screenshot_tester.dart | 89 ------------------ .../test_driver/flutter_gold_main_test.dart | 38 -------- .../goldens/red_square_image/iPhone7,2.png | Bin 19364 -> 0 bytes .../test_driver/main_test.dart | 14 +-- .../flutter_test/lib/src/_goldens_io.dart | 1 - 9 files changed, 62 insertions(+), 183 deletions(-) delete mode 100644 dev/integration_tests/flutter_driver_screenshot_test/test_driver/driver_screenshot_tester.dart delete mode 100644 dev/integration_tests/flutter_driver_screenshot_test/test_driver/flutter_gold_main_test.dart delete mode 100644 dev/integration_tests/flutter_driver_screenshot_test/test_driver/goldens/red_square_image/iPhone7,2.png diff --git a/dev/devicelab/bin/tasks/flutter_driver_screenshot_test_fuchsia.dart b/dev/devicelab/bin/tasks/flutter_driver_screenshot_test_fuchsia.dart index 424bd15a815..8d97bb9ad5d 100644 --- a/dev/devicelab/bin/tasks/flutter_driver_screenshot_test_fuchsia.dart +++ b/dev/devicelab/bin/tasks/flutter_driver_screenshot_test_fuchsia.dart @@ -10,5 +10,5 @@ import 'package:flutter_devicelab/tasks/integration_tests.dart'; Future main() async { deviceOperatingSystem = DeviceOperatingSystem.fuchsia; - await task(createFlutterDriverScreenshotTest(useFlutterGold: true)); + await task(createFlutterDriverScreenshotTest()); } diff --git a/dev/devicelab/lib/tasks/integration_tests.dart b/dev/devicelab/lib/tasks/integration_tests.dart index a40b5340a44..5078cea1649 100644 --- a/dev/devicelab/lib/tasks/integration_tests.dart +++ b/dev/devicelab/lib/tasks/integration_tests.dart @@ -108,17 +108,11 @@ TaskFunction createAndroidSplashScreenKitchenSinkTest() { } /// Executes a driver test that takes a screenshot and compares it against a golden image. -/// If [useFlutterGold] is true, the golden image is served by Flutter Gold -/// (https://flutter-gold.skia.org/), otherwise the golden image is read from the disk. -TaskFunction createFlutterDriverScreenshotTest({ - bool useFlutterGold = false, -}) { +/// The golden image is served by Flutter Gold (https://flutter-gold.skia.org/). +TaskFunction createFlutterDriverScreenshotTest() { return DriverTest( '${flutterDirectory.path}/dev/integration_tests/flutter_driver_screenshot_test', 'lib/main.dart', - extraOptions: useFlutterGold ? const [ - '--driver', 'test_driver/flutter_gold_main_test.dart' - ] : const [] ); } diff --git a/dev/integration_tests/flutter_driver_screenshot_test/README.md b/dev/integration_tests/flutter_driver_screenshot_test/README.md index 110d016d2a1..e9fba7b6713 100644 --- a/dev/integration_tests/flutter_driver_screenshot_test/README.md +++ b/dev/integration_tests/flutter_driver_screenshot_test/README.md @@ -6,8 +6,7 @@ Each sub page should displays some simple UIs to screenshot tested. The flutter driver test runs the app and opens each page to take a screenshot. -Use `test_driver/flutter_gold_main_test.dart` to test against golden files stored on Flutter Gold. -Otherwise, use `main_test.dart` to test against golden files stored on `test_driver/goldens//.png`. +Use `main_test.dart` to test against golden files stored on Flutter Gold. Note that new binaries can't be checked in the Flutter repo, so use [Flutter Gold](https://github.com/flutter/flutter/wiki/Writing-a-golden-file-test-for-package:flutter) instead. @@ -17,7 +16,6 @@ Note that new binaries can't be checked in the Flutter repo, so use [Flutter Gol 2. The new class should set a static `title` and `key` 3. Add an instance of the new class to the `_allPages` list in the `main.dart` 4. Create a new test case similar to `"'A page with an image screenshot"` in `test_driver/main_test.dart` to run the screenshot test. -5. Create directories for the test: `test_driver/goldens/` should be created before running the test based on the target platform the test is designed to run. An example of a `Page` subclass can be found in `lib/image_page.dart` diff --git a/dev/integration_tests/flutter_driver_screenshot_test/ios/Podfile b/dev/integration_tests/flutter_driver_screenshot_test/ios/Podfile index e9286cbac1e..6697f0a539e 100644 --- a/dev/integration_tests/flutter_driver_screenshot_test/ios/Podfile +++ b/dev/integration_tests/flutter_driver_screenshot_test/ios/Podfile @@ -15,56 +15,69 @@ def parse_KV_file(file, separator='=') if !File.exists? file_abs_path return []; end - pods_ary = [] + generated_key_values = {} 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 + File.foreach(file_abs_path) do |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) + generated_key_values[podname] = podpath + else + puts "Invalid plugin specification: #{line}" + end + end + generated_key_values end target 'Runner' do use_frameworks! + use_modular_headers! + + # Flutter Pod + + copied_flutter_dir = File.join(__dir__, 'Flutter') + copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework') + copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec') + unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path) + # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet. + # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration. + # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist. + + generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig') + unless File.exist?(generated_xcode_build_settings_path) + raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path) + cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR']; + + unless File.exist?(copied_framework_path) + FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir) + end + unless File.exist?(copied_podspec_path) + FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir) + end + end + + # Keep pod path relative so it can be checked into Podfile.lock. + pod 'Flutter', :path => 'Flutter' + + # Plugin Pods # 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 pub 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') - } + plugin_pods.each do |name, path| + symlink = File.join('.symlinks', 'plugins', name) + File.symlink(path, symlink) + pod name, :path => File.join(symlink, 'ios') + end end -# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system. -install! 'cocoapods', :disable_input_output_paths => true - post_install do |installer| installer.pods_project.targets.each do |target| target.build_configurations.each do |config| diff --git a/dev/integration_tests/flutter_driver_screenshot_test/test_driver/driver_screenshot_tester.dart b/dev/integration_tests/flutter_driver_screenshot_test/test_driver/driver_screenshot_tester.dart deleted file mode 100644 index e3d1d746220..00000000000 --- a/dev/integration_tests/flutter_driver_screenshot_test/test_driver/driver_screenshot_tester.dart +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2014 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:io' show File; - -import 'package:flutter_driver/flutter_driver.dart'; -import 'package:meta/meta.dart'; -import 'package:path/path.dart' as path; - -const String _kPathParent = 'test_driver/goldens/'; - -/// The utility class that helps test cases to tests screenshots with a [FlutterDriver]. -@immutable -class DriverScreenShotTester { - /// Constructs a [DriverScreenShotTester]. - /// - /// All the parameters are required and must not be null. - const DriverScreenShotTester({ - @required this.testName, - @required this.driver, - @required this.deviceModel, - }) : assert(testName != null), - assert(driver != null), - assert(deviceModel != null); - - /// The name of the test. - /// - /// It needs to match the folder name which the goldens resides under `test_driver/goldens`. - final String testName; - - /// The `FlutterDriver` used to take the screenshots. - final FlutterDriver driver; - - /// The device model of the device that the test is running on. - final String deviceModel; - - /// Compares `screenshot` to the corresponding golden image. Returns true if they match. - /// - /// The golden image should exists at `test_driver/goldens//.png` - /// prior to this call. - Future compareScreenshots(List screenshot) async { - if (screenshot == null) { - return false; - } - final File file = File(_getImageFilePath()); - final List matcher = await file.readAsBytes(); - - if (matcher == null) { - return false; - } - return _bytesEqual(screenshot, matcher); - } - - bool _bytesEqual(List a, List b) { - if (a.length != b.length) { - return false; - } - for (int index = 0; index < a.length; index += 1) { - if (a[index] != b[index]) { - return false; - } - } - return true; - } - - /// Returns a bytes representation of a screenshot on the current screen. - Future> getScreenshotAsBytes() async { - return await driver.screenshot(); - } - - /// Save the `screenshot` as a golden image. - /// - /// The path of the image is defined as: - /// `test_driver/goldens//.png` - /// - /// Can be used when recording the golden for the first time. - Future saveScreenshot(List screenshot) async { - final File file = File(_getImageFilePath()); - if (!file.existsSync()) { - await file.writeAsBytes(screenshot); - } - } - - String _getImageFilePath() { - return path.joinAll([_kPathParent, testName, deviceModel + '.png']); - } -} diff --git a/dev/integration_tests/flutter_driver_screenshot_test/test_driver/flutter_gold_main_test.dart b/dev/integration_tests/flutter_driver_screenshot_test/test_driver/flutter_gold_main_test.dart deleted file mode 100644 index b8dd6ab73a2..00000000000 --- a/dev/integration_tests/flutter_driver_screenshot_test/test_driver/flutter_gold_main_test.dart +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2014 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_driver/flutter_driver.dart'; -import 'package:test/test.dart' hide TypeMatcher, isInstanceOf; -import 'package:flutter_test/src/buffer_matcher.dart'; - -Future main() async { - FlutterDriver driver; - String deviceModel; - - setUpAll(() async { - driver = await FlutterDriver.connect(); - deviceModel = await driver.requestData('device_model'); - }); - - tearDownAll(() => driver.close()); - - test('A page with an image screenshot', () async { - final SerializableFinder imagePageListTile = - find.byValueKey('image_page'); - await driver.waitFor(imagePageListTile); - await driver.tap(imagePageListTile); - await driver.waitFor(find.byValueKey('red_square_image')); - await driver.waitUntilNoTransientCallbacks(); - - // TODO(egarciad): This is currently a no-op on LUCI. - // https://github.com/flutter/flutter/issues/49837 - await expectLater( - driver.screenshot(), - bufferMatchesGoldenFile('red_square_driver_screenshot__$deviceModel.png'), - ); - - await driver.tap(find.byTooltip('Back')); - }); -} diff --git a/dev/integration_tests/flutter_driver_screenshot_test/test_driver/goldens/red_square_image/iPhone7,2.png b/dev/integration_tests/flutter_driver_screenshot_test/test_driver/goldens/red_square_image/iPhone7,2.png deleted file mode 100644 index 671988854f60cd327044d961b655d75d54f20173..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19364 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 main() async { FlutterDriver driver; @@ -19,7 +19,6 @@ Future main() async { tearDownAll(() => driver.close()); test('A page with an image screenshot', () async { - final SerializableFinder imagePageListTile = find.byValueKey('image_page'); await driver.waitFor(imagePageListTile); @@ -27,10 +26,13 @@ Future main() async { await driver.waitFor(find.byValueKey('red_square_image')); await driver.waitUntilNoTransientCallbacks(); - final DriverScreenShotTester tester = DriverScreenShotTester(testName: 'red_square_image', deviceModel: deviceModel, driver: driver); - final List screenShot = await tester.getScreenshotAsBytes(); - final bool compareResult = await tester.compareScreenshots(screenShot); - expect(compareResult, true); + // TODO(egarciad): This is currently a no-op on LUCI. + // https://github.com/flutter/flutter/issues/49837 + await expectLater( + driver.screenshot(), + bufferMatchesGoldenFile('red_square_driver_screenshot__$deviceModel.png'), + ); + await driver.tap(find.byTooltip('Back')); }); } diff --git a/packages/flutter_test/lib/src/_goldens_io.dart b/packages/flutter_test/lib/src/_goldens_io.dart index 49a24e70c04..edb81230e7f 100644 --- a/packages/flutter_test/lib/src/_goldens_io.dart +++ b/packages/flutter_test/lib/src/_goldens_io.dart @@ -6,7 +6,6 @@ import 'dart:async'; import 'dart:io'; import 'dart:math' as math; import 'dart:typed_data'; -import 'dart:ui'; import 'package:image/image.dart'; import 'package:path/path.dart' as path;