@@ -926,6 +926,7 @@ void main() {
926926 ),
927927 ),
928928 );
929+
929930 final RenderParagraph paragraph2 = tester.renderObject <RenderParagraph >(find.descendant (of: find.text ('Good, and you?' ), matching: find.byType (RichText )));
930931 final TestGesture gesture = await tester.startGesture (textOffsetToPosition (paragraph2, 7 )); // at the 'a'
931932 addTearDown (gesture.removePointer);
@@ -1708,6 +1709,115 @@ void main() {
17081709 variant: const TargetPlatformVariant (< TargetPlatform > { TargetPlatform .iOS, TargetPlatform .android }),
17091710 );
17101711
1712+ testWidgets ('the selection behavior when clicking `Copy` item in mobile platforms' , (WidgetTester tester) async {
1713+ List <ContextMenuButtonItem > buttonItems = < ContextMenuButtonItem > [];
1714+ await tester.pumpWidget (
1715+ MaterialApp (
1716+ home: SelectableRegion (
1717+ focusNode: FocusNode (),
1718+ selectionControls: materialTextSelectionHandleControls,
1719+ contextMenuBuilder: (
1720+ BuildContext context,
1721+ SelectableRegionState selectableRegionState,
1722+ ) {
1723+ buttonItems = selectableRegionState.contextMenuButtonItems;
1724+ return const SizedBox .shrink ();
1725+ },
1726+ child: const Text ('How are you?' ),
1727+ ),
1728+ ),
1729+ );
1730+
1731+ final RenderParagraph paragraph1 = tester.renderObject <RenderParagraph >(find.descendant (of: find.text ('How are you?' ), matching: find.byType (RichText )));
1732+ await tester.longPressAt (textOffsetToPosition (paragraph1, 6 )); // at the 'r'
1733+ await tester.pump (kLongPressTimeout);
1734+ // `are` is selected.
1735+ expect (paragraph1.selections[0 ], const TextSelection (baseOffset: 4 , extentOffset: 7 ));
1736+
1737+ expect (buttonItems.length, 2 );
1738+ expect (buttonItems[0 ].type, ContextMenuButtonType .copy);
1739+
1740+ // Press `Copy` item
1741+ buttonItems[0 ].onPressed.call ();
1742+
1743+ final SelectableRegionState regionState = tester.state <SelectableRegionState >(find.byType (SelectableRegion ));
1744+
1745+ // In Android copy should clear the selection.
1746+ switch (defaultTargetPlatform) {
1747+ case TargetPlatform .android:
1748+ case TargetPlatform .fuchsia:
1749+ expect (regionState.selectionOverlay, isNull);
1750+ expect (regionState.selectionOverlay? .startHandleLayerLink, isNull);
1751+ expect (regionState.selectionOverlay? .endHandleLayerLink, isNull);
1752+ break ;
1753+ case TargetPlatform .iOS:
1754+ expect (regionState.selectionOverlay, isNotNull);
1755+ expect (regionState.selectionOverlay? .startHandleLayerLink, isNotNull);
1756+ expect (regionState.selectionOverlay? .endHandleLayerLink, isNotNull);
1757+ break ;
1758+ case TargetPlatform .linux:
1759+ case TargetPlatform .macOS:
1760+ case TargetPlatform .windows:
1761+ expect (regionState.selectionOverlay, isNotNull);
1762+ break ;
1763+ }
1764+ },
1765+ skip: kIsWeb, // [intended]
1766+ );
1767+
1768+ testWidgets ('the handles do not disappear when clicking `Select all` item in mobile platforms' , (WidgetTester tester) async {
1769+ List <ContextMenuButtonItem > buttonItems = < ContextMenuButtonItem > [];
1770+ await tester.pumpWidget (
1771+ MaterialApp (
1772+ home: SelectableRegion (
1773+ focusNode: FocusNode (),
1774+ selectionControls: materialTextSelectionHandleControls,
1775+ contextMenuBuilder: (
1776+ BuildContext context,
1777+ SelectableRegionState selectableRegionState,
1778+ ) {
1779+ buttonItems = selectableRegionState.contextMenuButtonItems;
1780+ return const SizedBox .shrink ();
1781+ },
1782+ child: const Text ('How are you?' ),
1783+ ),
1784+ ),
1785+ );
1786+
1787+ final RenderParagraph paragraph1 = tester.renderObject <RenderParagraph >(find.descendant (of: find.text ('How are you?' ), matching: find.byType (RichText )));
1788+ await tester.longPressAt (textOffsetToPosition (paragraph1, 6 )); // at the 'r'
1789+ await tester.pump (kLongPressTimeout);
1790+ // `are` is selected.
1791+ expect (paragraph1.selections[0 ], const TextSelection (baseOffset: 4 , extentOffset: 7 ));
1792+
1793+ expect (buttonItems.length, 2 );
1794+ expect (buttonItems[1 ].type, ContextMenuButtonType .selectAll);
1795+
1796+ // Press `Select All` item
1797+ buttonItems[1 ].onPressed.call ();
1798+
1799+ final SelectableRegionState regionState = tester.state <SelectableRegionState >(find.byType (SelectableRegion ));
1800+
1801+ switch (defaultTargetPlatform) {
1802+ case TargetPlatform .android:
1803+ case TargetPlatform .iOS:
1804+ case TargetPlatform .fuchsia:
1805+ expect (regionState.selectionOverlay, isNotNull);
1806+ expect (regionState.selectionOverlay? .startHandleLayerLink, isNotNull);
1807+ expect (regionState.selectionOverlay? .endHandleLayerLink, isNotNull);
1808+ break ;
1809+ case TargetPlatform .linux:
1810+ case TargetPlatform .macOS:
1811+ case TargetPlatform .windows:
1812+ // Test doesn't run these platforms.
1813+ break ;
1814+ }
1815+
1816+ },
1817+ skip: kIsWeb, // [intended]
1818+ variant: const TargetPlatformVariant (< TargetPlatform > { TargetPlatform .iOS, TargetPlatform .android, TargetPlatform .fuchsia }),
1819+ );
1820+
17111821 testWidgets ('builds the correct button items' , (WidgetTester tester) async {
17121822 Set <ContextMenuButtonType > buttonTypes = < ContextMenuButtonType > {};
17131823 await tester.pumpWidget (
0 commit comments