22// Use of this source code is governed by a BSD-style license that can be
33// found in the LICENSE file.
44
5+ import 'dart:async' ;
6+ import 'dart:typed_data' ;
7+
58import 'package:test/bootstrap/browser.dart' ;
69import 'package:test/test.dart' ;
710import 'package:ui/src/engine/dom.dart' ;
@@ -20,18 +23,26 @@ void testMain() {
2023 await initializeEngine ();
2124 });
2225
23- group ('$AccessibilityAnnouncements ' , () {
24- void expectAnnouncementElements ({required bool present}) {
25- expect (
26- domDocument.getElementById ('ftl-announcement-polite' ),
27- present ? isNotNull : isNull,
28- );
29- expect (
30- domDocument.getElementById ('ftl-announcement-assertive' ),
31- present ? isNotNull : isNull,
32- );
33- }
26+ void expectAnnouncementElements ({required bool present}) {
27+ expect (
28+ domDocument.getElementById ('ftl-announcement-polite' ),
29+ present ? isNotNull : isNull,
30+ );
31+ expect (
32+ domDocument.getElementById ('ftl-announcement-assertive' ),
33+ present ? isNotNull : isNull,
34+ );
35+ }
36+
37+ tearDown (() async {
38+ // Completely reset accessibility announcements for subsequent tests.
39+ accessibilityAnnouncements.dispose ();
40+ await Future <void >.delayed (liveMessageDuration * 2 );
41+ initializeAccessibilityAnnouncements ();
42+ expectAnnouncementElements (present: true );
43+ });
3444
45+ group ('$AccessibilityAnnouncements ' , () {
3546 test ('Initialization and disposal' , () {
3647 // Elements should be there right after engine initialization.
3748 expectAnnouncementElements (present: true );
@@ -43,76 +54,89 @@ void testMain() {
4354 expectAnnouncementElements (present: true );
4455 });
4556
46- void resetAccessibilityAnnouncements () {
47- accessibilityAnnouncements.dispose ();
48- initializeAccessibilityAnnouncements ();
49- expectAnnouncementElements (present: true );
57+ ByteData ? encodeMessageOnly ({required String message}) {
58+ return codec.encodeMessage (< dynamic , dynamic > {
59+ 'data' : < dynamic , dynamic > {'message' : message},
60+ });
61+ }
62+
63+ void sendAnnouncementMessage ({required String message, int ? assertiveness}) {
64+ accessibilityAnnouncements.handleMessage (codec, codec.encodeMessage (< dynamic , dynamic > {
65+ 'data' : < dynamic , dynamic > {
66+ 'message' : message,
67+ 'assertiveness' : assertiveness,
68+ },
69+ }));
70+ }
71+
72+ void expectMessages ({String polite = '' , String assertive = '' }) {
73+ expect (accessibilityAnnouncements.ariaLiveElementFor (Assertiveness .polite).text, polite);
74+ expect (accessibilityAnnouncements.ariaLiveElementFor (Assertiveness .assertive).text, assertive);
5075 }
5176
52- test ('Default value of aria-live is polite when assertiveness is not specified' , () {
53- resetAccessibilityAnnouncements ();
54- const Map <dynamic , dynamic > testInput = < dynamic , dynamic > {'data' : < dynamic , dynamic > {'message' : 'polite message' }};
55- accessibilityAnnouncements.handleMessage (codec, codec.encodeMessage (testInput));
56- expect (accessibilityAnnouncements.ariaLiveElementFor (Assertiveness .polite).text, 'polite message' );
57- expect (accessibilityAnnouncements.ariaLiveElementFor (Assertiveness .assertive).text, '' );
77+ void expectNoMessages () => expectMessages ();
78+
79+ test ('Default value of aria-live is polite when assertiveness is not specified' , () async {
80+ accessibilityAnnouncements.handleMessage (codec, encodeMessageOnly (message: 'polite message' ));
81+ expectMessages (polite: 'polite message' );
82+
83+ await Future <void >.delayed (liveMessageDuration);
84+ expectNoMessages ();
5885 });
5986
60- test ('aria-live is assertive when assertiveness is set to 1' , () {
61- resetAccessibilityAnnouncements ( );
62- const Map < dynamic , dynamic > testInput = < dynamic , dynamic > { 'data' : < dynamic , dynamic > { 'message' : ' assertive message', 'assertiveness' : 1 }} ;
63- accessibilityAnnouncements. handleMessage (codec, codec. encodeMessage (testInput));
64- expect (accessibilityAnnouncements. ariaLiveElementFor ( Assertiveness .polite).text, '' );
65- expect (accessibilityAnnouncements. ariaLiveElementFor ( Assertiveness .assertive).text, 'assertive message' );
87+ test ('aria-live is assertive when assertiveness is set to 1' , () async {
88+ sendAnnouncementMessage (message : 'assertive message' , assertiveness : 1 );
89+ expectMessages (assertive : ' assertive message') ;
90+
91+ await Future < void >. delayed (liveMessageDuration );
92+ expectNoMessages ( );
6693 });
6794
68- test ('aria-live is polite when assertiveness is null' , () {
69- resetAccessibilityAnnouncements ( );
70- const Map < dynamic , dynamic > testInput = < dynamic , dynamic > { 'data' : < dynamic , dynamic > { 'message' : ' polite message', 'assertiveness' : null }} ;
71- accessibilityAnnouncements. handleMessage (codec, codec. encodeMessage (testInput));
72- expect (accessibilityAnnouncements. ariaLiveElementFor ( Assertiveness .polite).text, 'polite message' );
73- expect (accessibilityAnnouncements. ariaLiveElementFor ( Assertiveness .assertive).text, '' );
95+ test ('aria-live is polite when assertiveness is null' , () async {
96+ sendAnnouncementMessage (message : 'polite message' );
97+ expectMessages (polite : ' polite message') ;
98+
99+ await Future < void >. delayed (liveMessageDuration );
100+ expectNoMessages ( );
74101 });
75102
76- test ('aria-live is polite when assertiveness is set to 0' , () {
77- resetAccessibilityAnnouncements ( );
78- const Map < dynamic , dynamic > testInput = < dynamic , dynamic > { 'data' : < dynamic , dynamic > { 'message' : ' polite message', 'assertiveness' : 0 }} ;
79- accessibilityAnnouncements. handleMessage (codec, codec. encodeMessage (testInput));
80- expect (accessibilityAnnouncements. ariaLiveElementFor ( Assertiveness .polite).text, 'polite message' );
81- expect (accessibilityAnnouncements. ariaLiveElementFor ( Assertiveness .assertive).text, '' );
103+ test ('aria-live is polite when assertiveness is set to 0' , () async {
104+ sendAnnouncementMessage (message : 'polite message' , assertiveness : 0 );
105+ expectMessages (polite : ' polite message') ;
106+
107+ await Future < void >. delayed (liveMessageDuration );
108+ expectNoMessages ( );
82109 });
83110
84- test ('The same message announced twice is altered to convince the screen reader to read it again.' , () {
85- resetAccessibilityAnnouncements ();
86- const Map <dynamic , dynamic > testInput = < dynamic , dynamic > {'data' : < dynamic , dynamic > {'message' : 'Hello' }};
87- accessibilityAnnouncements.handleMessage (codec, codec.encodeMessage (testInput));
88- expect (accessibilityAnnouncements.ariaLiveElementFor (Assertiveness .polite).text, 'Hello' );
89- expect (accessibilityAnnouncements.ariaLiveElementFor (Assertiveness .assertive).text, '' );
90-
91- // The DOM value gains a "." to make the message look updated.
92- const Map <dynamic , dynamic > testInput2 = < dynamic , dynamic > {'data' : < dynamic , dynamic > {'message' : 'Hello' }};
93- accessibilityAnnouncements.handleMessage (codec, codec.encodeMessage (testInput2));
94- expect (accessibilityAnnouncements.ariaLiveElementFor (Assertiveness .polite).text, 'Hello.' );
95- expect (accessibilityAnnouncements.ariaLiveElementFor (Assertiveness .assertive).text, '' );
96-
97- // Now the "." is removed because the message without it will also look updated.
98- const Map <dynamic , dynamic > testInput3 = < dynamic , dynamic > {'data' : < dynamic , dynamic > {'message' : 'Hello' }};
99- accessibilityAnnouncements.handleMessage (codec, codec.encodeMessage (testInput3));
100- expect (accessibilityAnnouncements.ariaLiveElementFor (Assertiveness .polite).text, 'Hello' );
101- expect (accessibilityAnnouncements.ariaLiveElementFor (Assertiveness .assertive).text, '' );
111+ test ('Rapid-fire messages are each announced.' , () async {
112+ sendAnnouncementMessage (message: 'Hello' );
113+ expectMessages (polite: 'Hello' );
114+
115+ await Future <void >.delayed (liveMessageDuration * 0.5 );
116+ sendAnnouncementMessage (message: 'There' );
117+ expectMessages (polite: 'HelloThere' );
118+
119+ await Future <void >.delayed (liveMessageDuration * 0.6 );
120+ expectMessages (polite: 'There' );
121+
122+ await Future <void >.delayed (liveMessageDuration * 0.5 );
123+ expectNoMessages ();
102124 });
103125
104- test ('announce() polite' , () {
105- resetAccessibilityAnnouncements ();
126+ test ('announce() polite' , () async {
106127 accessibilityAnnouncements.announce ('polite message' , Assertiveness .polite);
107- expect (accessibilityAnnouncements.ariaLiveElementFor (Assertiveness .polite).text, 'polite message' );
108- expect (accessibilityAnnouncements.ariaLiveElementFor (Assertiveness .assertive).text, '' );
128+ expectMessages (polite: 'polite message' );
129+
130+ await Future <void >.delayed (liveMessageDuration);
131+ expectNoMessages ();
109132 });
110133
111- test ('announce() assertive' , () {
112- resetAccessibilityAnnouncements ();
134+ test ('announce() assertive' , () async {
113135 accessibilityAnnouncements.announce ('assertive message' , Assertiveness .assertive);
114- expect (accessibilityAnnouncements.ariaLiveElementFor (Assertiveness .polite).text, '' );
115- expect (accessibilityAnnouncements.ariaLiveElementFor (Assertiveness .assertive).text, 'assertive message' );
136+ expectMessages (assertive: 'assertive message' );
137+
138+ await Future <void >.delayed (liveMessageDuration);
139+ expectNoMessages ();
116140 });
117141 });
118142}
0 commit comments