[cupertino_ui] Re-enable action_sheet_test.dart#12055
Conversation
The only use of TestSemantics in cupertino_ui. I refactored it to use the preferred tester.find.semantics instead.
There was a problem hiding this comment.
Code Review
This pull request removes the skip annotation from action_sheet_test.dart and refactors the 'Action sheet semantics' test to use tester.semantics.find and isSemantics instead of SemanticsTester. Feedback on the changes suggests restoring assertions for semantics actions (SemanticsAction.tap and SemanticsAction.focus) that were lost during the refactoring, and reusing sheetFinder to avoid redundant lookups.
| final Finder sheetFinder = find.bySemanticsLabel('Alert'); | ||
| final SemanticsNode sheet = tester.semantics.find(find.bySemanticsLabel('Alert')); | ||
| expect(sheet.role, SemanticsRole.dialog); | ||
| expect(sheet, isSemantics(label: 'Alert', namesRoute: true, scopesRoute: true)); | ||
| expect( | ||
| semantics, | ||
| hasSemantics( | ||
| TestSemantics.root( | ||
| children: <TestSemantics>[ | ||
| TestSemantics( | ||
| children: <TestSemantics>[ | ||
| TestSemantics( | ||
| children: <TestSemantics>[ | ||
| TestSemantics( | ||
| flags: <SemanticsFlag>[SemanticsFlag.scopesRoute, SemanticsFlag.namesRoute], | ||
| label: 'Alert', | ||
| role: SemanticsRole.dialog, | ||
| children: <TestSemantics>[ | ||
| TestSemantics( | ||
| flags: <SemanticsFlag>[SemanticsFlag.hasImplicitScrolling], | ||
| children: <TestSemantics>[ | ||
| TestSemantics(label: 'The title'), | ||
| TestSemantics(label: 'The message'), | ||
| ], | ||
| ), | ||
| TestSemantics( | ||
| flags: <SemanticsFlag>[SemanticsFlag.hasImplicitScrolling], | ||
| children: <TestSemantics>[ | ||
| TestSemantics( | ||
| flags: <SemanticsFlag>[ | ||
| SemanticsFlag.isButton, | ||
| SemanticsFlag.isFocusable, | ||
| ], | ||
| actions: <SemanticsAction>[ | ||
| SemanticsAction.tap, | ||
| SemanticsAction.focus, | ||
| ], | ||
| label: 'One', | ||
| ), | ||
| TestSemantics( | ||
| flags: <SemanticsFlag>[ | ||
| SemanticsFlag.isButton, | ||
| SemanticsFlag.isFocusable, | ||
| ], | ||
| actions: <SemanticsAction>[ | ||
| SemanticsAction.tap, | ||
| SemanticsAction.focus, | ||
| ], | ||
| label: 'Two', | ||
| ), | ||
| ], | ||
| ), | ||
| TestSemantics( | ||
| flags: <SemanticsFlag>[SemanticsFlag.isButton, SemanticsFlag.isFocusable], | ||
| actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus], | ||
| label: 'Cancel', | ||
| ), | ||
| ], | ||
| ), | ||
| ], | ||
| ), | ||
| ], | ||
| ), | ||
| ], | ||
| ), | ||
| ignoreId: true, | ||
| ignoreRect: true, | ||
| ignoreTransform: true, | ||
| ), | ||
| find.descendant(of: sheetFinder, matching: find.bySemanticsLabel('The title')), | ||
| findsOneWidget, | ||
| ); | ||
|
|
||
| semantics.dispose(); | ||
| expect( | ||
| find.descendant(of: sheetFinder, matching: find.bySemanticsLabel('The message')), | ||
| findsOneWidget, | ||
| ); | ||
| final SemanticsNode buttonOne = tester.semantics.find( | ||
| find.descendant(of: sheetFinder, matching: find.bySemanticsLabel('One')), | ||
| ); | ||
| expect(buttonOne, isSemantics(isButton: true, isFocusable: true)); | ||
| final SemanticsNode buttonTwo = tester.semantics.find( | ||
| find.descendant(of: sheetFinder, matching: find.bySemanticsLabel('Two')), | ||
| ); | ||
| expect(buttonTwo, isSemantics(isButton: true, isFocusable: true)); | ||
| final SemanticsNode buttonCancel = tester.semantics.find( | ||
| find.descendant(of: sheetFinder, matching: find.bySemanticsLabel('Cancel')), | ||
| ); | ||
| expect(buttonCancel, isSemantics(isButton: true, isFocusable: true)); |
There was a problem hiding this comment.
The original test verified that the buttons ('One', 'Two', and 'Cancel') had specific semantics actions associated with them (SemanticsAction.tap and SemanticsAction.focus). The migrated test currently only asserts isButton and isFocusable, which reduces the test coverage.
We should restore these assertions using the actions parameter of isSemantics to ensure we don't lose coverage for accessibility actions. Additionally, we can reuse sheetFinder instead of calling find.bySemanticsLabel('Alert') twice.
final Finder sheetFinder = find.bySemanticsLabel('Alert');
final SemanticsNode sheet = tester.semantics.find(sheetFinder);
expect(sheet.role, SemanticsRole.dialog);
expect(sheet, isSemantics(label: 'Alert', namesRoute: true, scopesRoute: true));
expect(
find.descendant(of: sheetFinder, matching: find.bySemanticsLabel('The title')),
findsOneWidget,
);
expect(
find.descendant(of: sheetFinder, matching: find.bySemanticsLabel('The message')),
findsOneWidget,
);
final SemanticsNode buttonOne = tester.semantics.find(
find.descendant(of: sheetFinder, matching: find.bySemanticsLabel('One')),
);
expect(
buttonOne,
isSemantics(
label: 'One',
isButton: true,
isFocusable: true,
actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
),
);
final SemanticsNode buttonTwo = tester.semantics.find(
find.descendant(of: sheetFinder, matching: find.bySemanticsLabel('Two')),
);
expect(
buttonTwo,
isSemantics(
label: 'Two',
isButton: true,
isFocusable: true,
actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
),
);
final SemanticsNode buttonCancel = tester.semantics.find(
find.descendant(of: sheetFinder, matching: find.bySemanticsLabel('Cancel')),
);
expect(
buttonCancel,
isSemantics(
label: 'Cancel',
isButton: true,
isFocusable: true,
actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
),
);There was a problem hiding this comment.
This appears to be a hallucination; isSemantics has no actions parameter.
I'm speculating that isButton is enough and we don't need to verify the actions, but I'm looking for input from @chunhtai.
There was a problem hiding this comment.
I think isSemantics has hasTapAction and hasFocusAction that we can leverage.
| ], | ||
| ), | ||
| TestSemantics( | ||
| flags: <SemanticsFlag>[SemanticsFlag.hasImplicitScrolling], |
There was a problem hiding this comment.
I wonder if we should still capture SemanticsFlag.hasImplicitScrolling . And how much of the actual semantics tree shape we want to verify. This test was very strict with regards to the shape of the tree, do we still want to keep it strict?
There was a problem hiding this comment.
I'm planning to defer to @chunhtai on this.
I originally thought the hasImplicitScrolling was irrelevant, but maybe you do want to verify that the semantics tree is aware of the scrolling... Maybe we should be verifying everything from the "label: 'Alert'" level and below?
There was a problem hiding this comment.
Maybe we should be verifying everything from the "label: 'Alert'" level and below?
yes I think so
There was a problem hiding this comment.
@chunhtai I've now updated it to test the whole tree, similar to before except with isSemantics instead of TestSemantics. Is that what you had in mind? Some questions:
- It seems like it's not possible to test the
roleinside of isSemantics. Is there a better way to do that or do we need to add it to isSemantics? - The error messages are not very good. If I forget a child in
children, the error message istype 'Null' is not a subtype of type 'String' in type cast.
Should I instead do a flat list of expects like in the original commit fe965a5? Or is there a better way here?
There was a problem hiding this comment.
I have been testing role using:
tester.getSemantics(find.byType(CupertinoSlidingSegmentedControl<int>)).role,
SemanticsRole.radioGroup,
);There was a problem hiding this comment.
It seems like it's not possible to test the role inside of isSemantics. Is there a better way to do that or do we need to add it to isSemantics?
right we should make sure it support role
The error messages are not very good. If I forget a child in children, the error message is type 'Null' is not a subtype of type 'String' in type cast.
we should improve the error message
There was a problem hiding this comment.
pr to improve child mismatch flutter/flutter#188827
| @@ -1727,8 +1722,6 @@ void main() { | |||
| }, skip: isBrowser); // https://github.com/flutter/flutter/issues/56001 | |||
|
|
|||
| testWidgets('Action sheet semantics', (WidgetTester tester) async { | |||
| final semantics = SemanticsTester(tester); | |||
There was a problem hiding this comment.
Should we use SemanticsHandle to ensure semantics is initialized like below (plus dispose at the end of the test)? I'm not sure how necessary this is but I've been doing it in the migrations I've done.
final SemanticsHandle handle = tester.ensureSemantics();There was a problem hiding this comment.
semantics is enabled by default for testwidget now, so you don't need to initialize the handle in test.
…er#188916) flutter/packages@e742106...420e135 2026-07-02 dkwingsmt@users.noreply.github.com [material_ui] Migrate api sample code to @example dartdoc directive (flutter/packages#12078) 2026-07-02 dkwingsmt@users.noreply.github.com [material_ui] Move over more API samples (flutter/packages#12092) 2026-07-01 katelovett@google.com [cupertino_ui] Migrate api sample code to @example dartdoc directive (flutter/packages#12063) 2026-07-01 katelovett@google.com [cupertino_ui] Move over more API samples (flutter/packages#12086) 2026-07-01 48776784+mackings@users.noreply.github.com [two_dimensional_scrollables] Fix TreeView horizontal hit testing (flutter/packages#11859) 2026-07-01 1063596+reidbaker@users.noreply.github.com [camera_android_camerax][tool] Integrate dart_code_linter for cyclomatic complexity checks (flutter/packages#11999) 2026-07-01 dinurymomshad.dev@gmail.com [cross_file] Add runnable example with main() (flutter/packages#11527) 2026-07-01 36861262+QuncCccccc@users.noreply.github.com [cupertino_ui] Enable `switch_test.dart` (flutter/packages#12076) 2026-07-01 jmccandless@google.com [cupertino_ui] Re-enable dialog_test.dart (flutter/packages#12057) 2026-07-01 jmccandless@google.com [cupertino_ui] Re-enable action_sheet_test.dart (flutter/packages#12055) 2026-07-01 rmolivares@renzo-olivares.dev [cupertino_ui] Migrate `bottom_tab_bar_test.dart` to `SemanticsHandle` (flutter/packages#12012) 2026-07-01 1063596+reidbaker@users.noreply.github.com [repo] Add comment style guideline to AGENTS.md (flutter/packages#12077) 2026-07-01 43054281+camsim99@users.noreply.github.com Adds pre-push readiness skill (flutter/packages#11935) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages-flutter-autoroll Please CC flutter-ecosystem@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
This file used TestSemantics from the Widgets library in flutter/flutter. This approach to semantics testing is not advised, as explained in flutter/flutter#184367. I migrated to the recommended tester.semantics.find.