44
55// ignore_for_file: avoid_print
66
7- import 'dart:html' as html;
8-
97// Imports the Flutter Driver API.
108import 'package:flutter/src/widgets/framework.dart' ;
119import 'package:flutter_test/flutter_test.dart' ;
1210import 'package:integration_test/integration_test.dart' ;
13-
1411import 'package:pointer_interceptor_web_example/main.dart' as app;
12+ import 'package:web/web.dart' as web;
1513
1614final Finder nonClickableButtonFinder =
1715 find.byKey (const Key ('transparent-button' ));
1816final Finder clickableWrappedButtonFinder =
1917 find.byKey (const Key ('wrapped-transparent-button' ));
2018final Finder clickableButtonFinder = find.byKey (const Key ('clickable-button' ));
21- final Finder backgroundFinder =
22- find.byKey (const ValueKey <String >('background-widget' ));
19+ final Finder backgroundFinder = find.byKey (const Key ('background-widget' ));
2320
2421void main () {
2522 IntegrationTestWidgetsFlutterBinding .ensureInitialized ();
@@ -28,10 +25,9 @@ void main() {
2825 testWidgets (
2926 'on wrapped elements, the browser does not hit the background-html-view' ,
3027 (WidgetTester tester) async {
31- app.main ();
32- await tester.pumpAndSettle ();
28+ await _fullyRenderApp (tester);
3329
34- final html .Element element =
30+ final web .Element element =
3531 _getHtmlElementAtCenter (clickableButtonFinder, tester);
3632
3733 expect (element.id, isNot ('background-html-view' ));
@@ -40,10 +36,9 @@ void main() {
4036 testWidgets (
4137 'on wrapped elements with intercepting set to false, the browser hits the background-html-view' ,
4238 (WidgetTester tester) async {
43- app.main ();
44- await tester.pumpAndSettle ();
39+ await _fullyRenderApp (tester);
4540
46- final html .Element element =
41+ final web .Element element =
4742 _getHtmlElementAtCenter (clickableWrappedButtonFinder, tester);
4843
4944 expect (element.id, 'background-html-view' );
@@ -52,20 +47,18 @@ void main() {
5247 testWidgets (
5348 'on unwrapped elements, the browser hits the background-html-view' ,
5449 (WidgetTester tester) async {
55- app.main ();
56- await tester.pumpAndSettle ();
50+ await _fullyRenderApp (tester);
5751
58- final html .Element element =
52+ final web .Element element =
5953 _getHtmlElementAtCenter (nonClickableButtonFinder, tester);
6054
6155 expect (element.id, 'background-html-view' );
6256 }, semanticsEnabled: false );
6357
6458 testWidgets ('on background directly' , (WidgetTester tester) async {
65- app.main ();
66- await tester.pumpAndSettle ();
59+ await _fullyRenderApp (tester);
6760
68- final html .Element element =
61+ final web .Element element =
6962 _getHtmlElementAt (tester.getTopLeft (backgroundFinder));
7063
7164 expect (element.id, 'background-html-view' );
@@ -75,15 +68,9 @@ void main() {
7568 group ('With semantics' , () {
7669 testWidgets ('finds semantics of wrapped widgets' ,
7770 (WidgetTester tester) async {
78- app.main ();
79- await tester.pumpAndSettle ();
71+ await _fullyRenderApp (tester);
8072
81- if (! _newSemanticsAvailable ()) {
82- print ('Skipping test: Needs flutter > 2.10' );
83- return ;
84- }
85-
86- final html.Element element =
73+ final web.Element element =
8774 _getHtmlElementAtCenter (clickableButtonFinder, tester);
8875
8976 expect (element.tagName.toLowerCase (), 'flt-semantics' );
@@ -93,15 +80,9 @@ void main() {
9380 testWidgets (
9481 'finds semantics of wrapped widgets with intercepting set to false' ,
9582 (WidgetTester tester) async {
96- app.main ();
97- await tester.pumpAndSettle ();
98-
99- if (! _newSemanticsAvailable ()) {
100- print ('Skipping test: Needs flutter > 2.10' );
101- return ;
102- }
83+ await _fullyRenderApp (tester);
10384
104- final html .Element element =
85+ final web .Element element =
10586 _getHtmlElementAtCenter (clickableWrappedButtonFinder, tester);
10687
10788 expect (element.tagName.toLowerCase (), 'flt-semantics' );
@@ -111,15 +92,9 @@ void main() {
11192
11293 testWidgets ('finds semantics of unwrapped elements' ,
11394 (WidgetTester tester) async {
114- app.main ();
115- await tester.pumpAndSettle ();
95+ await _fullyRenderApp (tester);
11696
117- if (! _newSemanticsAvailable ()) {
118- print ('Skipping test: Needs flutter > 2.10' );
119- return ;
120- }
121-
122- final html.Element element =
97+ final web.Element element =
12398 _getHtmlElementAtCenter (nonClickableButtonFinder, tester);
12499
125100 expect (element.tagName.toLowerCase (), 'flt-semantics' );
@@ -134,20 +109,26 @@ void main() {
134109 // simply allows the hit test to land on the platform view by making itself
135110 // hit test transparent.
136111 testWidgets ('on background directly' , (WidgetTester tester) async {
137- app.main ();
138- await tester.pumpAndSettle ();
112+ await _fullyRenderApp (tester);
139113
140- final html .Element element =
114+ final web .Element element =
141115 _getHtmlElementAt (tester.getTopLeft (backgroundFinder));
142116
143117 expect (element.id, 'background-html-view' );
144118 });
145119 });
146120}
147121
122+ Future <void > _fullyRenderApp (WidgetTester tester) async {
123+ await tester.pumpWidget (const app.MyApp ());
124+ // Pump 2 frames so the framework injects the platform view into the DOM.
125+ await tester.pump ();
126+ await tester.pump ();
127+ }
128+
148129// Calls [_getHtmlElementAt] passing it the center of the widget identified by
149130// the `finder`.
150- html .Element _getHtmlElementAtCenter (Finder finder, WidgetTester tester) {
131+ web .Element _getHtmlElementAtCenter (Finder finder, WidgetTester tester) {
151132 final Offset point = tester.getCenter (finder);
152133 return _getHtmlElementAt (point);
153134}
@@ -158,22 +139,20 @@ html.Element _getHtmlElementAtCenter(Finder finder, WidgetTester tester) {
158139// sensitive to the presence of shadow roots and browser quirks (not all
159140// browsers agree on what it should return in all situations). Since this test
160141// runs only in Chromium, it relies on Chromium's behavior.
161- html .Element _getHtmlElementAt (Offset point) {
142+ web .Element _getHtmlElementAt (Offset point) {
162143 // Probe at the shadow so the browser reports semantics nodes in addition to
163144 // platform view elements. If probed from `html.document` the browser hides
164145 // the contents of <flt-glass-name> as an implementation detail.
165- final html.ShadowRoot glassPaneShadow =
166- html.document.querySelector ('flt-glass-pane' )! .shadowRoot! ;
167- return glassPaneShadow.elementFromPoint (point.dx.toInt (), point.dy.toInt ())! ;
146+ final web.ShadowRoot glassPaneShadow =
147+ web.document.querySelector ('flt-glass-pane' )! .shadowRoot! ;
148+ // Use `round` below to ensure clicks always fall *inside* the located
149+ // element, rather than truncating the decimals.
150+ // Truncating decimals makes some tests fail when a centered element (in high
151+ // DPI) is not exactly aligned to the pixel grid (because the browser *rounds*)
152+ return glassPaneShadow.elementFromPoint (point.dx.round (), point.dy.round ());
168153}
169154
170- // TODO(dit): Remove this after flutter master (2.13) lands into stable.
171- // This detects that we can do new semantics assertions by looking at the 'id'
172- // attribute on flt-semantics elements (it is now set in 2.13 and up).
173- bool _newSemanticsAvailable () {
174- final html.ShadowRoot glassPaneShadow =
175- html.document.querySelector ('flt-glass-pane' )! .shadowRoot! ;
176- final List <html.Element > elements =
177- glassPaneShadow.querySelectorAll ('flt-semantics[id]' );
178- return elements.isNotEmpty;
155+ /// Shady API: https://github.com/w3c/csswg-drafts/issues/556
156+ extension ElementFromPointInShadowRoot on web.ShadowRoot {
157+ external web.Element elementFromPoint (int x, int y);
179158}
0 commit comments