forked from dotnet/blazor
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support custom events and non-bubbling standard events (dotnet#722)
* Support non-bubbling events * Support responding to arbitrary events. E2E coverage of this and bubbling. * Rename E2E test files to avoid clash with other PR
- Loading branch information
1 parent
f61ed4d
commit be8f2d4
Showing
5 changed files
with
164 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
109 changes: 109 additions & 0 deletions
109
test/Microsoft.AspNetCore.Blazor.E2ETest/Tests/EventBubblingTest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using BasicTestApp; | ||
using Microsoft.AspNetCore.Blazor.E2ETest.Infrastructure; | ||
using Microsoft.AspNetCore.Blazor.E2ETest.Infrastructure.ServerFixtures; | ||
using OpenQA.Selenium; | ||
using System; | ||
using Xunit; | ||
using Xunit.Abstractions; | ||
|
||
namespace Microsoft.AspNetCore.Blazor.E2ETest.Tests | ||
{ | ||
public class EventBubblingTest : BasicTestAppTestBase | ||
{ | ||
// Note that currently we only support custom events if they have bubble:true. | ||
// That's because the event delegator doesn't know which custom events bubble and which don't, | ||
// so it doesn't know whether to register a normal handler or a capturing one. If this becomes | ||
// a problem, we could consider registering both types of handler and just bailing out from | ||
// the one that doesn't match the 'bubbles' flag on the received event object. | ||
|
||
public EventBubblingTest( | ||
BrowserFixture browserFixture, | ||
DevHostServerFixture<Program> serverFixture, | ||
ITestOutputHelper output) | ||
: base(browserFixture, serverFixture, output) | ||
{ | ||
Navigate(ServerPathBase, noReload: true); | ||
MountTestComponent<EventBubblingComponent>(); | ||
} | ||
|
||
[Fact] | ||
public void BubblingStandardEvent_FiredOnElementWithHandler() | ||
{ | ||
Browser.FindElement(By.Id("button-with-onclick")).Click(); | ||
|
||
// Triggers event on target and ancestors with handler in upwards direction | ||
Assert.Equal( | ||
new[] { "target onclick", "parent onclick" }, | ||
GetLogLines()); | ||
} | ||
|
||
[Fact] | ||
public void BubblingStandardEvent_FiredOnElementWithoutHandler() | ||
{ | ||
Browser.FindElement(By.Id("button-without-onclick")).Click(); | ||
|
||
// Triggers event on ancestors with handler in upwards direction | ||
Assert.Equal( | ||
new[] { "parent onclick" }, | ||
GetLogLines()); | ||
} | ||
|
||
[Fact] | ||
public void BubblingCustomEvent_FiredOnElementWithHandler() | ||
{ | ||
TriggerCustomBubblingEvent("element-with-onsneeze", "sneeze"); | ||
|
||
// Triggers event on target and ancestors with handler in upwards direction | ||
Assert.Equal( | ||
new[] { "target onsneeze", "parent onsneeze" }, | ||
GetLogLines()); | ||
} | ||
|
||
[Fact] | ||
public void BubblingCustomEvent_FiredOnElementWithoutHandler() | ||
{ | ||
TriggerCustomBubblingEvent("element-without-onsneeze", "sneeze"); | ||
|
||
// Triggers event on ancestors with handler in upwards direction | ||
Assert.Equal( | ||
new[] { "parent onsneeze" }, | ||
GetLogLines()); | ||
} | ||
|
||
[Fact] | ||
public void NonBubblingEvent_FiredOnElementWithHandler() | ||
{ | ||
Browser.FindElement(By.Id("input-with-onfocus")).Click(); | ||
|
||
// Triggers event only on target, not other ancestors with event handler | ||
Assert.Equal(new[] { "target onfocus" }, GetLogLines()); | ||
} | ||
|
||
[Fact] | ||
public void NonBubblingEvent_FiredOnElementWithoutHandler() | ||
{ | ||
Browser.FindElement(By.Id("input-without-onfocus")).Click(); | ||
|
||
// Triggers no event | ||
Assert.Empty(GetLogLines()); | ||
} | ||
|
||
private string[] GetLogLines() | ||
=> Browser.FindElement(By.TagName("textarea")) | ||
.GetAttribute("value") | ||
.Replace("\r\n", "\n") | ||
.Split('\n', StringSplitOptions.RemoveEmptyEntries); | ||
|
||
private void TriggerCustomBubblingEvent(string elementId, string eventName) | ||
{ | ||
var jsExecutor = (IJavaScriptExecutor)Browser; | ||
jsExecutor.ExecuteScript( | ||
$"document.getElementById('{elementId}').dispatchEvent(" + | ||
$" new Event('{eventName}', {{ bubbles: true }})" + | ||
$")"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<h3>Bubbling standard event</h3> | ||
|
||
<div onclick="@(() => LogEvent("parent onclick"))"> | ||
<button id="button-with-onclick" onclick="@(() => LogEvent("target onclick"))">Button with onclick handler</button> | ||
<button id="button-without-onclick" >Button without onclick handler</button> | ||
</div> | ||
|
||
<h3>Bubbling custom event</h3> | ||
|
||
<div onsneeze="@(new Action(() => LogEvent("parent onsneeze")))"> | ||
<div id="element-with-onsneeze" onsneeze="@(new Action(() => LogEvent("target onsneeze")))">Element with onsneeze handler</div> | ||
<div id="element-without-onsneeze" >Element without onsneeze handler</div> | ||
</div> | ||
|
||
<h3>Non-bubbling standard event</h3> | ||
|
||
<!-- The new Action(...) is needed until we add support for onfocus --> | ||
<div onfocus="@(new Action(() => LogEvent("parent onfocus")))"> | ||
<p>With onfocus: <input id="input-with-onfocus" onfocus="@(new Action(() => LogEvent("target onfocus")))" /></p> | ||
<p>Without onfocus: <input id="input-without-onfocus" /></p> | ||
</div> | ||
|
||
<h3>Event log</h3> | ||
|
||
<textarea readonly bind="@logValue"></textarea> | ||
|
||
@functions { | ||
string logValue = string.Empty; | ||
|
||
void LogEvent(string message) | ||
{ | ||
logValue += message + Environment.NewLine; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters