[integration_test] Add watchPerformance (#3116)

* add watchPerformance
diff --git a/packages/integration_test/CHANGELOG.md b/packages/integration_test/CHANGELOG.md
index d6ef143..409af07 100644
--- a/packages/integration_test/CHANGELOG.md
+++ b/packages/integration_test/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.9.2
+
+* Add `watchPerformance` for performance test.
+
 ## 0.9.1
 
 * Keep handling deprecated Android v1 classes for backward compatibility.
diff --git a/packages/integration_test/lib/integration_test.dart b/packages/integration_test/lib/integration_test.dart
index 4176c1c..5a37e88 100644
--- a/packages/integration_test/lib/integration_test.dart
+++ b/packages/integration_test/lib/integration_test.dart
@@ -4,6 +4,7 @@
 
 import 'dart:async';
 import 'dart:developer' as developer;
+import 'dart:ui';
 
 import 'package:flutter/rendering.dart';
 import 'package:flutter_test/flutter_test.dart';
@@ -81,6 +82,10 @@
 
   Size _surfaceSize;
 
+  // This flag is used to print warning messages when tracking performance
+  // under debug mode.
+  static bool _firstRun = false;
+
   /// Artificially changes the surface size to `size` on the Widget binding,
   /// then flushes microtasks.
   ///
@@ -282,4 +287,43 @@
     reportData ??= <String, dynamic>{};
     reportData[reportKey] = timeline.toJson();
   }
+
+  /// Watches the [FrameTiming] during `action` and report it to the binding
+  /// with key `reportKey`.
+  ///
+  /// This can be used to implement performance tests previously using
+  /// [traceAction] and [TimelineSummary] from [flutter_driver]
+  Future<void> watchPerformance(
+    Future<void> action(), {
+    String reportKey = 'performance',
+  }) async {
+    assert(() {
+      if (_firstRun) {
+        debugPrint(kDebugWarning);
+        _firstRun = false;
+      }
+      return true;
+    }());
+
+    // The engine could batch FrameTimings and send them only once per second.
+    // Delay for a sufficient time so either old FrameTimings are flushed and not
+    // interfering our measurements here, or new FrameTimings are all reported.
+    // TODO(CareF): remove this when flush FrameTiming is readly in engine.
+    //              See https://github.com/flutter/flutter/issues/64808
+    //              and https://github.com/flutter/flutter/issues/67593
+    Future<void> delayForFrameTimings() =>
+        Future<void>.delayed(const Duration(seconds: 2));
+
+    await delayForFrameTimings(); // flush old FrameTimings
+    final List<FrameTiming> frameTimings = <FrameTiming>[];
+    final TimingsCallback watcher = frameTimings.addAll;
+    addTimingsCallback(watcher);
+    await action();
+    await delayForFrameTimings(); // make sure all FrameTimings are reported
+    removeTimingsCallback(watcher);
+    final FrameTimingSummarizer frameTimes =
+        FrameTimingSummarizer(frameTimings);
+    reportData ??= <String, dynamic>{};
+    reportData[reportKey] = frameTimes.summary;
+  }
 }
diff --git a/packages/integration_test/pubspec.yaml b/packages/integration_test/pubspec.yaml
index 39a48d1..d9a27eb 100644
--- a/packages/integration_test/pubspec.yaml
+++ b/packages/integration_test/pubspec.yaml
@@ -1,6 +1,6 @@
 name: integration_test
 description: Runs tests that use the flutter_test API as integration tests.
-version: 0.9.1
+version: 0.9.2
 homepage: https://github.com/flutter/plugins/tree/master/packages/integration_test
 
 environment: