Skip to content

Commit 8588c0d

Browse files
committed
Add E2E test for CSP violation
1 parent b2c2681 commit 8588c0d

File tree

2 files changed

+51
-7
lines changed

2 files changed

+51
-7
lines changed

src/Components/test/E2ETest/ServerExecutionTests/ServerReconnectionCustomUITest.cs

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,23 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using BasicTestApp.Reconnection;
5+
using Microsoft.AspNetCore.Builder;
56
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure;
67
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures;
78
using Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests;
89
using Microsoft.AspNetCore.E2ETesting;
10+
using Microsoft.AspNetCore.Hosting;
911
using OpenQA.Selenium;
1012
using TestServer;
1113
using Xunit.Abstractions;
1214

1315
namespace Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests;
1416

15-
public class ServerReconnectionCustomUITest : ServerReconnectionTest
17+
public class ServerReconnectionCustomUITest : ServerTestBase<BasicTestAppServerSiteFixture<ServerStartupWithCsp>>
1618
{
1719
public ServerReconnectionCustomUITest(
1820
BrowserFixture browserFixture,
19-
BasicTestAppServerSiteFixture<ServerStartup> serverFixture,
21+
BasicTestAppServerSiteFixture<ServerStartupWithCsp> serverFixture,
2022
ITestOutputHelper output)
2123
: base(browserFixture, serverFixture, output)
2224
{
@@ -30,24 +32,44 @@ protected override void InitializeAsyncCore()
3032
}
3133

3234
[Fact]
33-
public void CustomReconnectUI()
35+
public void CustomReconnectUIIsDisplayed()
3436
{
3537
Browser.Exists(By.Id("increment")).Click();
3638

37-
Browser.Equal("dialog", () => Browser.Exists(By.Id("components-reconnect-modal")).TagName);
38-
39-
var javascript = (IJavaScriptExecutor)Browser;
40-
javascript.ExecuteScript("Blazor._internal.forceCloseConnection()");
39+
var js = (IJavaScriptExecutor)Browser;
40+
js.ExecuteScript("Blazor._internal.forceCloseConnection()");
4141

4242
// We should see the 'reconnecting' UI appear
43+
Browser.Equal("block", () => Browser.Exists(By.Id("components-reconnect-modal")).GetCssValue("display"));
4344
Browser.NotEqual(null, () => Browser.Exists(By.Id("components-reconnect-modal")).GetAttribute("open"));
4445

46+
// The reconnect modal should not be a 'div' element created by the fallback JS code
47+
Browser.Equal("dialog", () => Browser.Exists(By.Id("components-reconnect-modal")).TagName);
48+
4549
// Then it should disappear
50+
Browser.Equal("none", () => Browser.Exists(By.Id("components-reconnect-modal")).GetCssValue("display"));
4651
Browser.Equal(null, () => Browser.Exists(By.Id("components-reconnect-modal")).GetAttribute("open"));
4752

4853
Browser.Exists(By.Id("increment")).Click();
4954

5055
// Can dispatch events after reconnect
5156
Browser.Equal("2", () => Browser.Exists(By.Id("count")).Text);
5257
}
58+
59+
[Fact]
60+
public void StyleSrcCSPIsNotViolated()
61+
{
62+
var js = (IJavaScriptExecutor)Browser;
63+
js.ExecuteScript("Blazor._internal.forceCloseConnection()");
64+
65+
// We should see the 'reconnecting' UI appear
66+
Browser.Equal("block", () => Browser.Exists(By.Id("components-reconnect-modal")).GetCssValue("display"));
67+
68+
// Check that there is no CSP-related error in the browser console
69+
var logs = Browser.Manage().Logs.GetLog(LogType.Browser);
70+
var styleErrors = logs.Where(
71+
log => log.Message.Contains("Refused to apply inline style because it violates the following Content Security Policy directive"));
72+
73+
Assert.Empty(styleErrors);
74+
}
5375
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
namespace TestServer;
5+
6+
public class ServerStartupWithCsp : ServerStartup
7+
{
8+
public ServerStartupWithCsp(IConfiguration configuration) : base(configuration)
9+
{
10+
}
11+
12+
public override void Configure(IApplicationBuilder app, IWebHostEnvironment env, ResourceRequestLog resourceRequestLog)
13+
{
14+
app.Use(async (context, next) =>
15+
{
16+
context.Response.Headers.ContentSecurityPolicy = "style-src 'self';";
17+
await next();
18+
});
19+
20+
base.Configure(app, env, resourceRequestLog);
21+
}
22+
}

0 commit comments

Comments
 (0)