| // Copyright 2015 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. |
| |
| import 'package:flutter/material.dart'; |
| import 'package:flutter/widgets.dart'; |
| import 'package:flutter/rendering.dart'; |
| import 'package:flutter_test/flutter_test.dart'; |
| |
| void main() { |
| testWidgets('SemanticsDebugger smoke test', (WidgetTester tester) async { |
| |
| // This is a smoketest to verify that adding a debugger doesn't crash. |
| await tester.pumpWidget( |
| new Directionality( |
| textDirection: TextDirection.ltr, |
| child: new Stack( |
| children: <Widget>[ |
| new Semantics(), |
| new Semantics( |
| container: true, |
| ), |
| new Semantics( |
| label: 'label', |
| textDirection: TextDirection.ltr, |
| ), |
| ], |
| ), |
| ), |
| ); |
| |
| await tester.pumpWidget( |
| new Directionality( |
| textDirection: TextDirection.ltr, |
| child: new SemanticsDebugger( |
| child: new Stack( |
| children: <Widget>[ |
| new Semantics(), |
| new Semantics( |
| container: true, |
| ), |
| new Semantics( |
| label: 'label', |
| textDirection: TextDirection.ltr, |
| ), |
| ], |
| ), |
| ), |
| ), |
| ); |
| |
| expect(true, isTrue); // expect that we reach here without crashing |
| }); |
| |
| testWidgets('SemanticsDebugger reparents subtree', |
| (WidgetTester tester) async { |
| final GlobalKey key = new GlobalKey(); |
| |
| await tester.pumpWidget( |
| new Directionality( |
| textDirection: TextDirection.ltr, |
| child: new SemanticsDebugger( |
| child: new Stack( |
| children: <Widget>[ |
| new Semantics(label: 'label1', textDirection: TextDirection.ltr), |
| new Positioned( |
| key: key, |
| left: 0.0, |
| top: 0.0, |
| width: 100.0, |
| height: 100.0, |
| child: new Semantics(label: 'label2', textDirection: TextDirection.ltr), |
| ), |
| ], |
| ), |
| ), |
| ), |
| ); |
| |
| await tester.pumpWidget( |
| new Directionality( |
| textDirection: TextDirection.ltr, |
| child: new SemanticsDebugger( |
| child: new Stack( |
| children: <Widget>[ |
| new Semantics(label: 'label1', textDirection: TextDirection.ltr), |
| new Semantics( |
| container: true, |
| child: new Stack( |
| children: <Widget>[ |
| new Positioned( |
| key: key, |
| left: 0.0, |
| top: 0.0, |
| width: 100.0, |
| height: 100.0, |
| child: new Semantics(label: 'label2', textDirection: TextDirection.ltr), |
| ), |
| new Semantics(label: 'label3', textDirection: TextDirection.ltr), |
| ], |
| ), |
| ), |
| ], |
| ), |
| ), |
| ), |
| ); |
| |
| await tester.pumpWidget( |
| new Directionality( |
| textDirection: TextDirection.ltr, |
| child: new SemanticsDebugger( |
| child: new Stack( |
| children: <Widget>[ |
| new Semantics(label: 'label1', textDirection: TextDirection.ltr), |
| new Semantics( |
| container: true, |
| child: new Stack( |
| children: <Widget>[ |
| new Positioned( |
| key: key, |
| left: 0.0, |
| top: 0.0, |
| width: 100.0, |
| height: 100.0, |
| child: new Semantics(label: 'label2', textDirection: TextDirection.ltr)), |
| new Semantics(label: 'label3', textDirection: TextDirection.ltr), |
| new Semantics(label: 'label4', textDirection: TextDirection.ltr), |
| ], |
| ), |
| ), |
| ], |
| ), |
| ), |
| ), |
| ); |
| |
| expect(tester.takeException(), isNull); |
| }); |
| |
| testWidgets('SemanticsDebugger interaction test', |
| (WidgetTester tester) async { |
| final List<String> log = <String>[]; |
| |
| await tester.pumpWidget( |
| new Directionality( |
| textDirection: TextDirection.ltr, |
| child: new SemanticsDebugger( |
| child: new Material( |
| child: new ListView( |
| children: <Widget>[ |
| new RaisedButton( |
| onPressed: () { |
| log.add('top'); |
| }, |
| child: const Text('TOP'), |
| ), |
| new RaisedButton( |
| onPressed: () { |
| log.add('bottom'); |
| }, |
| child: const Text('BOTTOM'), |
| ), |
| ], |
| ), |
| ), |
| ), |
| ), |
| ); |
| |
| await tester.tap(find.text('TOP')); |
| expect(log, equals(<String>['top'])); |
| log.clear(); |
| |
| await tester.tap(find.text('BOTTOM')); |
| expect(log, equals(<String>['bottom'])); |
| log.clear(); |
| }); |
| |
| testWidgets('SemanticsDebugger interaction test - negative', |
| (WidgetTester tester) async { |
| final List<String> log = <String>[]; |
| |
| await tester.pumpWidget( |
| new Directionality( |
| textDirection: TextDirection.ltr, |
| child: new SemanticsDebugger( |
| child: new Material( |
| child: new ListView( |
| children: <Widget>[ |
| new RaisedButton( |
| onPressed: () { |
| log.add('top'); |
| }, |
| child: const Text('TOP', textDirection: TextDirection.ltr), |
| ), |
| new ExcludeSemantics( |
| child: new RaisedButton( |
| onPressed: () { |
| log.add('bottom'); |
| }, |
| child: const Text('BOTTOM', textDirection: TextDirection.ltr), |
| ), |
| ), |
| ], |
| ), |
| ), |
| ), |
| ), |
| ); |
| |
| await tester.tap(find.text('TOP')); |
| expect(log, equals(<String>['top'])); |
| log.clear(); |
| |
| await tester.tap(find.text('BOTTOM')); |
| expect(log, equals(<String>[])); |
| log.clear(); |
| }); |
| |
| testWidgets('SemanticsDebugger scroll test', (WidgetTester tester) async { |
| final Key childKey = new UniqueKey(); |
| |
| await tester.pumpWidget( |
| new Directionality( |
| textDirection: TextDirection.ltr, |
| child: new SemanticsDebugger( |
| child: new ListView( |
| children: <Widget>[ |
| new Container( |
| key: childKey, |
| height: 5000.0, |
| color: Colors.green[500], |
| ), |
| ], |
| ), |
| ), |
| ), |
| ); |
| |
| expect(tester.getTopLeft(find.byKey(childKey)).dy, equals(0.0)); |
| |
| await tester.fling(find.byType(ListView), const Offset(0.0, -200.0), 200.0); |
| await tester.pump(); |
| |
| expect(tester.getTopLeft(find.byKey(childKey)).dy, equals(-480.0)); |
| |
| await tester.fling(find.byType(ListView), const Offset(200.0, 0.0), 200.0); |
| await tester.pump(); |
| |
| expect(tester.getTopLeft(find.byKey(childKey)).dy, equals(-480.0)); |
| |
| await tester.fling(find.byType(ListView), const Offset(-200.0, 0.0), 200.0); |
| await tester.pump(); |
| |
| expect(tester.getTopLeft(find.byKey(childKey)).dy, equals(-480.0)); |
| |
| await tester.fling(find.byType(ListView), const Offset(0.0, 200.0), 200.0); |
| await tester.pump(); |
| |
| expect(tester.getTopLeft(find.byKey(childKey)).dy, equals(0.0)); |
| }); |
| |
| testWidgets('SemanticsDebugger long press', (WidgetTester tester) async { |
| bool didLongPress = false; |
| |
| await tester.pumpWidget( |
| new Directionality( |
| textDirection: TextDirection.ltr, |
| child: new SemanticsDebugger( |
| child: new GestureDetector( |
| onLongPress: () { |
| expect(didLongPress, isFalse); |
| didLongPress = true; |
| }, |
| child: const Text('target', textDirection: TextDirection.ltr), |
| ), |
| ), |
| ), |
| ); |
| |
| await tester.longPress(find.text('target')); |
| expect(didLongPress, isTrue); |
| }); |
| |
| testWidgets('SemanticsDebugger slider', (WidgetTester tester) async { |
| double value = 0.75; |
| |
| await tester.pumpWidget( |
| new Directionality( |
| textDirection: TextDirection.ltr, |
| child: new SemanticsDebugger( |
| child: new Directionality( |
| textDirection: TextDirection.ltr, |
| child: new Material( |
| child: new Center( |
| child: new Slider( |
| value: value, |
| onChanged: (double newValue) { |
| value = newValue; |
| }, |
| ), |
| ), |
| ), |
| ), |
| ), |
| ), |
| ); |
| |
| // The fling below must be such that the velocity estimation examines an |
| // offset greater than the kTouchSlop. Too slow or too short a distance, and |
| // it won't trigger. The actual distance moved doesn't matter since this is |
| // interpreted as a gesture by the semantics debugger and sent to the widget |
| // as a semantic action that always moves by 10% of the complete track. |
| await tester.fling(find.byType(Slider), const Offset(-100.0, 0.0), 2000.0); |
| expect(value, equals(0.65)); |
| }); |
| |
| testWidgets('SemanticsDebugger checkbox', (WidgetTester tester) async { |
| final Key keyTop = new UniqueKey(); |
| final Key keyBottom = new UniqueKey(); |
| |
| bool valueTop = false; |
| final bool valueBottom = true; |
| |
| await tester.pumpWidget( |
| new Directionality( |
| textDirection: TextDirection.ltr, |
| child: new SemanticsDebugger( |
| child: new Material( |
| child: new ListView( |
| children: <Widget>[ |
| new Checkbox( |
| key: keyTop, |
| value: valueTop, |
| onChanged: (bool newValue) { |
| valueTop = newValue; |
| }, |
| ), |
| new Checkbox( |
| key: keyBottom, |
| value: valueBottom, |
| onChanged: null, |
| ), |
| ], |
| ), |
| ), |
| ), |
| ), |
| ); |
| |
| await tester.tap(find.byKey(keyTop)); |
| |
| expect(valueTop, isTrue); |
| valueTop = false; |
| expect(valueTop, isFalse); |
| |
| await tester.tap(find.byKey(keyBottom)); |
| |
| expect(valueTop, isFalse); |
| expect(valueTop, isFalse); |
| }); |
| } |