11using System ;
2- using System . Collections . Generic ;
3- using System . Globalization ;
42using System . Threading . Tasks ;
53using AngleSharp . Dom ;
6- using AngleSharp . Html . Dom ;
7- using AngleSharpWrappers ;
8- using Bunit . Rendering ;
9- using Microsoft . AspNetCore . Components . RenderTree ;
104
115namespace Bunit
126{
@@ -15,73 +9,6 @@ namespace Bunit
159 /// </summary>
1610 public static class GeneralEventDispatchExtensions
1711 {
18- private static HashSet < string > NonBubblingEvents = new HashSet < string > { "onabort" , "onblur" , "onchange" , "onerror" , "onfocus" , "onload" , "onloadend" , "onloadstart" , "onmouseenter" , "onmouseleave" , "onprogress" , "onreset" , "onscroll" , "onsubmit" , "onunload" , "ontoggle" , "ondomnodeinsertedintodocument" , "ondomnoderemovedfromdocument" } ;
19- private static HashSet < string > DisabledEventNames = new HashSet < string > { "onclick" , "ondblclick" , "onmousedown" , "onmousemove" , "onmouseup" } ;
20-
21- /// <summary>
22- /// Raises the event <paramref name="eventName"/> on the element <paramref name="element"/>
23- /// passing the <paramref name="eventArgs"/> to the event handler.
24- /// </summary>
25- /// <param name="element">The element to raise the event on.</param>
26- /// <param name="eventName">The name of the event to raise (using on-form, e.g. <c>onclick</c>).</param>
27- /// <param name="eventArgs">The event arguments to pass to the event handler</param>
28- /// <returns></returns>
29- public static Task TriggerEventAsync ( this IElement element , string eventName , EventArgs eventArgs )
30- {
31- if ( element is null )
32- throw new ArgumentNullException ( nameof ( element ) ) ;
33- if ( eventName is null )
34- throw new ArgumentNullException ( nameof ( eventName ) ) ;
35- var renderer = element . Owner . Context . GetService < ITestRenderer > ( ) ;
36- if ( renderer is null )
37- throw new InvalidOperationException ( $ "Blazor events can only be raised on elements rendered with the Blazor test renderer '{ nameof ( ITestRenderer ) } '.") ;
38-
39- var eventAttrName = Htmlizer . ToBlazorAttribute ( eventName ) ;
40- var eventStopPropergationAttrName = $ "{ eventAttrName } :stoppropagation";
41- var result = new List < Task > ( ) ;
42- var isNonBubblingEvent = NonBubblingEvents . Contains ( eventName . ToLowerInvariant ( ) ) ;
43-
44- foreach ( var candidate in element . GetParentsAndSelf ( ) )
45- {
46- if ( candidate . TryGetEventId ( eventAttrName , out var id ) )
47- result . Add ( renderer . DispatchEventAsync ( id , new EventFieldInfo ( ) { FieldValue = eventName } , eventArgs ) ) ;
48-
49- if ( isNonBubblingEvent || candidate . HasAttribute ( eventStopPropergationAttrName ) || candidate . EventIsDisabled ( eventName ) )
50- {
51- break ;
52- }
53- }
54-
55- if ( result . Count == 0 )
56- throw new MissingEventHandlerException ( element , eventName ) ;
57-
58- return Task . WhenAll ( result ) ;
59- }
60-
61- private static bool EventIsDisabled ( this IElement element , string eventName )
62- {
63- // We want to replicate the normal DOM event behavior that, for 'interactive' elements
64- // with a 'disabled' attribute, certain mouse events are suppressed
65-
66- var elm = ( element as ElementWrapper ) ? . WrappedElement ?? element ;
67- switch ( elm )
68- {
69- case IHtmlButtonElement :
70- case IHtmlInputElement :
71- case IHtmlTextAreaElement :
72- case IHtmlSelectElement :
73- return DisabledEventNames . Contains ( eventName ) && elm . IsDisabled ( ) ;
74- default :
75- return false ;
76- }
77- }
78-
79- private static bool TryGetEventId ( this IElement element , string blazorEventName , out ulong id )
80- {
81- var eventId = element . GetAttribute ( blazorEventName ) ;
82- return ulong . TryParse ( eventId , NumberStyles . Integer , CultureInfo . InvariantCulture , out id ) ;
83- }
84-
8512 /// <summary>
8613 /// Raises the <c>@onactivate</c> event on <paramref name="element"/>, passing an empty (<see cref="EventArgs.Empty"/>)
8714 /// to the event handler.
@@ -95,7 +22,7 @@ private static bool TryGetEventId(this IElement element, string blazorEventName,
9522 /// </summary>
9623 /// <param name="element">The element to raise the event on.</param>
9724 /// <returns>A task that completes when the event handler is done.</returns>
98- private static Task ActivateAsync ( this IElement element ) => TriggerEventAsync ( element , "onactivate" , EventArgs . Empty ) ;
25+ private static Task ActivateAsync ( this IElement element ) => element . TriggerEventAsync ( "onactivate" , EventArgs . Empty ) ;
9926
10027 /// <summary>
10128 /// Raises the <c>@onbeforeactivate</c> event on <paramref name="element"/>, passing an empty (<see cref="EventArgs.Empty"/>)
@@ -110,7 +37,7 @@ private static bool TryGetEventId(this IElement element, string blazorEventName,
11037 /// </summary>
11138 /// <param name="element">The element to raise the event on.</param>
11239 /// <returns>A task that completes when the event handler is done.</returns>
113- private static Task BeforeActivateAsync ( this IElement element ) => TriggerEventAsync ( element , "onbeforeactivate" , EventArgs . Empty ) ;
40+ private static Task BeforeActivateAsync ( this IElement element ) => element . TriggerEventAsync ( "onbeforeactivate" , EventArgs . Empty ) ;
11441
11542 /// <summary>
11643 /// Raises the <c>@onbeforedeactivate</c> event on <paramref name="element"/>, passing an empty (<see cref="EventArgs.Empty"/>)
@@ -125,7 +52,7 @@ private static bool TryGetEventId(this IElement element, string blazorEventName,
12552 /// </summary>
12653 /// <param name="element">The element to raise the event on.</param>
12754 /// <returns>A task that completes when the event handler is done.</returns>
128- private static Task BeforeDeactivateAsync ( this IElement element ) => TriggerEventAsync ( element , "onbeforedeactivate" , EventArgs . Empty ) ;
55+ private static Task BeforeDeactivateAsync ( this IElement element ) => element . TriggerEventAsync ( "onbeforedeactivate" , EventArgs . Empty ) ;
12956
13057 /// <summary>
13158 /// Raises the <c>@ondeactivate</c> event on <paramref name="element"/>, passing an empty (<see cref="EventArgs.Empty"/>)
@@ -140,7 +67,7 @@ private static bool TryGetEventId(this IElement element, string blazorEventName,
14067 /// </summary>
14168 /// <param name="element">The element to raise the event on.</param>
14269 /// <returns>A task that completes when the event handler is done.</returns>
143- private static Task DeactivateAsync ( this IElement element ) => TriggerEventAsync ( element , "ondeactivate" , EventArgs . Empty ) ;
70+ private static Task DeactivateAsync ( this IElement element ) => element . TriggerEventAsync ( "ondeactivate" , EventArgs . Empty ) ;
14471
14572 /// <summary>
14673 /// Raises the <c>@onended</c> event on <paramref name="element"/>, passing an empty (<see cref="EventArgs.Empty"/>)
@@ -155,7 +82,7 @@ private static bool TryGetEventId(this IElement element, string blazorEventName,
15582 /// </summary>
15683 /// <param name="element">The element to raise the event on.</param>
15784 /// <returns>A task that completes when the event handler is done.</returns>
158- private static Task EndedAsync ( this IElement element ) => TriggerEventAsync ( element , "onended" , EventArgs . Empty ) ;
85+ private static Task EndedAsync ( this IElement element ) => element . TriggerEventAsync ( "onended" , EventArgs . Empty ) ;
15986
16087 /// <summary>
16188 /// Raises the <c>@onfullscreenchange</c> event on <paramref name="element"/>, passing an empty (<see cref="EventArgs.Empty"/>)
@@ -170,7 +97,7 @@ private static bool TryGetEventId(this IElement element, string blazorEventName,
17097 /// </summary>
17198 /// <param name="element">The element to raise the event on.</param>
17299 /// <returns>A task that completes when the event handler is done.</returns>
173- private static Task FullscreenChangeAsync ( this IElement element ) => TriggerEventAsync ( element , "onfullscreenchange" , EventArgs . Empty ) ;
100+ private static Task FullscreenChangeAsync ( this IElement element ) => element . TriggerEventAsync ( "onfullscreenchange" , EventArgs . Empty ) ;
174101
175102 /// <summary>
176103 /// Raises the <c>@onfullscreenerror</c> event on <paramref name="element"/>, passing an empty (<see cref="EventArgs.Empty"/>)
@@ -185,7 +112,7 @@ private static bool TryGetEventId(this IElement element, string blazorEventName,
185112 /// </summary>
186113 /// <param name="element">The element to raise the event on.</param>
187114 /// <returns>A task that completes when the event handler is done.</returns>
188- private static Task FullscreenErrorAsync ( this IElement element ) => TriggerEventAsync ( element , "onfullscreenerror" , EventArgs . Empty ) ;
115+ private static Task FullscreenErrorAsync ( this IElement element ) => element . TriggerEventAsync ( "onfullscreenerror" , EventArgs . Empty ) ;
189116
190117 /// <summary>
191118 /// Raises the <c>@onloadeddata</c> event on <paramref name="element"/>, passing an empty (<see cref="EventArgs.Empty"/>)
@@ -200,7 +127,7 @@ private static bool TryGetEventId(this IElement element, string blazorEventName,
200127 /// </summary>
201128 /// <param name="element">The element to raise the event on.</param>
202129 /// <returns>A task that completes when the event handler is done.</returns>
203- private static Task LoadedDataAsync ( this IElement element ) => TriggerEventAsync ( element , "onloadeddata" , EventArgs . Empty ) ;
130+ private static Task LoadedDataAsync ( this IElement element ) => element . TriggerEventAsync ( "onloadeddata" , EventArgs . Empty ) ;
204131
205132 /// <summary>
206133 /// Raises the <c>@onloadedmetadata</c> event on <paramref name="element"/>, passing an empty (<see cref="EventArgs.Empty"/>)
@@ -215,7 +142,7 @@ private static bool TryGetEventId(this IElement element, string blazorEventName,
215142 /// </summary>
216143 /// <param name="element">The element to raise the event on.</param>
217144 /// <returns>A task that completes when the event handler is done.</returns>
218- private static Task LoadedMetadataAsync ( this IElement element ) => TriggerEventAsync ( element , "onloadedmetadata" , EventArgs . Empty ) ;
145+ private static Task LoadedMetadataAsync ( this IElement element ) => element . TriggerEventAsync ( "onloadedmetadata" , EventArgs . Empty ) ;
219146
220147 /// <summary>
221148 /// Raises the <c>@onpointerlockchange</c> event on <paramref name="element"/>, passing an empty (<see cref="EventArgs.Empty"/>)
@@ -230,7 +157,7 @@ private static bool TryGetEventId(this IElement element, string blazorEventName,
230157 /// </summary>
231158 /// <param name="element">The element to raise the event on.</param>
232159 /// <returns>A task that completes when the event handler is done.</returns>
233- private static Task PointerlockChangeAsync ( this IElement element ) => TriggerEventAsync ( element , "onpointerlockchange" , EventArgs . Empty ) ;
160+ private static Task PointerlockChangeAsync ( this IElement element ) => element . TriggerEventAsync ( "onpointerlockchange" , EventArgs . Empty ) ;
234161
235162 /// <summary>
236163 /// Raises the <c>@onpointerlockerror</c> event on <paramref name="element"/>, passing an empty (<see cref="EventArgs.Empty"/>)
@@ -245,7 +172,7 @@ private static bool TryGetEventId(this IElement element, string blazorEventName,
245172 /// </summary>
246173 /// <param name="element">The element to raise the event on.</param>
247174 /// <returns>A task that completes when the event handler is done.</returns>
248- private static Task PointerlockErrorAsync ( this IElement element ) => TriggerEventAsync ( element , "onpointerlockerror" , EventArgs . Empty ) ;
175+ private static Task PointerlockErrorAsync ( this IElement element ) => element . TriggerEventAsync ( "onpointerlockerror" , EventArgs . Empty ) ;
249176
250177 /// <summary>
251178 /// Raises the <c>@onreadystatechange</c> event on <paramref name="element"/>, passing an empty (<see cref="EventArgs.Empty"/>)
@@ -260,7 +187,7 @@ private static bool TryGetEventId(this IElement element, string blazorEventName,
260187 /// </summary>
261188 /// <param name="element">The element to raise the event on.</param>
262189 /// <returns>A task that completes when the event handler is done.</returns>
263- private static Task ReadystateChangeAsync ( this IElement element ) => TriggerEventAsync ( element , "onreadystatechange" , EventArgs . Empty ) ;
190+ private static Task ReadystateChangeAsync ( this IElement element ) => element . TriggerEventAsync ( "onreadystatechange" , EventArgs . Empty ) ;
264191
265192 /// <summary>
266193 /// Raises the <c>@onscroll</c> event on <paramref name="element"/>, passing an empty (<see cref="EventArgs.Empty"/>)
@@ -275,6 +202,6 @@ private static bool TryGetEventId(this IElement element, string blazorEventName,
275202 /// </summary>
276203 /// <param name="element">The element to raise the event on.</param>
277204 /// <returns>A task that completes when the event handler is done.</returns>
278- private static Task ScrollAsync ( this IElement element ) => TriggerEventAsync ( element , "onscroll" , EventArgs . Empty ) ;
205+ private static Task ScrollAsync ( this IElement element ) => element . TriggerEventAsync ( "onscroll" , EventArgs . Empty ) ;
279206 }
280207}
0 commit comments