-
Notifications
You must be signed in to change notification settings - Fork 3.6k
[web_benchmarks] Refactor the test benchmark app to make the example easier to follow #7640
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 10 commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
eec1ac2
Refactor the test benchmark app to make the example easier to follow
kenzieschmoll 0a155ec
remove case
kenzieschmoll dfd6d34
fix test
kenzieschmoll 31adbd3
remove import
kenzieschmoll ec8ca10
clean up
kenzieschmoll 956919c
revert go router
kenzieschmoll 998fd64
remove path url strategy
kenzieschmoll 0de0753
remove unused route
kenzieschmoll eb480e4
remove initial page
kenzieschmoll 8a6631b
versions
kenzieschmoll 268e261
test version
kenzieschmoll 9cab269
spelling
kenzieschmoll 463d875
add license
kenzieschmoll File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
146 changes: 146 additions & 0 deletions
146
packages/web_benchmarks/testing/test_app/benchmark/test_infra/automator.dart
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,146 @@ | ||
| // Copyright 2013 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. | ||
|
|
||
| // ignore_for_file: avoid_print | ||
|
|
||
| import 'dart:async'; | ||
|
|
||
| import 'package:flutter/foundation.dart'; | ||
| import 'package:flutter/material.dart'; | ||
| import 'package:flutter_test/flutter_test.dart'; | ||
| import 'package:test_app/home_page.dart' show aboutPageKey, textKey; | ||
| import 'package:test_app/main.dart'; | ||
| import 'package:web/web.dart'; | ||
| import 'package:web_benchmarks/client.dart'; | ||
|
|
||
| import 'common.dart'; | ||
|
|
||
| /// A class that automates the test web app. | ||
| class Automater { | ||
| Automater({ | ||
| required this.benchmark, | ||
| required this.stopWarmingUpCallback, | ||
| required this.profile, | ||
| }); | ||
|
|
||
| /// The current benchmark. | ||
| final BenchmarkName benchmark; | ||
|
|
||
| /// A function to call when warm-up is finished. | ||
| /// | ||
| /// This function is intended to ask `Recorder` to mark the warm-up phase | ||
| /// as over. | ||
| final void Function() stopWarmingUpCallback; | ||
|
|
||
| /// The profile collected for the running benchmark | ||
| final Profile profile; | ||
|
|
||
| /// Whether the automation has ended. | ||
| bool finished = false; | ||
|
|
||
| /// A widget controller for automation. | ||
| late LiveWidgetController controller; | ||
|
|
||
| Widget createWidget() { | ||
| Future<void>.delayed(const Duration(milliseconds: 400), automate); | ||
| return const MyApp(); | ||
| } | ||
|
|
||
| Future<void> automate() async { | ||
| await warmUp(); | ||
|
|
||
| switch (benchmark) { | ||
| case BenchmarkName.appNavigate: | ||
| await _handleAppNavigate(); | ||
| case BenchmarkName.appScroll: | ||
| await _handleAppScroll(); | ||
| case BenchmarkName.appTap: | ||
| await _handleAppTap(); | ||
| case BenchmarkName.simpleCompilationCheck: | ||
| _handleSimpleCompilationCheck(); | ||
| case BenchmarkName.simpleInitialPageCheck: | ||
| _handleSimpleInitialPageCheck(); | ||
| } | ||
|
|
||
| // At the end of the test, mark as finished. | ||
| finished = true; | ||
| } | ||
|
|
||
| /// Warm up the animation. | ||
| Future<void> warmUp() async { | ||
| // Let animation stop. | ||
| await animationStops(); | ||
|
|
||
| // Set controller. | ||
| controller = LiveWidgetController(WidgetsBinding.instance); | ||
|
|
||
| await controller.pumpAndSettle(); | ||
|
|
||
| // When warm-up finishes, inform the recorder. | ||
| stopWarmingUpCallback(); | ||
| } | ||
|
|
||
| Future<void> _handleAppNavigate() async { | ||
| for (int i = 0; i < 10; ++i) { | ||
| print('Testing round $i...'); | ||
| await controller.tap(find.byKey(aboutPageKey)); | ||
| await animationStops(); | ||
| await controller.tap(find.byType(BackButton)); | ||
| await animationStops(); | ||
| } | ||
| } | ||
|
|
||
| Future<void> _handleAppScroll() async { | ||
| final ScrollableState scrollable = | ||
| Scrollable.of(find.byKey(textKey).evaluate().single); | ||
| await scrollable.position.animateTo( | ||
| 30000, | ||
| curve: Curves.linear, | ||
| duration: const Duration(seconds: 20), | ||
| ); | ||
| } | ||
|
|
||
| Future<void> _handleAppTap() async { | ||
| for (int i = 0; i < 10; ++i) { | ||
| print('Testing round $i...'); | ||
| await controller.tap(find.byIcon(Icons.add)); | ||
| await animationStops(); | ||
| } | ||
| } | ||
|
|
||
| void _handleSimpleCompilationCheck() { | ||
| // Record whether we are in wasm mode or not. Ideally, we'd have a more | ||
| // first-class way to add metadata like this, but this will work for us to | ||
| // pass information about the environment back to the server for the | ||
| // purposes of our own tests. | ||
| profile.extraData['isWasm'] = kIsWasm ? 1 : 0; | ||
| } | ||
|
|
||
| void _handleSimpleInitialPageCheck() { | ||
| // Record whether the URL contains the expected initial page so we can | ||
| // verify the behavior of setting the `initialPage` on the benchmark server. | ||
| final bool containsExpectedPage = | ||
| window.location.toString().contains(testBenchmarkInitialPage); | ||
| profile.extraData['expectedUrl'] = containsExpectedPage ? 1 : 0; | ||
| } | ||
| } | ||
|
|
||
| const Duration _animationCheckingInterval = Duration(milliseconds: 50); | ||
|
|
||
| Future<void> animationStops() async { | ||
| if (!WidgetsBinding.instance.hasScheduledFrame) { | ||
| return; | ||
| } | ||
|
|
||
| final Completer<void> stopped = Completer<void>(); | ||
|
|
||
| Timer.periodic(_animationCheckingInterval, (Timer timer) { | ||
| if (!WidgetsBinding.instance.hasScheduledFrame) { | ||
| stopped.complete(); | ||
| timer.cancel(); | ||
| } | ||
| }); | ||
|
|
||
| await stopped.future; | ||
| } | ||
21 changes: 21 additions & 0 deletions
21
packages/web_benchmarks/testing/test_app/benchmark/test_infra/client/app_client.dart
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| // Copyright 2013 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 'package:web_benchmarks/client.dart'; | ||
|
|
||
| import '../common.dart'; | ||
| import '../recorder.dart'; | ||
|
|
||
| Future<void> main() async { | ||
| await runBenchmarks( | ||
| <String, RecorderFactory>{ | ||
| BenchmarkName.appNavigate.name: () => | ||
| TestAppRecorder(benchmark: BenchmarkName.appNavigate), | ||
| BenchmarkName.appScroll.name: () => | ||
| TestAppRecorder(benchmark: BenchmarkName.appScroll), | ||
| BenchmarkName.appTap.name: () => | ||
| TestAppRecorder(benchmark: BenchmarkName.appTap), | ||
| }, | ||
| ); | ||
| } |
18 changes: 18 additions & 0 deletions
18
...eb_benchmarks/testing/test_app/benchmark/test_infra/client/simple_compilation_client.dart
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| // Copyright 2013 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 'package:web_benchmarks/client.dart'; | ||
|
|
||
| import '../common.dart'; | ||
| import '../recorder.dart'; | ||
|
|
||
| Future<void> main() async { | ||
| await runBenchmarks( | ||
| <String, RecorderFactory>{ | ||
| BenchmarkName.simpleCompilationCheck.name: () => TestAppRecorder( | ||
| benchmark: BenchmarkName.simpleCompilationCheck, | ||
| ), | ||
| }, | ||
| ); | ||
| } |
18 changes: 18 additions & 0 deletions
18
...b_benchmarks/testing/test_app/benchmark/test_infra/client/simple_initial_page_client.dart
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| // Copyright 2013 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 'package:web_benchmarks/client.dart'; | ||
|
|
||
| import '../common.dart'; | ||
| import '../recorder.dart'; | ||
|
|
||
| Future<void> main() async { | ||
| await runBenchmarks( | ||
| <String, RecorderFactory>{ | ||
| BenchmarkName.simpleInitialPageCheck.name: () => TestAppRecorder( | ||
| benchmark: BenchmarkName.simpleInitialPageCheck, | ||
| ), | ||
| }, | ||
| ); | ||
| } |
13 changes: 13 additions & 0 deletions
13
packages/web_benchmarks/testing/test_app/benchmark/test_infra/common.dart
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| // Copyright 2013 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. | ||
|
|
||
| const String testBenchmarkInitialPage = 'index.html#about'; | ||
|
|
||
| enum BenchmarkName { | ||
| appNavigate, | ||
| appScroll, | ||
| appTap, | ||
| simpleInitialPageCheck, | ||
| simpleCompilationCheck; | ||
| } |
38 changes: 38 additions & 0 deletions
38
packages/web_benchmarks/testing/test_app/benchmark/test_infra/recorder.dart
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| // Copyright 2013 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 'package:flutter/material.dart'; | ||
| import 'package:web_benchmarks/client.dart'; | ||
|
|
||
| import 'automator.dart'; | ||
| import 'common.dart'; | ||
|
|
||
| /// A recorder that measures frame building durations for the test app. | ||
| class TestAppRecorder extends WidgetRecorder { | ||
| TestAppRecorder({required this.benchmark}) | ||
| : super(name: benchmark.name, useCustomWarmUp: true); | ||
|
|
||
| /// The name of the benchmark to be run. | ||
| /// | ||
| /// See `common.dart` for the list of the names of all benchmarks. | ||
| final BenchmarkName benchmark; | ||
|
|
||
| Automater? _automator; | ||
| bool get _finished => _automator?.finished ?? false; | ||
|
|
||
| /// Whether we should continue recording. | ||
| @override | ||
| bool shouldContinue() => !_finished || profile.shouldContinue(); | ||
|
|
||
| /// Creates the [Automater] widget. | ||
| @override | ||
| Widget createWidget() { | ||
| _automator = Automater( | ||
| benchmark: benchmark, | ||
| stopWarmingUpCallback: profile.stopWarmingUp, | ||
| profile: profile, | ||
| ); | ||
| return _automator!.createWidget(); | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.