1. 07 Mar, 2024 2 commits
    • Bruno Leroux's avatar
      [flutter_test] Use defaultTargetPlatform for key events simulation (#143579) · 471a8285
      Bruno Leroux authored
      ## Description
      
      This PRs changes the default value for the `platform` parameter used to simulate key events.
      
      With this PR, the default value is "web" on web, otherwise it is the operating system name retrieved from `defaultTargetPlatform`.
      
      Previously, for methods in `WidgetController`, it defaulted to “web” on web, and “android” everywhere else. And for methods in `KeyEventSimulator` it defaulted to “web” on web, and the operating system that the test was running on everywhere else. Because the operating system was based on `Platform.operatingSystem`, it usually differed from the target platform the test was running on.
      
      AFAIK, the `platform` parameter is only meaningful for simulating `RawKeyEvent`. Once `RawKeyboard` will be fully removed, the `platform` parameter won’t be needed. 
      @gspencergoog  In the meantime, do you think it is worth merging this fix?
      
      ## Related Issue
      
      Fixes to https://github.com/flutter/flutter/issues/133955
      
      ## Tests
      
      Adds one test.
      471a8285
    • Bruno Leroux's avatar
      [flutter_test] Change KeyEventSimulator default transit mode (#143847) · 8ade81fb
      Bruno Leroux authored
      ## Description
      
      This PRs changes the default value transit mode for key event simulation.
      
      The default transit mode for key event simulation is currently `KeyDataTransitMode.rawKeyData` while on the framework side `KeyDataTransitMode.keyDataThenRawKeyData` is the preferred transit mode.
      
      `KeyDataTransitMode.keyDataThenRawKeyData` is more accurate and can help detect issues.
      
      For instance the following test will fail with `KeyDataTransitMode.rawKeyData` because raw keyboard logic for modifier keys is less accurate:
      
      ```dart
        testWidgets('Press control left once', (WidgetTester tester) async {
          debugKeyEventSimulatorTransitModeOverride = KeyDataTransitMode.keyDataThenRawKeyData;
      
          final List<KeyEvent> events = <KeyEvent>[];
          final FocusNode focusNode = FocusNode();
          addTearDown(focusNode.dispose);
      
          await tester.pumpWidget(
            Focus(
              focusNode: focusNode,
              autofocus: true,
              onKeyEvent: (_, KeyEvent event) {
                events.add(event);
                return KeyEventResult.handled;
              },
              child: Container(),
            ),
          );
      
          await simulateKeyDownEvent(LogicalKeyboardKey.controlLeft);
      
          // This will fail when transit mode is KeyDataTransitMode.rawKeyData
          // because a down event for controlRight is synthesized.
          expect(events.length, 1);
      
          debugKeyEventSimulatorTransitModeOverride = null;
        });
      ```
      
      And the following this test is ok with `KeyDataTransitMode.rawKeyData` but rightly fails with `KeyDataTransitMode.keyDataThenRawKeyData`:
      
      ```dart
        testWidgets('Simulates consecutive key down events', (WidgetTester tester) async {
          debugKeyEventSimulatorTransitModeOverride = KeyDataTransitMode.rawKeyData;
      
          // Simulating several key down events without key up in between is tolerated
          // when transit mode is KeyDataTransitMode.rawKeyData, it will trigger an
          // assert on KeyDataTransitMode.keyDataThenRawKeyData.
          await simulateKeyDownEvent(LogicalKeyboardKey.arrowDown);
          await simulateKeyDownEvent(LogicalKeyboardKey.arrowDown);
      
          debugKeyEventSimulatorTransitModeOverride = null;
        });
      ```
      
      ## Related Issue
      
      Related to https://github.com/flutter/flutter/issues/143845
      
      ## Tests
      
      Adds two tests.
      8ade81fb
  2. 04 Mar, 2024 1 commit
  3. 26 Feb, 2024 1 commit
  4. 23 Feb, 2024 1 commit
  5. 22 Feb, 2024 1 commit
    • Derek Xu's avatar
      Support using lightweight Flutter Engines to run tests (#141726) · dfb5888e
      Derek Xu authored
      This PR implements the functionality described above and hides it behind
      the `--experimental-faster-testing` flag of `flutter test`.
      
      ### The following are some performance measurements from test runs
      conducted on GitHub Actions
      
      run 1 logs:
      https://github.com/derekxu16/flutter_test_ci/actions/runs/8008029772/attempts/1
      run 2 logs:
      https://github.com/derekxu16/flutter_test_ci/actions/runs/8008029772/attempts/2
      run 3 logs:
      https://github.com/derekxu16/flutter_test_ci/actions/runs/8008029772/attempts/3
      
      **length of `flutter test --reporter=expanded test/animation
      test/foundation` step**
      
      run 1: 54s
      run 2: 52s
      run 3: 56s
      
      average: 54s
      
      **length of `flutter test --experimental-faster-testing
      --reporter=expanded test/animation test/foundation` step**
      
      run 1: 27s
      run 2: 27s
      run 3: 29s
      
      average: 27.67s (~48.77% shorter than 54s)
      
      **length of `flutter test --reporter=expanded test/animation
      test/foundation test/gestures test/painting test/physics test/rendering
      test/scheduler test/semantics test/services` step**
      
      run 1: 260s
      run 2: 270s
      run 3: 305s
      
      average: 278.33s
      
      
      **length of `flutter test --experimental-faster-testing
      --reporter=expanded test/animation test/foundation test/gestures
      test/painting test/physics test/rendering test/scheduler test/semantics
      test/services` step**
      
      from a clean build (right after deleting the build folder):
      
      run 1: 215s
      run 2: 227s
      run 3: 245s
      
      average: 229s (~17.72% shorter than 278.33s)
      
      Note that in reality, `test/material` was not passed to `flutter test`
      in the trials below. All of the test files under `test/material` except
      for `test/material/icons_test.dart` were listed out individually
      
      **length of `flutter test --reporter=expanded test/material` step**
      
      run 1: 408s
      run 2: 421s
      run 3: 451s
      
      average: 426.67s
      
      **length of `flutter test --experimental-faster-testing
      --reporter=expanded test/material` step**
      
      run 1: 382s
      run 2: 373s
      run 3: 400s
      
      average: 385s (~9.77% shorter than 426.67s)
      
      ---------
      Co-authored-by: 's avatarDan Field <dnfield@google.com>
      dfb5888e
  6. 16 Feb, 2024 1 commit
  7. 15 Feb, 2024 2 commits
  8. 14 Feb, 2024 2 commits
  9. 09 Feb, 2024 1 commit
    • Kris Pypen's avatar
      Fix: performance improvement on golden test comparison (#142913) · 2f117c54
      Kris Pypen authored
      During golden test image comparison 2 lists of a different type are compared with the method "identical", so this will never be true. The test image is a _Uint8ArrayView while the master image is an Uint8List. So that results in always a heavy computation to get the difference between the test and the master image.
      
      When you run this test snippet I go from 51 seconds to 14 seconds:
      ```dart
      import 'package:flutter/material.dart';
      import 'package:flutter_test/flutter_test.dart';
      
      void main() {
        for (int i = 0; i < 100; i++) {
          testWidgets('Small test', (WidgetTester tester) async {
            await tester.pumpWidget(Directionality(textDirection: TextDirection.ltr, child: Text('jo')));
            await expectLater(find.byType(Text), matchesGoldenFile('main.png'));
          });
        }
      }
      ```
      2f117c54
  10. 07 Feb, 2024 2 commits
  11. 30 Jan, 2024 1 commit
  12. 26 Jan, 2024 3 commits
    • Michael Goderbauer's avatar
      Relands "Add runWidget to bootstrap a widget tree without a default View" (#142344) · 671d8eaf
      Michael Goderbauer authored
      Reverts flutter/flutter#142339
      
      In the original change one of the tests included the same view twice which resulted in a different failure than the expected one. The second commit contains the fix for this. I don't understand how this wasn't caught presubmit on CI.
      671d8eaf
    • auto-submit[bot]'s avatar
      Reverts "Add runWidget to bootstrap a widget tree without a default View" (#142339) · 114261a6
      auto-submit[bot] authored
      Reverts flutter/flutter#141484
      Initiated by: eliasyishak
      This change reverts the following previous change:
      Original Description:
      The existing `runApp` bootstraps the widget tree and renders the provided widget into the default view (which is currently the implicit View from `PlatformDispatcher.implicitView` and - in the future - may be a default-created window). Apps, that want more control over the View they are rendered in, need a new way to bootstrap the widget tree: `runWidget`. It does not make any assumptions about the View the provided widget is rendered into. Instead, it is up to the caller to include a View widget in the provided widget tree that specifies where content should be rendered. In the future, this may enable developers to create a custom window for their app instead of relying on the default-created one.
      114261a6
    • Michael Goderbauer's avatar
      Add runWidget to bootstrap a widget tree without a default View (#141484) · 5b44596c
      Michael Goderbauer authored
      The existing `runApp` bootstraps the widget tree and renders the provided widget into the default view (which is currently the implicit View from `PlatformDispatcher.implicitView` and - in the future - may be a default-created window). Apps, that want more control over the View they are rendered in, need a new way to bootstrap the widget tree: `runWidget`. It does not make any assumptions about the View the provided widget is rendered into. Instead, it is up to the caller to include a View widget in the provided widget tree that specifies where content should be rendered. In the future, this may enable developers to create a custom window for their app instead of relying on the default-created one.
      5b44596c
  13. 19 Jan, 2024 2 commits
    • Michael Goderbauer's avatar
      Make pumpWidget's arguments named (#141728) · cc544169
      Michael Goderbauer authored
      Much nicer calling API and simplifies evolving this API in the future.
      
      I wish we could write a dart fix for this, but that's blocked on https://github.com/dart-lang/sdk/issues/54668.
      cc544169
    • fzyzcjy's avatar
      Tiny fix inaccurate documentations about bindings (#140282) · 9e024fdf
      fzyzcjy authored
      The old doc says that, AutomatedTestWidgetsFlutterBinding for `flutter test` and LiveTestWidgetsFlutterBinding for `flutter run`. However, suppose we `flutter test integration_test/simple_test.dart` with the following code:
      
      ```
      void main() {
        testWidgets('hi', (WidgetTester tester) async {
          print('hi ${TestWidgetsFlutterBinding.instance} ${Platform.operatingSystem}');
        });
      }
      ```
      
      We will see: `hi <IntegrationTestWidgetsFlutterBinding> ios`. Therefore, we see `IntegrationTestWidgetsFlutterBinding` is used in a `flutter test` command, which is contrary to the documentation.
      9e024fdf
  14. 16 Jan, 2024 1 commit
  15. 12 Jan, 2024 1 commit
  16. 09 Jan, 2024 1 commit
    • Michael Goderbauer's avatar
      Reapply "Dynamic view sizing" (#140165) (#140918) · 4534a24c
      Michael Goderbauer authored
      This reverts commit
      https://github.com/flutter/flutter/commit/d24c01bd0c41331bd17165e0173b24c5d05d7c0a.
      
      The original change was reverted because it caused some apps to get
      stuck on the splash screen on some phones.
      
      An investigation determined that this was due to a rounding error.
      Example: The device reports a physical size of 1008.0 x 2198.0 with a
      dpr of 1.912500023841858. Flutter would translate that to a logical size
      of 527.0588169589221 x 1149.2810314243163 and use that as the input for
      its layout algorithm. Since the constraints here are tight, the layout
      algorithm would determine that the resulting logical size of the root
      render object must be 527.0588169589221 x 1149.2810314243163.
      Translating this back to physical pixels by applying the dpr resulted in
      a physical size of 1007.9999999999999 x 2198.0 for the frame. Android
      now rejected that frame because it didn't match the expected size of
      1008.0 x 2198.0 and since no frame had been rendered would never take
      down the splash screen.
      
      Prior to dynamically sized views, this wasn't an issue because we would
      hard-code the frame size to whatever the requested size was.
      
      Changes in this PR over the original PR:
      
      * The issue has been fixed now by constraining the calculated physical
      size to the input physical constraints which makes sure that we always
      end up with a size that is acceptable to the operating system.
      * The `ViewConfiguration` was refactored to use the slightly more
      convenient `BoxConstraints` over the `ViewConstraints` to represent
      constraints. Both essentially represent the same thing, but
      `BoxConstraints` are more powerful and we avoid a couple of translations
      between the two by translating the` ViewConstraints` from the
      `FlutterView` to `BoxConstraints` directly when the `ViewConfiguration`
      is created.
      
      All changes over the original PR are contained in the second commit of
      this PR.
      
      Fixes b/316813075
      Part of https://github.com/flutter/flutter/issues/134501.
      4534a24c
  17. 04 Jan, 2024 1 commit
  18. 03 Jan, 2024 2 commits
  19. 21 Dec, 2023 2 commits
  20. 20 Dec, 2023 4 commits
    • Michael Goderbauer's avatar
      Remove outdated ignores from tool (#140467) · 68e346e4
      Michael Goderbauer authored
      These were not ignoring anything (anymore).
      68e346e4
    • LongCatIsLooong's avatar
      Reland `find.textRange.ofSubstring` changes (#140469) · e2e8bcb1
      LongCatIsLooong authored
      Extracted from https://github.com/flutter/flutter/pull/139717 as-is. Landing this change first so we can avoid doing a g3fix.
      e2e8bcb1
    • auto-submit[bot]'s avatar
      Reverts "Make `TextSpan` hit testing precise." (#140468) · 9003f138
      auto-submit[bot] authored
      Reverts flutter/flutter#139717
      Initiated by: LongCatIsLooong
      This change reverts the following previous change:
      Original Description:
      Fixes https://github.com/flutter/flutter/issues/131435, #104594, #43400
      Needs https://github.com/flutter/engine/pull/48774 (to fix the web test failure).
      
      Currently the method we use for text span hit testing `TextPainter.getPositionForOffset` always returns the closest `TextPosition`, even when the given offset is far away from the text. 
      
      The new TextPaintes method tells you the layout bounds (`width =  letterspacing / 2 + x_advance + letterspacing / 2`, `height = font ascent + font descent`) of a character, the PR changes the hit testing implementation such that a TextSpan is only considered hit if the point-down event landed in one of it's character's layout bounds.
      
      Potential issues:
      
      1. In theory since the text is baseline aligned, we should use the max ascent and max descent of each character to calculate the height of the text span's hit-test region, in case some characters in the span have to fall back to a different font, but that will be slower and it typically doesn't make a huge difference. 
      
      This is a breaking change. It also introduces a new finder and a new method `WidgetTester.tapOnText`: `await tester.tapOnText('string to match')` for ease of migration.
      9003f138
    • LongCatIsLooong's avatar
      Make `TextSpan` hit testing precise. (#139717) · ea5b9728
      LongCatIsLooong authored
      Fixes https://github.com/flutter/flutter/issues/131435, #104594, #43400
      Needs https://github.com/flutter/engine/pull/48774 (to fix the web test failure).
      
      Currently the method we use for text span hit testing `TextPainter.getPositionForOffset` always returns the closest `TextPosition`, even when the given offset is far away from the text. 
      
      The new TextPaintes method tells you the layout bounds (`width =  letterspacing / 2 + x_advance + letterspacing / 2`, `height = font ascent + font descent`) of a character, the PR changes the hit testing implementation such that a TextSpan is only considered hit if the point-down event landed in one of it's character's layout bounds.
      
      Potential issues:
      
      1. In theory since the text is baseline aligned, we should use the max ascent and max descent of each character to calculate the height of the text span's hit-test region, in case some characters in the span have to fall back to a different font, but that will be slower and it typically doesn't make a huge difference. 
      
      This is a breaking change. It also introduces a new finder and a new method `WidgetTester.tapOnText`: `await tester.tapOnText('string to match')` for ease of migration.
      ea5b9728
  21. 14 Dec, 2023 1 commit
  22. 11 Dec, 2023 3 commits
  23. 29 Nov, 2023 3 commits
  24. 27 Nov, 2023 1 commit