Card Component Added

This commit is contained in:
2026-04-13 15:39:41 +05:00
parent 06ec22704b
commit c23c598b0b
13 changed files with 513 additions and 2 deletions
@@ -0,0 +1,250 @@
using Microsoft.Playwright;
namespace Enciphered.Blazor.UIComponents.Tests;
[TestFixture]
public class CardTests : PlaywrightTestBase
{
// ── Helpers ──────────────────────────────────────────────────────────────
private async Task GoToCardsAsync()
{
await Page.GotoAsync($"{BaseUrl}/cards", new PageGotoOptions { WaitUntil = WaitUntilState.NetworkIdle });
await Page.WaitForSelectorAsync("[data-testid='card-basic']", new PageWaitForSelectorOptions { Timeout = 10_000 });
}
private ILocator Card(string testId) => Page.Locator($"[data-testid='{testId}']");
// ────────────────────────────────────────────
// Basic card structure
// ────────────────────────────────────────────
[Test]
public async Task BasicCard_Is_Visible()
{
await GoToCardsAsync();
await Expect(Card("card-basic")).ToBeVisibleAsync();
}
[Test]
public async Task BasicCard_Has_Rounded_Border_Classes()
{
await GoToCardsAsync();
var card = Card("card-basic");
await Expect(card).ToHaveClassAsync(new System.Text.RegularExpressions.Regex("rounded-xl"));
await Expect(card).ToHaveClassAsync(new System.Text.RegularExpressions.Regex("border"));
}
[Test]
public async Task BasicCard_Renders_Title()
{
await GoToCardsAsync();
var title = Card("card-basic").Locator("h3");
await Expect(title).ToBeVisibleAsync();
await Expect(title).ToHaveTextAsync("Card Title");
}
[Test]
public async Task BasicCard_Renders_Description()
{
await GoToCardsAsync();
var desc = Card("card-basic").Locator("[data-slot='card-description']");
await Expect(desc).ToBeVisibleAsync();
await Expect(desc).ToHaveTextAsync("Card Description");
}
[Test]
public async Task BasicCard_Renders_Content()
{
await GoToCardsAsync();
var content = Card("card-basic").Locator("p:has-text('Card Content')");
await Expect(content).ToBeVisibleAsync();
}
[Test]
public async Task BasicCard_Renders_Footer()
{
await GoToCardsAsync();
var footer = Card("card-basic").Locator("p:has-text('Card Footer')");
await Expect(footer).ToBeVisibleAsync();
}
[Test]
public async Task BasicCard_Description_Appears_Below_Title()
{
await GoToCardsAsync();
var title = Card("card-basic").Locator("h3");
var desc = Card("card-basic").Locator("[data-slot='card-description']");
var titleBox = await title.BoundingBoxAsync();
var descBox = await desc.BoundingBoxAsync();
Assert.That(titleBox, Is.Not.Null, "Title bounding box should exist");
Assert.That(descBox, Is.Not.Null, "Description bounding box should exist");
Assert.That(descBox!.Y, Is.GreaterThan(titleBox!.Y), "Description should be positioned below the title");
}
// ────────────────────────────────────────────
// Login card header with action
// ────────────────────────────────────────────
[Test]
public async Task LoginCard_Is_Visible()
{
await GoToCardsAsync();
await Expect(Card("card-login")).ToBeVisibleAsync();
}
[Test]
public async Task LoginCard_Renders_Title()
{
await GoToCardsAsync();
var title = Card("card-login").Locator("h3");
await Expect(title).ToHaveTextAsync("Login to your account");
}
[Test]
public async Task LoginCard_Renders_Action()
{
await GoToCardsAsync();
var action = Card("card-login").Locator("[data-slot='card-action']");
await Expect(action).ToBeVisibleAsync();
await Expect(action).ToContainTextAsync("Sign Up");
}
[Test]
public async Task LoginCard_Action_Is_Right_Of_Title()
{
await GoToCardsAsync();
var title = Card("card-login").Locator("h3");
var action = Card("card-login").Locator("[data-slot='card-action']");
var titleBox = await title.BoundingBoxAsync();
var actionBox = await action.BoundingBoxAsync();
Assert.That(titleBox, Is.Not.Null);
Assert.That(actionBox, Is.Not.Null);
Assert.That(actionBox!.X, Is.GreaterThan(titleBox!.X), "Action should be to the right of the title");
}
[Test]
public async Task LoginCard_Renders_Description()
{
await GoToCardsAsync();
var desc = Card("card-login").Locator("[data-slot='card-description']");
await Expect(desc).ToContainTextAsync("Enter your email below");
}
[Test]
public async Task LoginCard_Has_Email_Input()
{
await GoToCardsAsync();
var email = Card("card-login").Locator("input#email");
await Expect(email).ToBeVisibleAsync();
}
[Test]
public async Task LoginCard_Has_Password_Input()
{
await GoToCardsAsync();
var password = Card("card-login").Locator("input#password");
await Expect(password).ToBeVisibleAsync();
}
[Test]
public async Task LoginCard_Has_Login_Button()
{
await GoToCardsAsync();
var btn = Card("card-login").Locator("button:has-text('Login')").First;
await Expect(btn).ToBeVisibleAsync();
}
[Test]
public async Task LoginCard_Has_Google_Button()
{
await GoToCardsAsync();
var btn = Card("card-login").Locator("button:has-text('Login with Google')");
await Expect(btn).ToBeVisibleAsync();
}
// ────────────────────────────────────────────
// Image card
// ────────────────────────────────────────────
[Test]
public async Task ImageCard_Is_Visible()
{
await GoToCardsAsync();
await Expect(Card("card-image")).ToBeVisibleAsync();
}
[Test]
public async Task ImageCard_Renders_Image()
{
await GoToCardsAsync();
var img = Card("card-image").Locator("img");
await Expect(img).ToBeVisibleAsync();
await Expect(img).ToHaveAttributeAsync("alt", "Event cover");
}
[Test]
public async Task ImageCard_Image_Appears_Above_Title()
{
await GoToCardsAsync();
var img = Card("card-image").Locator("img");
var title = Card("card-image").Locator("h3");
var imgBox = await img.BoundingBoxAsync();
var titleBox = await title.BoundingBoxAsync();
Assert.That(imgBox, Is.Not.Null);
Assert.That(titleBox, Is.Not.Null);
Assert.That(titleBox!.Y, Is.GreaterThan(imgBox!.Y), "Title should be below the image");
}
[Test]
public async Task ImageCard_Renders_Title()
{
await GoToCardsAsync();
var title = Card("card-image").Locator("h3");
await Expect(title).ToHaveTextAsync("Design systems meetup");
}
[Test]
public async Task ImageCard_Renders_Featured_Badge()
{
await GoToCardsAsync();
var badge = Card("card-image").Locator("[data-slot='card-action']");
await Expect(badge).ToContainTextAsync("Featured");
}
[Test]
public async Task ImageCard_Renders_Description()
{
await GoToCardsAsync();
var desc = Card("card-image").Locator("[data-slot='card-description']");
await Expect(desc).ToContainTextAsync("A practical talk on component APIs");
}
[Test]
public async Task ImageCard_Has_View_Event_Button()
{
await GoToCardsAsync();
var btn = Card("card-image").Locator("button:has-text('View Event')");
await Expect(btn).ToBeVisibleAsync();
}
// ────────────────────────────────────────────
// All three cards render on the page
// ────────────────────────────────────────────
[Test]
public async Task CardsPage_Renders_Three_Cards()
{
await GoToCardsAsync();
await Expect(Card("card-basic")).ToBeVisibleAsync();
await Expect(Card("card-login")).ToBeVisibleAsync();
await Expect(Card("card-image")).ToBeVisibleAsync();
}
}