mirror of
https://github.com/alibaba/flutter-go.git
synced 2025-07-09 12:11:30 +08:00
322 lines
10 KiB
Dart
322 lines
10 KiB
Dart
// Copyright 2016 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
// Synced. * Contains Web DELTA *
|
|
|
|
import 'package:flutter_web/material.dart';
|
|
import 'package:flutter_web/rendering.dart';
|
|
import 'package:flutter_web_test/flutter_web_test.dart';
|
|
import 'package:flutter_web/gestures.dart';
|
|
|
|
import '../rendering/mock_canvas.dart';
|
|
import '../widgets/semantics_tester.dart';
|
|
import 'feedback_tester.dart';
|
|
|
|
void main() {
|
|
testWidgets('InkWell gestures control test', (WidgetTester tester) async {
|
|
final List<String> log = <String>[];
|
|
|
|
await tester.pumpWidget(Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Material(
|
|
child: Center(
|
|
child: InkWell(
|
|
onTap: () {
|
|
log.add('tap');
|
|
},
|
|
onDoubleTap: () {
|
|
log.add('double-tap');
|
|
},
|
|
onLongPress: () {
|
|
log.add('long-press');
|
|
},
|
|
onTapDown: (TapDownDetails details) {
|
|
log.add('tap-down');
|
|
},
|
|
onTapCancel: () {
|
|
log.add('tap-cancel');
|
|
},
|
|
),
|
|
),
|
|
),
|
|
));
|
|
|
|
await tester.tap(find.byType(InkWell), pointer: 1);
|
|
|
|
expect(log, isEmpty);
|
|
|
|
await tester.pump(const Duration(seconds: 1));
|
|
|
|
expect(log, equals(<String>['tap-down', 'tap']));
|
|
log.clear();
|
|
|
|
await tester.tap(find.byType(InkWell), pointer: 2);
|
|
await tester.pump(const Duration(milliseconds: 100));
|
|
await tester.tap(find.byType(InkWell), pointer: 3);
|
|
|
|
expect(log, equals(<String>['double-tap']));
|
|
log.clear();
|
|
|
|
await tester.longPress(find.byType(InkWell), pointer: 4);
|
|
|
|
expect(log, equals(<String>['tap-down', 'tap-cancel', 'long-press']));
|
|
|
|
log.clear();
|
|
TestGesture gesture =
|
|
await tester.startGesture(tester.getRect(find.byType(InkWell)).center);
|
|
await tester.pump(const Duration(milliseconds: 100));
|
|
expect(log, equals(<String>['tap-down']));
|
|
await gesture.up();
|
|
await tester.pump(const Duration(seconds: 1));
|
|
|
|
log.clear();
|
|
gesture =
|
|
await tester.startGesture(tester.getRect(find.byType(InkWell)).center);
|
|
await tester.pump(const Duration(milliseconds: 100));
|
|
await gesture.moveBy(const Offset(0.0, 200.0));
|
|
await gesture.cancel();
|
|
expect(log, equals(<String>['tap-down', 'tap-cancel']));
|
|
});
|
|
|
|
testWidgets('long-press and tap on disabled should not throw',
|
|
(WidgetTester tester) async {
|
|
await tester.pumpWidget(const Material(
|
|
child: Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Center(
|
|
child: InkWell(),
|
|
),
|
|
),
|
|
));
|
|
await tester.tap(find.byType(InkWell), pointer: 1);
|
|
await tester.pump(const Duration(seconds: 1));
|
|
await tester.longPress(find.byType(InkWell), pointer: 1);
|
|
await tester.pump(const Duration(seconds: 1));
|
|
});
|
|
|
|
testWidgets('ink well changes color on hover', (WidgetTester tester) async {
|
|
await tester.pumpWidget(Material(
|
|
child: Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Center(
|
|
child: Container(
|
|
width: 100,
|
|
height: 100,
|
|
child: InkWell(
|
|
hoverColor: const Color(0xff00ff00),
|
|
splashColor: const Color(0xffff0000),
|
|
focusColor: const Color(0xff0000ff),
|
|
highlightColor: const Color(0xf00fffff),
|
|
onTap: () {},
|
|
onLongPress: () {},
|
|
onHover: (bool hover) {}),
|
|
),
|
|
),
|
|
),
|
|
));
|
|
final TestGesture gesture =
|
|
await tester.createGesture(kind: PointerDeviceKind.mouse);
|
|
await gesture.addPointer();
|
|
await gesture.moveTo(tester.getCenter(find.byType(Container)));
|
|
await tester.pumpAndSettle();
|
|
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere(
|
|
(RenderObject object) =>
|
|
object.runtimeType.toString() == '_RenderInkFeatures');
|
|
expect(
|
|
inkFeatures,
|
|
paints
|
|
..rect(
|
|
rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
|
|
color: const Color(0xff00ff00)));
|
|
|
|
await gesture.removePointer();
|
|
}, skip: true); // TODO(flutter_web): re-enable.
|
|
|
|
testWidgets('ink response changes color on focus',
|
|
(WidgetTester tester) async {
|
|
final FocusNode focusNode = FocusNode(debugLabel: 'Ink Focus');
|
|
await tester.pumpWidget(Material(
|
|
child: Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Center(
|
|
child: Focus(
|
|
focusNode: focusNode,
|
|
child: Container(
|
|
width: 100,
|
|
height: 100,
|
|
child: InkWell(
|
|
hoverColor: const Color(0xff00ff00),
|
|
splashColor: const Color(0xffff0000),
|
|
focusColor: const Color(0xff0000ff),
|
|
highlightColor: const Color(0xf00fffff),
|
|
onTap: () {},
|
|
onLongPress: () {},
|
|
onHover: (bool hover) {}),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
));
|
|
await tester.pumpAndSettle();
|
|
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere(
|
|
(RenderObject object) =>
|
|
object.runtimeType.toString() == '_RenderInkFeatures');
|
|
expect(inkFeatures, paintsExactlyCountTimes(#rect, 0));
|
|
focusNode.requestFocus();
|
|
await tester.pumpAndSettle();
|
|
expect(
|
|
inkFeatures,
|
|
paints
|
|
..rect(
|
|
rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
|
|
color: const Color(0xff0000ff)));
|
|
});
|
|
|
|
group('feedback', () {
|
|
FeedbackTester feedback;
|
|
|
|
setUp(() {
|
|
feedback = FeedbackTester();
|
|
});
|
|
|
|
tearDown(() {
|
|
feedback?.dispose();
|
|
});
|
|
|
|
testWidgets('enabled (default)', (WidgetTester tester) async {
|
|
await tester.pumpWidget(Material(
|
|
child: Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Center(
|
|
child: InkWell(
|
|
onTap: () {},
|
|
onLongPress: () {},
|
|
),
|
|
),
|
|
),
|
|
));
|
|
await tester.tap(find.byType(InkWell), pointer: 1);
|
|
await tester.pump(const Duration(seconds: 1));
|
|
expect(feedback.clickSoundCount, 1);
|
|
expect(feedback.hapticCount, 0);
|
|
|
|
await tester.tap(find.byType(InkWell), pointer: 1);
|
|
await tester.pump(const Duration(seconds: 1));
|
|
expect(feedback.clickSoundCount, 2);
|
|
expect(feedback.hapticCount, 0);
|
|
|
|
await tester.longPress(find.byType(InkWell), pointer: 1);
|
|
await tester.pump(const Duration(seconds: 1));
|
|
expect(feedback.clickSoundCount, 2);
|
|
expect(feedback.hapticCount, 1);
|
|
});
|
|
|
|
testWidgets('disabled', (WidgetTester tester) async {
|
|
await tester.pumpWidget(Material(
|
|
child: Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Center(
|
|
child: InkWell(
|
|
onTap: () {},
|
|
onLongPress: () {},
|
|
enableFeedback: false,
|
|
),
|
|
),
|
|
),
|
|
));
|
|
await tester.tap(find.byType(InkWell), pointer: 1);
|
|
await tester.pump(const Duration(seconds: 1));
|
|
expect(feedback.clickSoundCount, 0);
|
|
expect(feedback.hapticCount, 0);
|
|
|
|
await tester.longPress(find.byType(InkWell), pointer: 1);
|
|
await tester.pump(const Duration(seconds: 1));
|
|
expect(feedback.clickSoundCount, 0);
|
|
expect(feedback.hapticCount, 0);
|
|
});
|
|
});
|
|
|
|
testWidgets('splashing survives scrolling when keep-alive is enabled',
|
|
(WidgetTester tester) async {
|
|
Future<void> runTest(bool keepAlive) async {
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Material(
|
|
child: CompositedTransformFollower(
|
|
// forces a layer, which makes the paints easier to separate out
|
|
link: LayerLink(),
|
|
child: ListView(
|
|
addAutomaticKeepAlives: keepAlive,
|
|
dragStartBehavior: DragStartBehavior.down,
|
|
children: <Widget>[
|
|
Container(
|
|
height: 500.0,
|
|
child: InkWell(onTap: () {}, child: const Placeholder())),
|
|
Container(height: 500.0),
|
|
Container(height: 500.0),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
expect(
|
|
tester.renderObject<RenderProxyBox>(find.byType(PhysicalModel)).child,
|
|
isNot(paints..circle()));
|
|
await tester.tap(find.byType(InkWell));
|
|
await tester.pump();
|
|
await tester.pump(const Duration(milliseconds: 10));
|
|
expect(
|
|
tester.renderObject<RenderProxyBox>(find.byType(PhysicalModel)).child,
|
|
paints..circle());
|
|
await tester.drag(find.byType(ListView), const Offset(0.0, -1000.0));
|
|
await tester.pump(const Duration(milliseconds: 10));
|
|
await tester.drag(find.byType(ListView), const Offset(0.0, 1000.0));
|
|
await tester.pump(const Duration(milliseconds: 10));
|
|
expect(
|
|
tester.renderObject<RenderProxyBox>(find.byType(PhysicalModel)).child,
|
|
keepAlive ? (paints..circle()) : isNot(paints..circle()),
|
|
);
|
|
}
|
|
|
|
await runTest(true);
|
|
await runTest(false);
|
|
});
|
|
|
|
testWidgets('excludeFromSemantics', (WidgetTester tester) async {
|
|
final SemanticsTester semantics = SemanticsTester(tester);
|
|
|
|
await tester.pumpWidget(Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Material(
|
|
child: InkWell(
|
|
onTap: () {},
|
|
child: const Text('Button'),
|
|
),
|
|
),
|
|
));
|
|
expect(
|
|
semantics,
|
|
includesNodeWith(
|
|
label: 'Button', actions: <SemanticsAction>[SemanticsAction.tap]));
|
|
|
|
await tester.pumpWidget(Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Material(
|
|
child: InkWell(
|
|
onTap: () {},
|
|
child: const Text('Button'),
|
|
excludeFromSemantics: true,
|
|
),
|
|
),
|
|
));
|
|
expect(
|
|
semantics,
|
|
isNot(includesNodeWith(
|
|
label: 'Button', actions: <SemanticsAction>[SemanticsAction.tap])));
|
|
|
|
semantics.dispose();
|
|
});
|
|
}
|