Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions src/AcceptanceTests/Authentication/LoginTests.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Text.RegularExpressions;
using ClearMeasure.Bootcamp.UI.Shared;
using ClearMeasure.Bootcamp.UI.Shared.Components;
using ClearMeasure.Bootcamp.UI.Shared.Pages;
Expand Down Expand Up @@ -57,6 +58,26 @@ public async Task Should_ExposeUserSelectIdMatchingLabelFor()
await Expect(Page.Locator($"label[for='{Login.Elements.User}']")).ToBeAttachedAsync();
}

[Test, Retry(2)]
public async Task Should_ShowBlinkingLoginLink_WhenAnonymous()
{
await Page.GotoAsync("/");
await Page.WaitForLoadStateAsync(LoadState.NetworkIdle);

var logoutLink = Page.GetByTestId(nameof(Logout.Elements.LogoutLink));
if (await logoutLink.CountAsync() > 0)
{
await logoutLink.ClickAsync();
await Page.WaitForURLAsync("**/");
}

var loginLink = Page.GetByTestId(nameof(LoginLink.Elements.LoginLink));
await Expect(loginLink).ToBeVisibleAsync();
await Expect(loginLink).ToHaveClassAsync(new Regex("login-link-blink"));
await Expect(loginLink).ToHaveAttributeAsync("href", "/login");
await Expect(loginLink).ToHaveTextAsync("Login");
}
Comment on lines +61 to +79

[Test, Retry(2)]
public async Task Should_LoginSuccessfully_UsingUsernameValue_NotDisplayLabel()
{
Expand All @@ -73,6 +94,7 @@ public async Task Should_LoginSuccessfully_UsingUsernameValue_NotDisplayLabel()

var welcomeTextLocator = Page.GetByTestId(nameof(Logout.Elements.WelcomeText));
await Expect(welcomeTextLocator).ToHaveTextAsync("Welcome hsimpson!");
await Expect(Page.GetByTestId(nameof(LoginLink.Elements.LoginLink))).ToHaveCountAsync(0);
}

[Test, Retry(2)]
Expand Down Expand Up @@ -102,6 +124,7 @@ public async Task LoginWithUsernameOnlyForwardsToHomePage()

var welcomeTextLocator = Page.GetByTestId(nameof(Logout.Elements.WelcomeText));
await Expect(welcomeTextLocator).ToHaveTextAsync("Welcome hsimpson!");
await Expect(Page.GetByTestId(nameof(LoginLink.Elements.LoginLink))).ToHaveCountAsync(0);
}

[Test, Retry(2)]
Expand Down
4 changes: 2 additions & 2 deletions src/UI.Shared/Components/LoginLink.razor
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<a data-testid="@Elements.LoginLink" href="/login">Login</a>
<a class="login-link-blink" data-testid="@Elements.LoginLink" href="/login">Login</a>

@code
{
public enum Elements
{
LoginLink
}
}
}
36 changes: 36 additions & 0 deletions src/UI.Shared/Components/LoginLink.razor.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
a.login-link-blink {
animation: login-link-blink-pulse 0.7s steps(2, end) infinite;
background-color: #f6e05e !important;
color: #1a202c !important;
font-weight: 700 !important;
transition: none !important;
outline: 3px solid #c53030;
outline-offset: 2px;
}
Comment on lines +1 to +9

@keyframes login-link-blink-pulse {
0%,
100% {
opacity: 1;
background-color: #f6e05e;
color: #1a202c;
outline-color: #c53030;
}

50% {
opacity: 0.15;
background-color: #fc8181;
color: #742a2a;
outline-color: #f6e05e;
}
}

@media (prefers-reduced-motion: reduce) {
a.login-link-blink {
animation: none;
opacity: 1;
background-color: #f6e05e !important;
color: #1a202c !important;
outline: 3px solid #c53030;
}
}
16 changes: 16 additions & 0 deletions src/UnitTests/UI.Shared/MainLayoutTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,22 @@ public async Task ShouldRenderLoginLink_InHeader_WhenUserIsNotAuthenticated()

var loginAnchor = layout.Find($"a[data-testid='{nameof(LoginLink.Elements.LoginLink)}']");
loginAnchor.GetAttribute("href").ShouldBe("/login");
loginAnchor.ClassList.ShouldContain("login-link-blink");
}

[Test]
public async Task ShouldRenderLoginLink_WithBlinkClass_WhenUserIsNotAuthenticated()
{
await using var ctx = CreateContext();

var component = ctx.Render<CascadingAuthenticationState>(p => p.AddChildContent<MainLayout>());
var layout = component.FindComponent<MainLayout>();

var loginAnchor = layout.Find($"a[data-testid='{nameof(LoginLink.Elements.LoginLink)}']");
loginAnchor.ClassList.ShouldContain("login-link-blink");
loginAnchor.GetAttribute("href").ShouldBe("/login");
loginAnchor.GetAttribute("data-testid").ShouldBe(nameof(LoginLink.Elements.LoginLink));
loginAnchor.TextContent.Trim().ShouldBe("Login");
}
Comment on lines +147 to 160

[Test]
Expand Down
Loading