The original commit actually *enabled* the test by removing the flaky: true field in the commit. This reverts commit 1d3fcfd6ca7e83c6c7d134fc99deb015839b0389.
This commit is contained in:
parent
1d3fcfd6ca
commit
f3018c378a
@ -544,6 +544,9 @@ tasks:
|
|||||||
The test makes sure that there is no regression while renderring an image with gl on iOS.
|
The test makes sure that there is no regression while renderring an image with gl on iOS.
|
||||||
stage: devicelab_ios
|
stage: devicelab_ios
|
||||||
required_agent_capabilities: ["mac/ios", "ios/gl-render-image"]
|
required_agent_capabilities: ["mac/ios", "ios/gl-render-image"]
|
||||||
|
#TODO(cyanglaz): The flaky flag is added because it is the first screenshot test we added.
|
||||||
|
# Remove the flaky flag when we are sure the test is stable.
|
||||||
|
flaky: true
|
||||||
|
|
||||||
# TODO(fujino): does not pass on iOS13 https://github.com/flutter/flutter/issues/41133
|
# TODO(fujino): does not pass on iOS13 https://github.com/flutter/flutter/issues/41133
|
||||||
# system_debug_ios:
|
# system_debug_ios:
|
||||||
|
@ -5,14 +5,12 @@ The main page contains a list of buttons; each button leads to a designated sub
|
|||||||
Each sub page should displays some simple UIs to screenshot tested.
|
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.
|
The flutter driver test runs the app and opens each page to take a screenshot.
|
||||||
Then it compares the screenshots with golden files stored on Flutter Gold.
|
|
||||||
|
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/<some_test_page_name>/<device_model>.png`.
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
# Reconstruction
|
|
||||||
|
|
||||||
We are currently in the process of moving this test to use golden API. The configuration guide below might need to be updated after that is done.
|
|
||||||
|
|
||||||
# Add a new page to test
|
# Add a new page to test
|
||||||
|
|
||||||
1. Create a new class which extends `Page` and implement the UI to be tested in the `build` method.
|
1. Create a new class which extends `Page` and implement the UI to be tested in the `build` method.
|
||||||
@ -25,5 +23,5 @@ An example of a `Page` subclass can be found in `lib/image_page.dart`
|
|||||||
|
|
||||||
# Environments
|
# Environments
|
||||||
|
|
||||||
* Device Lab which runs the app on iPhone 6.
|
* Device Lab which runs the app on iPhone 6s.
|
||||||
* LUCI which runs the app on a Fuchsia NUC device.
|
* LUCI which runs the app on a Fuchsia NUC device.
|
||||||
|
@ -0,0 +1,89 @@
|
|||||||
|
// 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/<testName>/<deviceModel>.png`
|
||||||
|
/// prior to this call.
|
||||||
|
Future<bool> compareScreenshots(List<int> screenshot) async {
|
||||||
|
if (screenshot == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final File file = File(_getImageFilePath());
|
||||||
|
final List<int> matcher = await file.readAsBytes();
|
||||||
|
|
||||||
|
if (matcher == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return _bytesEqual(screenshot, matcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _bytesEqual(List<int> a, List<int> 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<List<int>> getScreenshotAsBytes() async {
|
||||||
|
return await driver.screenshot();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Save the `screenshot` as a golden image.
|
||||||
|
///
|
||||||
|
/// The path of the image is defined as:
|
||||||
|
/// `test_driver/goldens/<testName>/<deviceModel>.png`
|
||||||
|
///
|
||||||
|
/// Can be used when recording the golden for the first time.
|
||||||
|
Future<void> saveScreenshot(List<int> screenshot) async {
|
||||||
|
final File file = File(_getImageFilePath());
|
||||||
|
if (!file.existsSync()) {
|
||||||
|
await file.writeAsBytes(screenshot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String _getImageFilePath() {
|
||||||
|
return path.joinAll(<String>[_kPathParent, testName, deviceModel + '.png']);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
// 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<void> 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'));
|
||||||
|
});
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
@ -5,7 +5,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:flutter_driver/flutter_driver.dart';
|
import 'package:flutter_driver/flutter_driver.dart';
|
||||||
import 'package:test/test.dart' hide TypeMatcher, isInstanceOf;
|
import 'package:test/test.dart' hide TypeMatcher, isInstanceOf;
|
||||||
import 'package:flutter_test/src/buffer_matcher.dart';
|
import './driver_screenshot_tester.dart';
|
||||||
|
|
||||||
Future<void> main() async {
|
Future<void> main() async {
|
||||||
FlutterDriver driver;
|
FlutterDriver driver;
|
||||||
@ -18,8 +18,8 @@ Future<void> main() async {
|
|||||||
|
|
||||||
tearDownAll(() => driver.close());
|
tearDownAll(() => driver.close());
|
||||||
|
|
||||||
// TODO(cyanglaz): Enable the test after https://github.com/flutter/flutter/pull/49815 lands.
|
|
||||||
test('A page with an image screenshot', () async {
|
test('A page with an image screenshot', () async {
|
||||||
|
|
||||||
final SerializableFinder imagePageListTile =
|
final SerializableFinder imagePageListTile =
|
||||||
find.byValueKey('image_page');
|
find.byValueKey('image_page');
|
||||||
await driver.waitFor(imagePageListTile);
|
await driver.waitFor(imagePageListTile);
|
||||||
@ -27,13 +27,10 @@ Future<void> main() async {
|
|||||||
await driver.waitFor(find.byValueKey('red_square_image'));
|
await driver.waitFor(find.byValueKey('red_square_image'));
|
||||||
await driver.waitUntilNoTransientCallbacks();
|
await driver.waitUntilNoTransientCallbacks();
|
||||||
|
|
||||||
// TODO(egarciad): This is currently a no-op on LUCI.
|
final DriverScreenShotTester tester = DriverScreenShotTester(testName: 'red_square_image', deviceModel: deviceModel, driver: driver);
|
||||||
// https://github.com/flutter/flutter/issues/49837
|
final List<int> screenShot = await tester.getScreenshotAsBytes();
|
||||||
await expectLater(
|
final bool compareResult = await tester.compareScreenshots(screenShot);
|
||||||
driver.screenshot(),
|
expect(compareResult, true);
|
||||||
bufferMatchesGoldenFile('red_square_driver_screenshot__$deviceModel.png'),
|
|
||||||
);
|
|
||||||
|
|
||||||
await driver.tap(find.byTooltip('Back'));
|
await driver.tap(find.byTooltip('Back'));
|
||||||
}, skip: true);
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user