Skip to content
This repository has been archived by the owner on Feb 25, 2021. It is now read-only.

Commit

Permalink
Support responding to arbitrary events. E2E coverage of this and bubb…
Browse files Browse the repository at this point in the history
…ling.
  • Loading branch information
SteveSandersonMS committed May 1, 2018
1 parent 01a2dd9 commit 433be38
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ private static UIEventArgs ParseEventArgsJson(string eventArgsType, string event
return JsonUtil.Deserialize<UIKeyboardEventArgs>(eventArgsJson);
case "change":
return JsonUtil.Deserialize<UIChangeEventArgs>(eventArgsJson);
case "unknown":
return JsonUtil.Deserialize<UIEventArgs>(eventArgsJson);
default:
throw new ArgumentException($"Unsupported value '{eventArgsType}'.", nameof(eventArgsType));
}
Expand Down
109 changes: 109 additions & 0 deletions test/Microsoft.AspNetCore.Blazor.E2ETest/Tests/EventTest.cs
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 EventTest : 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 EventTest(
BrowserFixture browserFixture,
DevHostServerFixture<Program> serverFixture,
ITestOutputHelper output)
: base(browserFixture, serverFixture, output)
{
Navigate(ServerPathBase, noReload: true);
MountTestComponent<EventCasesComponent>();
}

[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 }})" +
$")");
}
}
}
34 changes: 34 additions & 0 deletions test/testapps/BasicTestApp/EventCasesComponent.cshtml
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;
}
}
1 change: 1 addition & 0 deletions test/testapps/BasicTestApp/wwwroot/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<option value="BasicTestApp.ElementRefComponent">Element ref component</option>
<option value="BasicTestApp.ComponentRefComponent">Component ref component</option>
<option value="BasicTestApp.AfterRenderInteropComponent">After-render interop component</option>
<option value="BasicTestApp.EventCasesComponent">Event cases</option>
<!--<option value="BasicTestApp.RouterTest.Default">Router</option> Excluded because it requires additional setup to work correctly when loaded manually -->
</select>
&nbsp;
Expand Down

0 comments on commit 433be38

Please sign in to comment.