[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6KW9J44Z1K9WB366HM6EB80":3,"skill-same:01M6KW9J44Z1K9WB366HM6EB80":70},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":49,"commitSha":50,"skillDirectory":51,"forksCount":14,"repositoryHtmlUrl":52,"repositoryHomepageUrl":6,"ownerHtmlUrl":53,"ownerBlogUrl":6,"ownerDescription":54,"updatedAt":55,"install":56,"resources":69},"01M6KW9J44Z1K9WB366HM6EB80","bunit-blazor-testing",null,"Comprehensive guidance for writing Blazor component tests using bUnit with TUnit as the test runner. Covers in-memory rendering, component parameters, cascading values, service mocking, event testing, semantic HTML assertions, and snapshot testing.","rafsanulhasan\u002FHypermediaEngine","rafsanulhasan","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F2341142?v=4","01M6KW2HWPTZWK051N7B0HTBVG","Rafsanul Hasan","01M6KW2J0N3613382MF5DRN79H",0,"GPL-3.0","https:\u002F\u002Fgithub.com\u002Frafsanulhasan\u002FHypermediaEngine\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fbunit-blazor-testing\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"bunit blazor testing","blazor","testing","as","assertions","for","values","with","event","mocking","rendering","tunit","tests","runner","guidance","snapshot","component","test","memory","writing","2026-11-10 10:12:30",false,"---\nname: bunit-blazor-testing\ndescription: Comprehensive guidance for writing Blazor component tests using bUnit with TUnit as the test runner. Covers in-memory rendering, component parameters, cascading values, service mocking, event testing, semantic HTML assertions, and snapshot testing.\n---\n\n# bunit-blazor-testing\n\nThis skill guides the `sqa-engineer` to write Blazor component tests using **bUnit** — an in-memory Blazor component testing library — with **TUnit** as the test runner. bUnit renders Blazor components without a real browser, making tests fast and deterministic.\n\n> **When to use:** Use this skill for testing Blazor components in isolation (unit\u002Fcomponent tests). For full browser end-to-end tests of a Blazor app, use `tunit-playwright-ui-testing` instead.\n\n---\n\n## Phase 0 — Context Load (silent)\n\n1. Read `CLAUDE.md` and project conventions.\n2. Load memory: `Skill(\"manage-memory\", args: \"sqa-engineer\")`.\n3. Locate Blazor components under test.\n4. Identify the test project (create `*.BlazorTests` if needed).\n\n---\n\n## Phase 1 — NuGet Setup\n\n```xml\n\u003CPackageReference Include=\"bunit\" Version=\"1.*\" \u002F>\n\u003CPackageReference Include=\"TUnit\" Version=\"*\" \u002F>\n\u003CPackageReference Include=\"TUnit.Assertions\" Version=\"*\" \u002F>\n\u003CPackageReference Include=\"Bogus\" Version=\"*\" \u002F>\n```\n\n**Note:** bUnit ships a single `bunit` meta-package. It targets `net8.0` and `net9.0`; confirm compatibility with `net10.0` before pinning. If the project is on net10.0, you may need `\u003CTargetFramework>net9.0\u003C\u002FTargetFramework>` for the test project until bUnit releases net10.0 support, or use a preview build.\n\n---\n\n## Phase 2 — TestContext Setup\n\nbUnit provides `Bunit.TestContext` which renders components in an in-memory Blazor host:\n\n```csharp\nusing Bunit;\nusing TUnit.Core;\n\n[TestClass]\npublic class WeatherCardComponentTests : IDisposable\n{\n    private readonly TestContext _ctx = new();\n\n    [Test]\n    [DisplayName(\"[AC-5] WeatherCard shows temperature in Celsius\")]\n    public async Task WeatherCard_WhenTemperatureProvided_ShowsCelsiusValue()\n    {\n        \u002F\u002F Arrange\n        IRenderedComponent\u003CWeatherCard> cut = _ctx.RenderComponent\u003CWeatherCard>(parameters => parameters\n            .Add(p => p.TemperatureC, 22)\n            .Add(p => p.Summary, \"Warm\"));\n\n        \u002F\u002F Act — component is already rendered\n\n        \u002F\u002F Assert\n        cut.Find(\".temperature\").TextContent.Should().Contain(\"22\");\n    }\n\n    public void Dispose() => _ctx.Dispose();\n}\n```\n\n**Key types:**\n- `TestContext` — the in-memory Blazor host. Always dispose it after the test class.\n- `IRenderedComponent\u003CTComponent>` — a rendered component handle.\n- `cut` — \"component under test\" (standard bUnit convention).\n\n---\n\n## Phase 3 — Component Parameters\n\n```csharp\n\u002F\u002F Typed parameters (preferred)\n_ctx.RenderComponent\u003CMyComponent>(parameters => parameters\n    .Add(p => p.Title, \"Hello\")\n    .Add(p => p.IsVisible, true)\n    .Add(p => p.Items, new List\u003Cstring> { \"a\", \"b\" })\n    .Add(p => p.OnClick, EventCallback.Factory.Create(this, HandleClick)));\n\n\u002F\u002F Child content \u002F RenderFragment\n_ctx.RenderComponent\u003CMyComponent>(parameters => parameters\n    .AddChildContent(\"\u003Cp>Child content\u003C\u002Fp>\"));\n```\n\n---\n\n## Phase 4 — Service Mocking and DI\n\nRegister services in the bUnit TestContext's `Services` collection before rendering:\n\n```csharp\n\u002F\u002F Register a real service\n_ctx.Services.AddScoped\u003CIWeatherService, WeatherService>();\n\n\u002F\u002F Register a mock (using TUnit.Mocks or hand-rolled)\nWeatherServiceMock mockWeatherSvc = new();\n_ctx.Services.AddScoped\u003CIWeatherService>(_ => mockWeatherSvc);\n\n\u002F\u002F Register a Bogus-generated stub\n_ctx.Services.AddSingleton(new FakeWeatherService(new Faker()));\n```\n\n**Pattern: full DI registration**\n\n```csharp\n_ctx.Services.AddSingleton\u003CIConfiguration>(new ConfigurationBuilder().Build());\n_ctx.Services.AddHttpClient();\n\u002F\u002F ...add anything the component's DI graph requires\n```\n\n---\n\n## Phase 5 — Cascading Values\n\n```csharp\n_ctx.RenderComponent\u003CMyComponent>(parameters => parameters\n    .AddCascadingValue(\"ThemeName\", \"dark\")\n    .AddCascadingValue(new AppState { IsLoggedIn = true }));\n```\n\n---\n\n## Phase 6 — Event Testing\n\nTest user interactions by finding elements and triggering events:\n\n```csharp\n[Test]\npublic async Task SubmitButton_WhenClicked_CallsOnSubmitCallback()\n{\n    bool submitted = false;\n    IRenderedComponent\u003CContactForm> cut = _ctx.RenderComponent\u003CContactForm>(parameters => parameters\n        .Add(p => p.OnSubmit, EventCallback.Factory.Create(this, () => submitted = true)));\n\n    \u002F\u002F Act\n    cut.Find(\"button[type=submit]\").Click();\n\n    \u002F\u002F Assert\n    await Assert.That(submitted).IsTrue();\n}\n```\n\n**Common event helpers:**\n- `.Click()` — mouse click\n- `.Input(value)` — input event with value\n- `.Change(value)` — change event\n- `.KeyPress(key)` — keyboard event\n- `cut.InvokeAsync(() => component.SomeMethod())` — trigger state changes\n\n---\n\n## Phase 7 — Semantic HTML Assertions\n\nbUnit provides semantic HTML comparison that ignores whitespace and attribute order:\n\n```csharp\n\u002F\u002F Assert markup matches expected HTML\ncut.MarkupMatches(\"\u003Cdiv class=\\\"card\\\">\u003Ch1>Title\u003C\u002Fh1>\u003C\u002Fdiv>\");\n\n\u002F\u002F Assert element presence\ncut.Find(\"h1\").TextContent.Should().Be(\"Weather Forecast\");\n\n\u002F\u002F Assert element count\ncut.FindAll(\"li\").Count.Should().Be(5);\n\n\u002F\u002F Assert element has CSS class\ncut.Find(\".alert\").ClassList.Should().Contain(\"alert-danger\");\n\n\u002F\u002F Assert element attribute\ncut.Find(\"input\").GetAttribute(\"disabled\").Should().NotBeNull();\n```\n\n---\n\n## Phase 8 — Snapshot Testing\n\nFor components where the full markup is the contract:\n\n```csharp\n[Test]\npublic void WeatherCard_RendersCorrectMarkup()\n{\n    IRenderedComponent\u003CWeatherCard> cut = _ctx.RenderComponent\u003CWeatherCard>(\n        p => p.Add(c => c.Summary, \"Mild\"));\n\n    \u002F\u002F Saves snapshot on first run; asserts equality on subsequent runs\n    cut.SaveSnapshot();\n}\n```\n\n> Snapshots are saved to `__snapshots__\u002F` next to the test file. Commit them to source control. Re-generate with `dotnet test -- bunit:updateSnapshots=true` when intentional markup changes are made.\n\n---\n\n## Phase 9 — TUnit-Specific Patterns\n\nSince TUnit replaces xUnit\u002FNUnit as the runner:\n\n```csharp\n\u002F\u002F Use [TestClass] not [Fact] or [Test] on classes\n\u002F\u002F Use [Test] on methods (same as TUnit convention for other test types)\n\u002F\u002F Use TUnit.Assertions.Should for all assertions on bUnit output\n\u002F\u002F Use Assert.Multiple() to collect all failures\n\n[Test]\npublic async Task MyComponent_RendersAllItems()\n{\n    IRenderedComponent\u003CItemList> cut = _ctx.RenderComponent\u003CItemList>(\n        p => p.Add(c => c.Items, [\"A\", \"B\", \"C\"]));\n\n    await Assert.Multiple(async () =>\n    {\n        await Assert.That(cut.FindAll(\"li\")).HasCount().EqualTo(3);\n        await Assert.That(cut.Find(\"li:first-child\").TextContent).IsEqualTo(\"A\");\n    });\n}\n```\n\n---\n\n## Phase 10 — Running Tests\n\n```bash\ndotnet test --filter \"FullyQualifiedName~BlazorTests\"\n```\n\n---\n\n## Best Practices\n\n| Do | Don't |\n|----|-------|\n| Test one behavior per `[Test]` | Test multiple behaviors in one test |\n| Use `cut.Find()` with semantic selectors | Use brittle positional selectors |\n| Dispose `TestContext` after each test class | Leak the bUnit host |\n| Register mocks in `_ctx.Services` | Use static\u002Fglobal mocks |\n| Use `MarkupMatches()` for structural assertions | Use raw string equality on HTML |\n| Trace each test to an AC | Write untargeted \"just render it\" tests |\n","# bunit-blazor-testing\n\nThis skill guides the `sqa-engineer` to write Blazor component tests using **bUnit** — an in-memory Blazor component testing library — with **TUnit** as the test runner. bUnit renders Blazor components without a real browser, making tests fast and deterministic.\n\n> **When to use:** Use this skill for testing Blazor components in isolation (unit\u002Fcomponent tests). For full browser end-to-end tests of a Blazor app, use `tunit-playwright-ui-testing` instead.\n\n---\n\n## Phase 0 — Context Load (silent)\n\n1. Read `CLAUDE.md` and project conventions.\n2. Load memory: `Skill(\"manage-memory\", args: \"sqa-engineer\")`.\n3. Locate Blazor components under test.\n4. Identify the test project (create `*.BlazorTests` if needed).\n\n---\n\n## Phase 1 — NuGet Setup\n\n```xml\n\u003CPackageReference Include=\"bunit\" Version=\"1.*\" \u002F>\n\u003CPackageReference Include=\"TUnit\" Version=\"*\" \u002F>\n\u003CPackageReference Include=\"TUnit.Assertions\" Version=\"*\" \u002F>\n\u003CPackageReference Include=\"Bogus\" Version=\"*\" \u002F>\n```\n\n**Note:** bUnit ships a single `bunit` meta-package. It targets `net8.0` and `net9.0`; confirm compatibility with `net10.0` before pinning. If the project is on net10.0, you may need `\u003CTargetFramework>net9.0\u003C\u002FTargetFramework>` for the test project until bUnit releases net10.0 support, or use a preview build.\n\n---\n\n## Phase 2 — TestContext Setup\n\nbUnit provides `Bunit.TestContext` which renders components in an in-memory Blazor host:\n\n```csharp\nusing Bunit;\nusing TUnit.Core;\n\n[TestClass]\npublic class WeatherCardComponentTests : IDisposable\n{\n    private readonly TestContext _ctx = new();\n\n    [Test]\n    [DisplayName(\"[AC-5] WeatherCard shows temperature in Celsius\")]\n    public async Task WeatherCard_WhenTemperatureProvided_ShowsCelsiusValue()\n    {\n        \u002F\u002F Arrange\n        IRenderedComponent\u003CWeatherCard> cut = _ctx.RenderComponent\u003CWeatherCard>(parameters => parameters\n            .Add(p => p.TemperatureC, 22)\n            .Add(p => p.Summary, \"Warm\"));\n\n        \u002F\u002F Act — component is already rendered\n\n        \u002F\u002F Assert\n        cut.Find(\".temperature\").TextContent.Should().Contain(\"22\");\n    }\n\n    public void Dispose() => _ctx.Dispose();\n}\n```\n\n**Key types:**\n- `TestContext` — the in-memory Blazor host. Always dispose it after the test class.\n- `IRenderedComponent\u003CTComponent>` — a rendered component handle.\n- `cut` — \"component under test\" (standard bUnit convention).\n\n---\n\n## Phase 3 — Component Parameters\n\n```csharp\n\u002F\u002F Typed parameters (preferred)\n_ctx.RenderComponent\u003CMyComponent>(parameters => parameters\n    .Add(p => p.Title, \"Hello\")\n    .Add(p => p.IsVisible, true)\n    .Add(p => p.Items, new List\u003Cstring> { \"a\", \"b\" })\n    .Add(p => p.OnClick, EventCallback.Factory.Create(this, HandleClick)));\n\n\u002F\u002F Child content \u002F RenderFragment\n_ctx.RenderComponent\u003CMyComponent>(parameters => parameters\n    .AddChildContent(\"\u003Cp>Child content\u003C\u002Fp>\"));\n```\n\n---\n\n## Phase 4 — Service Mocking and DI\n\nRegister services in the bUnit TestContext's `Services` collection before rendering:\n\n```csharp\n\u002F\u002F Register a real service\n_ctx.Services.AddScoped\u003CIWeatherService, WeatherService>();\n\n\u002F\u002F Register a mock (using TUnit.Mocks or hand-rolled)\nWeatherServiceMock mockWeatherSvc = new();\n_ctx.Services.AddScoped\u003CIWeatherService>(_ => mockWeatherSvc);\n\n\u002F\u002F Register a Bogus-generated stub\n_ctx.Services.AddSingleton(new FakeWeatherService(new Faker()));\n```\n\n**Pattern: full DI registration**\n\n```csharp\n_ctx.Services.AddSingleton\u003CIConfiguration>(new ConfigurationBuilder().Build());\n_ctx.Services.AddHttpClient();\n\u002F\u002F ...add anything the component's DI graph requires\n```\n\n---\n\n## Phase 5 — Cascading Values\n\n```csharp\n_ctx.RenderComponent\u003CMyComponent>(parameters => parameters\n    .AddCascadingValue(\"ThemeName\", \"dark\")\n    .AddCascadingValue(new AppState { IsLoggedIn = true }));\n```\n\n---\n\n## Phase 6 — Event Testing\n\nTest user interactions by finding elements and triggering events:\n\n```csharp\n[Test]\npublic async Task SubmitButton_WhenClicked_CallsOnSubmitCallback()\n{\n    bool submitted = false;\n    IRenderedComponent\u003CContactForm> cut = _ctx.RenderComponent\u003CContactForm>(parameters => parameters\n        .Add(p => p.OnSubmit, EventCallback.Factory.Create(this, () => submitted = true)));\n\n    \u002F\u002F Act\n    cut.Find(\"button[type=submit]\").Click();\n\n    \u002F\u002F Assert\n    await Assert.That(submitted).IsTrue();\n}\n```\n\n**Common event helpers:**\n- `.Click()` — mouse click\n- `.Input(value)` — input event with value\n- `.Change(value)` — change event\n- `.KeyPress(key)` — keyboard event\n- `cut.InvokeAsync(() => component.SomeMethod())` — trigger state changes\n\n---\n\n## Phase 7 — Semantic HTML Assertions\n\nbUnit provides semantic HTML comparison that ignores whitespace and attribute order:\n\n```csharp\n\u002F\u002F Assert markup matches expected HTML\ncut.MarkupMatches(\"\u003Cdiv class=\\\"card\\\">\u003Ch1>Title\u003C\u002Fh1>\u003C\u002Fdiv>\");\n\n\u002F\u002F Assert element presence\ncut.Find(\"h1\").TextContent.Should().Be(\"Weather Forecast\");\n\n\u002F\u002F Assert element count\ncut.FindAll(\"li\").Count.Should().Be(5);\n\n\u002F\u002F Assert element has CSS class\ncut.Find(\".alert\").ClassList.Should().Contain(\"alert-danger\");\n\n\u002F\u002F Assert element attribute\ncut.Find(\"input\").GetAttribute(\"disabled\").Should().NotBeNull();\n```\n\n---\n\n## Phase 8 — Snapshot Testing\n\nFor components where the full markup is the contract:\n\n```csharp\n[Test]\npublic void WeatherCard_RendersCorrectMarkup()\n{\n    IRenderedComponent\u003CWeatherCard> cut = _ctx.RenderComponent\u003CWeatherCard>(\n        p => p.Add(c => c.Summary, \"Mild\"));\n\n    \u002F\u002F Saves snapshot on first run; asserts equality on subsequent runs\n    cut.SaveSnapshot();\n}\n```\n\n> Snapshots are saved to `__snapshots__\u002F` next to the test file. Commit them to source control. Re-generate with `dotnet test -- bunit:updateSnapshots=true` when intentional markup changes are made.\n\n---\n\n## Phase 9 — TUnit-Specific Patterns\n\nSince TUnit replaces xUnit\u002FNUnit as the runner:\n\n```csharp\n\u002F\u002F Use [TestClass] not [Fact] or [Test] on classes\n\u002F\u002F Use [Test] on methods (same as TUnit convention for other test types)\n\u002F\u002F Use TUnit.Assertions.Should for all assertions on bUnit output\n\u002F\u002F Use Assert.Multiple() to collect all failures\n\n[Test]\npublic async Task MyComponent_RendersAllItems()\n{\n    IRenderedComponent\u003CItemList> cut = _ctx.RenderComponent\u003CItemList>(\n        p => p.Add(c => c.Items, [\"A\", \"B\", \"C\"]));\n\n    await Assert.Multiple(async () =>\n    {\n        await Assert.That(cut.FindAll(\"li\")).HasCount().EqualTo(3);\n        await Assert.That(cut.Find(\"li:first-child\").TextContent).IsEqualTo(\"A\");\n    });\n}\n```\n\n---\n\n## Phase 10 — Running Tests\n\n```bash\ndotnet test --filter \"FullyQualifiedName~BlazorTests\"\n```\n\n---\n\n## Best Practices\n\n| Do | Don't |\n|----|-------|\n| Test one behavior per `[Test]` | Test multiple behaviors in one test |\n| Use `cut.Find()` with semantic selectors | Use brittle positional selectors |\n| Dispose `TestContext` after each test class | Leak the bUnit host |\n| Register mocks in `_ctx.Services` | Use static\u002Fglobal mocks |\n| Use `MarkupMatches()` for structural assertions | Use raw string equality on HTML |\n| Trace each test to an AC | Write untargeted \"just render it\" tests |\n",{"name":5,"description":7},"main","00b2c68281930728ee390bb16cec32b88d2caac7",".github\u002Fskills\u002Fbunit-blazor-testing","https:\u002F\u002Fgithub.com\u002Frafsanulhasan\u002FHypermediaEngine","https:\u002F\u002Fgithub.com\u002Frafsanulhasan","\r\n    MCSD || A-CSD || Software Architect\r\n\r\n","2026-06-06 07:47:06",{"source":8,"skillName":5,"commands":57,"prompt":67,"zipAvailable":68},[58,61,64],{"tool":59,"command":60},"npx","npx skills add rafsanulhasan\u002FHypermediaEngine --skill bunit-blazor-testing",{"tool":62,"command":63},"bunx","bunx skills add rafsanulhasan\u002FHypermediaEngine --skill bunit-blazor-testing",{"tool":65,"command":66},"pnpm","pnpm dlx skills add rafsanulhasan\u002FHypermediaEngine --skill bunit-blazor-testing","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Frafsanulhasan\u002FHypermediaEngine\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fbunit-blazor-testing\u002FSKILL.md",true,[],[71,95,114,133,161,183],{"skillNo":72,"name":73,"nameZh":6,"description":74,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":75,"categories":76,"keywords":78,"publishedAt":44},"01M6KWEJD606FG3DBBRM0W4DKW","write-tests","Test implementation skill for HypermediaEngine. Takes a confirmed test plan from design-test-cases and produces compilable, runnable xUnit tests following project conventions. Validates coverage quality through mutation testing. Invoked by the sqa-engineer agent after the test plan is approved.","https:\u002F\u002Fgithub.com\u002Frafsanulhasan\u002FHypermediaEngine\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fwrite-tests\u002FSKILL.md",[77],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[79,80,36,26,81,41,82,83,84,85,86,87,88,89,90,91,92,93,94,29],"write tests","write","design","project conventions","test plan","Bash","plan","quality","xunit","read","edit","coverage","engineer","mutation testing","project","mutation",{"skillNo":96,"name":97,"nameZh":6,"description":98,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":99,"categories":100,"keywords":101,"publishedAt":44},"01M6KWEF2XQ00C1Y6QCK7YHZ1H","write-documentation","Structured documentation writing workflow for HypermediaEngine. Writes or updates README.md files at the repo root and in each project directory (src\u002F, tests\u002F, samples\u002F, etc.) based on current implementation, ADRs, and architecture decisions.","https:\u002F\u002Fgithub.com\u002Frafsanulhasan\u002FHypermediaEngine\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fwrite-documentation\u002FSKILL.md",[],[102,80,103,43,104,105,106,84,107,108,109,110,88,89,111,93,36,112,113,29],"documentation","write documentation","directory","workflow","architecture","src","repo","decisions","README","files","updates","at",{"skillNo":115,"name":116,"nameZh":6,"description":117,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":118,"categories":119,"keywords":120,"publishedAt":44},"01M6KWEBDXTXAVPQ3BHS3YYYNT","write-adr","Writes a numbered Architecture Decision Record (ADR) for a significant architectural choice in the HypermediaEngine project. Invoked by the software-architect agent whenever a consequential design decision is made or ratified. Saves the ADR to docs\u002Farchitecture\u002Fdecisions\u002F.","https:\u002F\u002Fgithub.com\u002Frafsanulhasan\u002FHypermediaEngine\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fwrite-adr\u002FSKILL.md",[],[121,80,122,81,123,106,124,125,126,127,109,88,128,129,93,130,131,29,132],"adr","write adr","docs","architect","decision","choice","grep","architecture decision record","record","software","opus","architecture decision",{"skillNo":134,"name":135,"nameZh":6,"description":136,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":137,"categories":138,"keywords":145,"publishedAt":44},"01M6KWE76TM3QHGQ08PEB3KY6D","tunit-playwright-ui-testing","Comprehensive guidance for writing coded end-to-end UI tests in C# using TUnit.Playwright. Tests inherit from PageTest — the base class manages all browser lifecycle. Covers NuGet setup, PageTest inheritance, Page Object Model, browser configuration, parallelism limiting, and CI integration. Based on the official TUnit docs at https:\u002F\u002Ftunit.dev\u002Fdocs\u002Fexamples\u002Fplaywright.","https:\u002F\u002Fgithub.com\u002Frafsanulhasan\u002FHypermediaEngine\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Ftunit-playwright-ui-testing\u002FSKILL.md",[139,140],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":141,"categoryName":142,"taxonomyType":143,"taxonomyTypeDesc":144},"01JBSEEDCAT000000000000032","设计师","PROFESSION","适用职业",[26,146,147,148,149,35,150,43,151,152,153,154,155,156,157,158,36,159,160,29],"playwright","ui","playwright ui testing","ui testing","tunit playwright ui testing","official","dev","examples","ci","lifecycle","model","page","inheritance","end","object",{"skillNo":162,"name":163,"nameZh":6,"description":164,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":165,"categories":166,"keywords":170,"publishedAt":44},"01M6KWE44A738GDK65QS02XJBG","triage","Task classification, decomposition, dependency mapping, and routing skill. Invoked by the triage-agent to break any user request into discrete, independently-routable work items with assigned priorities and agent chains.","https:\u002F\u002Fgithub.com\u002Frafsanulhasan\u002FHypermediaEngine\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Ftriage\u002FSKILL.md",[167],{"categoryNo":168,"categoryName":169,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[163,171,172,173,174,175,176,177,178,179,180,31,181,182],"routing","classification","work","user","dependency","task","priorities","decomposition","user request","mapping","break","request",{"skillNo":184,"name":185,"nameZh":6,"description":186,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":187,"categories":188,"keywords":193,"publishedAt":44},"01M6KWDZ3W9ZKPR7FTTTSX8H2K","system-design","Expert system design skill. Use PROACTIVELY to design systems, review architectures, and assist software engineers in learning design principles and implementing them in the code with design patterns.","https:\u002F\u002Fgithub.com\u002Frafsanulhasan\u002FHypermediaEngine\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fsystem-design\u002FSKILL.md",[189,192],{"categoryNo":190,"categoryName":191,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":141,"categoryName":142,"taxonomyType":143,"taxonomyTypeDesc":144},[81,194,195,196,197,198,199,127,88,200,201,202,203,204,205,130,206,207,31,208],"system","system design","web","design systems","learning","haiku","use","design patterns","design principles","expert","patterns","systems","architectures","principles","implementing"]