Files
NextEdu/vitest_announcements.txt
SpecialX 19a05091d3 refactor(grades,attendance,error-book,elective): 组件化重构第 1 批 - 低风险模块
- grades: 拆分 batch-grade-entry (457→374) + grade-record-list (523→231),新增 4 个子组件
- attendance: 迁移 stats-cards/filters 到 StatsGrid/FilterBar 底座
- error-book: 迁移 stats-cards/filters 到 StatsGrid/FilterBar 底座
- elective: 迁移 stats-cards/filters 到 StatsGrid/FilterBar 底座
- 删除 12 个重复组件,新增 app 层 filter 组件就近放置
- tsc 零错误,lint 无新增错误
2026-07-06 19:01:57 +08:00

4213 lines
180 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
 RUN  v4.1.0 E:/Desktop/CICD
✓  unit  src/modules/announcements/schema.test.ts (18 tests) 13ms
✓  unit  src/modules/announcements/is-announcement-visible.test.ts (15 tests) 7ms
  unit  src/modules/announcements/components/announcement-card.test.tsx (16 tests | 9 failed) 400ms
 × 渲染标题与内容 41ms
✓ 渲染类型 badgeschool 7ms
✓ 未提供 href 时不渲染外层 Link 5ms
✓ isRead=false 时应用 ring-2 ring-primary/40 类名 3ms
✓ isRead=true 时不应用 ring 类名 3ms
✓ isRead=undefined 时不应用 ring 类名 2ms
✓ isRead=false 时渲染未读 badge 3ms
✓ isPinned=true 时渲染已置顶 badge 与 Pin 图标 fill 6ms
 × canManage=true 时渲染置顶按钮 144ms
 × canManage=false 时不渲染置顶按钮 30ms
 × 点击置顶按钮调用 service.togglePin 30ms
 × togglePin 返回失败时回滚 isPinned 并显示 toast.error 20ms
 × togglePin 抛错时回滚并显示 toast.error 27ms
 × 置顶按钮支持 Enter 键触发 27ms
 × 置顶按钮支持 Space 键触发 23ms
 × 置顶按钮在 toggling 时禁用 26ms
node.exe :
At line:1 char:1
+ & "C:\Program Files\nodejs/node.exe" "C:\Program Files\nodejs/node_mo ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
⎯⎯⎯⎯⎯⎯⎯ Failed Tests 9 ⎯⎯⎯⎯⎯⎯⎯
 FAIL   unit  src/modules/announcements/components/announcement-card.test.tsx[2
m > AnnouncementCard > 基础渲染 > 渲染标题与内容
Error: Invalid Chai property: toBeInTheDocument
  src/modules/announcements/components/announcement-card.test.tsx:128:41
126| const service = createMockService()
127| renderCard(service)
128| expect(screen.getByText("测试公告标题")).toBe
InTheDocument()
 | ^
129| expect(screen.getByText("测试公告内容")).toBe
InTheDocument()
130| })
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/9]⎯
 FAIL   unit  src/modules/announcements/components/announcement-card.test.tsx[2
m > AnnouncementCard > isPinned 视觉与交互 > canManage=true 时渲染置顶按钮
TestingLibraryElementError: Found multiple elements with the role "button" and name "actions.pin"
Here are the matching elements:
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
(If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAl
lByText`)).
Ignored nodes: comments, script, style
<body>
<div>
<div
class="relative h-full transition-colors hover:bg-accent/50"
data-testid="card"
>
<div
data-testid="card-header"
>
<h3
data-testid="card-title"
>
测试公告标题
</h3>
<div
class="flex shrink-0 items-center gap-1"
>
<span
class="text-xs"
data-testid="badge"
data-variant="default"
>
status.published
</span>
</div>
</div>
<div
data-testid="card-content"
>
<p
class="line-clamp-3 text-sm text-muted-foreground whitespace-pre-wrap"
>
测试公告内容
</p>
<div
class="flex flex-wrap items-center gap-2 text-xs text-muted-foreground"
>
<span
class="capitalize"
data-testid="badge"
data-variant="outline"
>
type.school
</span>
<span>
meta.publishedAt:{"date":"FMT:2026-06-25T00:00:00.000Z"}
</span>
<span
class="ml-auto"
>
meta.author:{"name":"管理员"}
</span>
</div>
</div>
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-
6 items-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v
-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
</div>
</div>
<div>
<div
class="relative h-full transition-colors hover:bg-accent/50"
data-testid="card"
>
<div
data-testid="card-header"
>
<h3
data-testid="card-title"
>
测试公告标题
</h3>
<div
class="flex shrink-0 items-center gap-1"
>
<span
class="text-xs"
data-testid="badge"
data-variant="default"
>
status.published
</span>
</div>
</div>
<div
data-testid="card-content"
>
<p
class="line-clamp-3 text-sm text-muted-foreground whitespace-pre-wrap"
>
测试公告内容
</p>
<div
class="flex flex-wrap items-center gap-2 text-xs text-muted-foreground"
>
<span
class="capitalize"
data-testid="badge"
data-variant="outline"
>
type.school
</span>
<span>
meta.publishedAt:{"date":"FMT:2026-06-25T00:00:00.000Z"}
</span>
<span
class="ml-auto"
>
meta.author:{"name":"管理员"}
</span>
</div>
</div>
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-
6 items-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v
-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
</div>
</div>
<div>
<div
class="relative h-full transition-colors hover:bg-accent/50"
data-testid="card"
>
<div
data-testid="card-header"
>[3...
  Object.getElementError node_modules/@testing-library/dom/dist/config.js:37:19
  getElementError node_modules/@testing-library/dom/dist/query-helpers.js:20:35
  getMultipleElementsFoundError node_modules/@testing-library/dom/dist/query-helpers.js:23:10[
39m
  node_modules/@testing-library/dom/dist/query-helpers.js:55:13
  node_modules/@testing-library/dom/dist/query-helpers.js:95:19
  src/modules/announcements/components/announcement-card.test.tsx:194:32
192| const service = createMockService()
193| renderCard(service)
194| const pinButton = screen.getByRole("button", { name: "actions.pi…
 | ^
195| expect(pinButton).toBeInTheDocument()
196| })
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/9]⎯
 FAIL   unit  src/modules/announcements/components/announcement-card.test.tsx[2
m > AnnouncementCard > isPinned 视觉与交互 > canManage=false 时不渲染置顶按钮
TestingLibraryElementError: Found multiple elements with the role "button" and name "actions.pin"
Here are the matching elements:
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
(If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAl
lByText`)).
Ignored nodes: comments, script, style
<body>
<div>
<div
class="relative h-full transition-colors hover:bg-accent/50"
data-testid="card"
>
<div
data-testid="card-header"
>
<h3
data-testid="card-title"
>
测试公告标题
</h3>
<div
class="flex shrink-0 items-center gap-1"
>
<span
class="text-xs"
data-testid="badge"
data-variant="default"
>
status.published
</span>
</div>
</div>
<div
data-testid="card-content"
>
<p
class="line-clamp-3 text-sm text-muted-foreground whitespace-pre-wrap"
>
测试公告内容
</p>
<div
class="flex flex-wrap items-center gap-2 text-xs text-muted-foreground"
>
<span
class="capitalize"
data-testid="badge"
data-variant="outline"
>
type.school
</span>
<span>
meta.publishedAt:{"date":"FMT:2026-06-25T00:00:00.000Z"}
</span>
<span
class="ml-auto"
>
meta.author:{"name":"管理员"}
</span>
</div>
</div>
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-
6 items-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v
-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
</div>
</div>
<div>
<div
class="relative h-full transition-colors hover:bg-accent/50"
data-testid="card"
>
<div
data-testid="card-header"
>
<h3
data-testid="card-title"
>
测试公告标题
</h3>
<div
class="flex shrink-0 items-center gap-1"
>
<span
class="text-xs"
data-testid="badge"
data-variant="default"
>
status.published
</span>
</div>
</div>
<div
data-testid="card-content"
>
<p
class="line-clamp-3 text-sm text-muted-foreground whitespace-pre-wrap"
>
测试公告内容
</p>
<div
class="flex flex-wrap items-center gap-2 text-xs text-muted-foreground"
>
<span
class="capitalize"
data-testid="badge"
data-variant="outline"
>
type.school
</span>
<span>
meta.publishedAt:{"date":"FMT:2026-06-25T00:00:00.000Z"}
</span>
<span
class="ml-auto"
>
meta.author:{"name":"管理员"}
</span>
</div>
</div>
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-
6 items-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v
-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
</div>
</div>
<div>
<div
class="relative h-full transition-colors hover:bg-accent/50"
data-testid="card"
>
<div
data-testid="card-header"
>[3...
  Object.getElementError node_modules/@testing-library/dom/dist/config.js:37:19
  getElementError node_modules/@testing-library/dom/dist/query-helpers.js:20:35
  getMultipleElementsFoundError node_modules/@testing-library/dom/dist/query-helpers.js:23:10[
39m
  node_modules/@testing-library/dom/dist/query-helpers.js:55:13
  node_modules/@testing-library/dom/dist/query-helpers.js:95:19
  src/modules/announcements/components/announcement-card.test.tsx:205:21
203| </AnnouncementsServiceProvider>
204| )
205| expect(screen.queryByRole("button", { name: "actions.pin" })).to…
 | ^
206| })
207|
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/9]⎯
 FAIL   unit  src/modules/announcements/components/announcement-card.test.tsx[2
m > AnnouncementCard > isPinned 视觉与交互 > 点击置顶按钮调用 service.togglePin
TestingLibraryElementError: Found multiple elements with the role "button" and name "actions.pin"
Here are the matching elements:
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
(If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAl
lByText`)).
Ignored nodes: comments, script, style
<body>
<div>
<div
class="relative h-full transition-colors hover:bg-accent/50"
data-testid="card"
>
<div
data-testid="card-header"
>
<h3
data-testid="card-title"
>
测试公告标题
</h3>
<div
class="flex shrink-0 items-center gap-1"
>
<span
class="text-xs"
data-testid="badge"
data-variant="default"
>
status.published
</span>
</div>
</div>
<div
data-testid="card-content"
>
<p
class="line-clamp-3 text-sm text-muted-foreground whitespace-pre-wrap"
>
测试公告内容
</p>
<div
class="flex flex-wrap items-center gap-2 text-xs text-muted-foreground"
>
<span
class="capitalize"
data-testid="badge"
data-variant="outline"
>
type.school
</span>
<span>
meta.publishedAt:{"date":"FMT:2026-06-25T00:00:00.000Z"}
</span>
<span
class="ml-auto"
>
meta.author:{"name":"管理员"}
</span>
</div>
</div>
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-
6 items-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v
-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
</div>
</div>
<div>
<div
class="relative h-full transition-colors hover:bg-accent/50"
data-testid="card"
>
<div
data-testid="card-header"
>
<h3
data-testid="card-title"
>
测试公告标题
</h3>
<div
class="flex shrink-0 items-center gap-1"
>
<span
class="text-xs"
data-testid="badge"
data-variant="default"
>
status.published
</span>
</div>
</div>
<div
data-testid="card-content"
>
<p
class="line-clamp-3 text-sm text-muted-foreground whitespace-pre-wrap"
>
测试公告内容
</p>
<div
class="flex flex-wrap items-center gap-2 text-xs text-muted-foreground"
>
<span
class="capitalize"
data-testid="badge"
data-variant="outline"
>
type.school
</span>
<span>
meta.publishedAt:{"date":"FMT:2026-06-25T00:00:00.000Z"}
</span>
<span
class="ml-auto"
>
meta.author:{"name":"管理员"}
</span>
</div>
</div>
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-
6 items-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v
-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
</div>
</div>
<div>
<div
class="relative h-full transition-colors hover:bg-accent/50"
data-testid="card"
>
<div
data-testid="card-header"
>[3...
  Object.getElementError node_modules/@testing-library/dom/dist/config.js:37:19
  getElementError node_modules/@testing-library/dom/dist/query-helpers.js:20:35
  getMultipleElementsFoundError node_modules/@testing-library/dom/dist/query-helpers.js:23:10[
39m
  node_modules/@testing-library/dom/dist/query-helpers.js:55:13
  node_modules/@testing-library/dom/dist/query-helpers.js:95:19
  src/modules/announcements/components/announcement-card.test.tsx:217:32
215| renderCard(service)
216|
217| const pinButton = screen.getByRole("button", { name: "actions.pi…
 | ^
218| await fireEvent.click(pinButton)
219|
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/9]⎯
 FAIL   unit  src/modules/announcements/components/announcement-card.test.tsx[2
m > AnnouncementCard > isPinned 视觉与交互 > togglePin 返回失败时回滚 isPinned 并显示 toast.error
TestingLibraryElementError: Found multiple elements with the role "button" and name "actions.pin"
Here are the matching elements:
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
(If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAl
lByText`)).
Ignored nodes: comments, script, style
<body>
<div>
<div
class="relative h-full transition-colors hover:bg-accent/50"
data-testid="card"
>
<div
data-testid="card-header"
>
<h3
data-testid="card-title"
>
测试公告标题
</h3>
<div
class="flex shrink-0 items-center gap-1"
>
<span
class="text-xs"
data-testid="badge"
data-variant="default"
>
status.published
</span>
</div>
</div>
<div
data-testid="card-content"
>
<p
class="line-clamp-3 text-sm text-muted-foreground whitespace-pre-wrap"
>
测试公告内容
</p>
<div
class="flex flex-wrap items-center gap-2 text-xs text-muted-foreground"
>
<span
class="capitalize"
data-testid="badge"
data-variant="outline"
>
type.school
</span>
<span>
meta.publishedAt:{"date":"FMT:2026-06-25T00:00:00.000Z"}
</span>
<span
class="ml-auto"
>
meta.author:{"name":"管理员"}
</span>
</div>
</div>
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-
6 items-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v
-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
</div>
</div>
<div>
<div
class="relative h-full transition-colors hover:bg-accent/50"
data-testid="card"
>
<div
data-testid="card-header"
>
<h3
data-testid="card-title"
>
测试公告标题
</h3>
<div
class="flex shrink-0 items-center gap-1"
>
<span
class="text-xs"
data-testid="badge"
data-variant="default"
>
status.published
</span>
</div>
</div>
<div
data-testid="card-content"
>
<p
class="line-clamp-3 text-sm text-muted-foreground whitespace-pre-wrap"
>
测试公告内容
</p>
<div
class="flex flex-wrap items-center gap-2 text-xs text-muted-foreground"
>
<span
class="capitalize"
data-testid="badge"
data-variant="outline"
>
type.school
</span>
<span>
meta.publishedAt:{"date":"FMT:2026-06-25T00:00:00.000Z"}
</span>
<span
class="ml-auto"
>
meta.author:{"name":"管理员"}
</span>
</div>
</div>
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-
6 items-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v
-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
</div>
</div>
<div>
<div
class="relative h-full transition-colors hover:bg-accent/50"
data-testid="card"
>
<div
data-testid="card-header"
>[3...
  Object.getElementError node_modules/@testing-library/dom/dist/config.js:37:19
  getElementError node_modules/@testing-library/dom/dist/query-helpers.js:20:35
  getMultipleElementsFoundError node_modules/@testing-library/dom/dist/query-helpers.js:23:10[
39m
  node_modules/@testing-library/dom/dist/query-helpers.js:55:13
  node_modules/@testing-library/dom/dist/query-helpers.js:95:19
  src/modules/announcements/components/announcement-card.test.tsx:233:32
231| renderCard(service)
232|
233| const pinButton = screen.getByRole("button", { name: "actions.pi…
 | ^
234| await fireEvent.click(pinButton)
235|
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[5/9]⎯
 FAIL   unit  src/modules/announcements/components/announcement-card.test.tsx[2
m > AnnouncementCard > isPinned 视觉与交互 > togglePin 抛错时回滚并显示 toast.error
TestingLibraryElementError: Found multiple elements with the role "button" and name "actions.pin"
Here are the matching elements:
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
(If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAl
lByText`)).
Ignored nodes: comments, script, style
<body>
<div>
<div
class="relative h-full transition-colors hover:bg-accent/50"
data-testid="card"
>
<div
data-testid="card-header"
>
<h3
data-testid="card-title"
>
测试公告标题
</h3>
<div
class="flex shrink-0 items-center gap-1"
>
<span
class="text-xs"
data-testid="badge"
data-variant="default"
>
status.published
</span>
</div>
</div>
<div
data-testid="card-content"
>
<p
class="line-clamp-3 text-sm text-muted-foreground whitespace-pre-wrap"
>
测试公告内容
</p>
<div
class="flex flex-wrap items-center gap-2 text-xs text-muted-foreground"
>
<span
class="capitalize"
data-testid="badge"
data-variant="outline"
>
type.school
</span>
<span>
meta.publishedAt:{"date":"FMT:2026-06-25T00:00:00.000Z"}
</span>
<span
class="ml-auto"
>
meta.author:{"name":"管理员"}
</span>
</div>
</div>
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-
6 items-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v
-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
</div>
</div>
<div>
<div
class="relative h-full transition-colors hover:bg-accent/50"
data-testid="card"
>
<div
data-testid="card-header"
>
<h3
data-testid="card-title"
>
测试公告标题
</h3>
<div
class="flex shrink-0 items-center gap-1"
>
<span
class="text-xs"
data-testid="badge"
data-variant="default"
>
status.published
</span>
</div>
</div>
<div
data-testid="card-content"
>
<p
class="line-clamp-3 text-sm text-muted-foreground whitespace-pre-wrap"
>
测试公告内容
</p>
<div
class="flex flex-wrap items-center gap-2 text-xs text-muted-foreground"
>
<span
class="capitalize"
data-testid="badge"
data-variant="outline"
>
type.school
</span>
<span>
meta.publishedAt:{"date":"FMT:2026-06-25T00:00:00.000Z"}
</span>
<span
class="ml-auto"
>
meta.author:{"name":"管理员"}
</span>
</div>
</div>
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-
6 items-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v
-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
</div>
</div>
<div>
<div
class="relative h-full transition-colors hover:bg-accent/50"
data-testid="card"
>
<div
data-testid="card-header"
>[3...
  Object.getElementError node_modules/@testing-library/dom/dist/config.js:37:19
  getElementError node_modules/@testing-library/dom/dist/query-helpers.js:20:35
  getMultipleElementsFoundError node_modules/@testing-library/dom/dist/query-helpers.js:23:10[
39m
  node_modules/@testing-library/dom/dist/query-helpers.js:55:13
  node_modules/@testing-library/dom/dist/query-helpers.js:95:19
  src/modules/announcements/components/announcement-card.test.tsx:245:32
243| renderCard(service)
244|
245| const pinButton = screen.getByRole("button", { name: "actions.pi…
 | ^
246| await fireEvent.click(pinButton)
247|
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[6/9]⎯
 FAIL   unit  src/modules/announcements/components/announcement-card.test.tsx[2
m > AnnouncementCard > a11yP2-1 > 置顶按钮支持 Enter 键触发
TestingLibraryElementError: Found multiple elements with the role "button" and name "actions.pin"
Here are the matching elements:
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
(If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAl
lByText`)).
Ignored nodes: comments, script, style
<body>
<div>
<div
class="relative h-full transition-colors hover:bg-accent/50"
data-testid="card"
>
<div
data-testid="card-header"
>
<h3
data-testid="card-title"
>
测试公告标题
</h3>
<div
class="flex shrink-0 items-center gap-1"
>
<span
class="text-xs"
data-testid="badge"
data-variant="default"
>
status.published
</span>
</div>
</div>
<div
data-testid="card-content"
>
<p
class="line-clamp-3 text-sm text-muted-foreground whitespace-pre-wrap"
>
测试公告内容
</p>
<div
class="flex flex-wrap items-center gap-2 text-xs text-muted-foreground"
>
<span
class="capitalize"
data-testid="badge"
data-variant="outline"
>
type.school
</span>
<span>
meta.publishedAt:{"date":"FMT:2026-06-25T00:00:00.000Z"}
</span>
<span
class="ml-auto"
>
meta.author:{"name":"管理员"}
</span>
</div>
</div>
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-
6 items-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v
-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
</div>
</div>
<div>
<div
class="relative h-full transition-colors hover:bg-accent/50"
data-testid="card"
>
<div
data-testid="card-header"
>
<h3
data-testid="card-title"
>
测试公告标题
</h3>
<div
class="flex shrink-0 items-center gap-1"
>
<span
class="text-xs"
data-testid="badge"
data-variant="default"
>
status.published
</span>
</div>
</div>
<div
data-testid="card-content"
>
<p
class="line-clamp-3 text-sm text-muted-foreground whitespace-pre-wrap"
>
测试公告内容
</p>
<div
class="flex flex-wrap items-center gap-2 text-xs text-muted-foreground"
>
<span
class="capitalize"
data-testid="badge"
data-variant="outline"
>
type.school
</span>
<span>
meta.publishedAt:{"date":"FMT:2026-06-25T00:00:00.000Z"}
</span>
<span
class="ml-auto"
>
meta.author:{"name":"管理员"}
</span>
</div>
</div>
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-
6 items-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v
-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
</div>
</div>
<div>
<div
class="relative h-full transition-colors hover:bg-accent/50"
data-testid="card"
>
<div
data-testid="card-header"
>[3...
  Object.getElementError node_modules/@testing-library/dom/dist/config.js:37:19
  getElementError node_modules/@testing-library/dom/dist/query-helpers.js:20:35
  getMultipleElementsFoundError node_modules/@testing-library/dom/dist/query-helpers.js:23:10[
39m
  node_modules/@testing-library/dom/dist/query-helpers.js:55:13
  node_modules/@testing-library/dom/dist/query-helpers.js:95:19
  src/modules/announcements/components/announcement-card.test.tsx:263:32
261| renderCard(service)
262|
263| const pinButton = screen.getByRole("button", { name: "actions.pi…
 | ^
264| await fireEvent.keyDown(pinButton, { key: [
32m"Enter" })
265|
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[7/9]⎯
 FAIL   unit  src/modules/announcements/components/announcement-card.test.tsx[2
m > AnnouncementCard > a11yP2-1 > 置顶按钮支持 Space 键触发
TestingLibraryElementError: Found multiple elements with the role "button" and name "actions.pin"
Here are the matching elements:
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
(If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAl
lByText`)).
Ignored nodes: comments, script, style
<body>
<div>
<div
class="relative h-full transition-colors hover:bg-accent/50"
data-testid="card"
>
<div
data-testid="card-header"
>
<h3
data-testid="card-title"
>
测试公告标题
</h3>
<div
class="flex shrink-0 items-center gap-1"
>
<span
class="text-xs"
data-testid="badge"
data-variant="default"
>
status.published
</span>
</div>
</div>
<div
data-testid="card-content"
>
<p
class="line-clamp-3 text-sm text-muted-foreground whitespace-pre-wrap"
>
测试公告内容
</p>
<div
class="flex flex-wrap items-center gap-2 text-xs text-muted-foreground"
>
<span
class="capitalize"
data-testid="badge"
data-variant="outline"
>
type.school
</span>
<span>
meta.publishedAt:{"date":"FMT:2026-06-25T00:00:00.000Z"}
</span>
<span
class="ml-auto"
>
meta.author:{"name":"管理员"}
</span>
</div>
</div>
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-
6 items-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v
-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
</div>
</div>
<div>
<div
class="relative h-full transition-colors hover:bg-accent/50"
data-testid="card"
>
<div
data-testid="card-header"
>
<h3
data-testid="card-title"
>
测试公告标题
</h3>
<div
class="flex shrink-0 items-center gap-1"
>
<span
class="text-xs"
data-testid="badge"
data-variant="default"
>
status.published
</span>
</div>
</div>
<div
data-testid="card-content"
>
<p
class="line-clamp-3 text-sm text-muted-foreground whitespace-pre-wrap"
>
测试公告内容
</p>
<div
class="flex flex-wrap items-center gap-2 text-xs text-muted-foreground"
>
<span
class="capitalize"
data-testid="badge"
data-variant="outline"
>
type.school
</span>
<span>
meta.publishedAt:{"date":"FMT:2026-06-25T00:00:00.000Z"}
</span>
<span
class="ml-auto"
>
meta.author:{"name":"管理员"}
</span>
</div>
</div>
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-
6 items-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v
-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
</div>
</div>
<div>
<div
class="relative h-full transition-colors hover:bg-accent/50"
data-testid="card"
>
<div
data-testid="card-header"
>[3...
  Object.getElementError node_modules/@testing-library/dom/dist/config.js:37:19
  getElementError node_modules/@testing-library/dom/dist/query-helpers.js:20:35
  getMultipleElementsFoundError node_modules/@testing-library/dom/dist/query-helpers.js:23:10[
39m
  node_modules/@testing-library/dom/dist/query-helpers.js:55:13
  node_modules/@testing-library/dom/dist/query-helpers.js:95:19
  src/modules/announcements/components/announcement-card.test.tsx:278:32
276| renderCard(service)
277|
278| const pinButton = screen.getByRole("button", { name: "actions.pi…
 | ^
279| await fireEvent.keyDown(pinButton, { key: [
32m" " })
280|
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[8/9]⎯
 FAIL   unit  src/modules/announcements/components/announcement-card.test.tsx[2
m > AnnouncementCard > a11yP2-1 > 置顶按钮在 toggling 时禁用
TestingLibraryElementError: Found multiple elements with the role "button" and name "actions.pin"
Here are the matching elements:
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
Ignored nodes: comments, script, style
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-6 item
s-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2
2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
(If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAl
lByText`)).
Ignored nodes: comments, script, style
<body>
<div>
<div
class="relative h-full transition-colors hover:bg-accent/50"
data-testid="card"
>
<div
data-testid="card-header"
>
<h3
data-testid="card-title"
>
测试公告标题
</h3>
<div
class="flex shrink-0 items-center gap-1"
>
<span
 Test Files  1 failed | 2 passed (3)
 Tests  9 failed | 40 passed (49)
 Start at  13:42:18
 Duration  6.09s (transform 695ms, setup 0ms, import 3.98s, tests 420ms, environment 7.55s)
class="text-xs"
data-testid="badge"
data-variant="default"
>
status.published
</span>
</div>
</div>
<div
data-testid="card-content"
>
<p
class="line-clamp-3 text-sm text-muted-foreground whitespace-pre-wrap"
>
测试公告内容
</p>
<div
class="flex flex-wrap items-center gap-2 text-xs text-muted-foreground"
>
<span
class="capitalize"
data-testid="badge"
data-variant="outline"
>
type.school
</span>
<span>
meta.publishedAt:{"date":"FMT:2026-06-25T00:00:00.000Z"}
</span>
<span
class="ml-auto"
>
meta.author:{"name":"管理员"}
</span>
</div>
</div>
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-
6 items-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v
-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
</div>
</div>
<div>
<div
class="relative h-full transition-colors hover:bg-accent/50"
data-testid="card"
>
<div
data-testid="card-header"
>
<h3
data-testid="card-title"
>
测试公告标题
</h3>
<div
class="flex shrink-0 items-center gap-1"
>
<span
class="text-xs"
data-testid="badge"
data-variant="default"
>
status.published
</span>
</div>
</div>
<div
data-testid="card-content"
>
<p
class="line-clamp-3 text-sm text-muted-foreground whitespace-pre-wrap"
>
测试公告内容
</p>
<div
class="flex flex-wrap items-center gap-2 text-xs text-muted-foreground"
>
<span
class="capitalize"
data-testid="badge"
data-variant="outline"
>
type.school
</span>
<span>
meta.publishedAt:{"date":"FMT:2026-06-25T00:00:00.000Z"}
</span>
<span
class="ml-auto"
>
meta.author:{"name":"管理员"}
</span>
</div>
</div>
<button
aria-label="actions.pin"
class="text-muted-foreground hover:text-foreground absolute right-3 top-3 z-10 inline-flex size-
6 items-center justify-center rounded-md transition-colors hover:bg-accent disabled:opacity-50"
type="button"
>
<svg
aria-hidden="true"
class="lucide lucide-pin h-3.5 w-3.5 transition-colors"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 17v5"
/>
<path
d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v
-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"
/>
</svg>
</button>
</div>
</div>
<div>
<div
class="relative h-full transition-colors hover:bg-accent/50"
data-testid="card"
>
<div
data-testid="card-header"
>[3...
  Object.getElementError node_modules/@testing-library/dom/dist/config.js:37:19
  getElementError node_modules/@testing-library/dom/dist/query-helpers.js:20:35
  getMultipleElementsFoundError node_modules/@testing-library/dom/dist/query-helpers.js:23:10[
39m
  node_modules/@testing-library/dom/dist/query-helpers.js:55:13
  node_modules/@testing-library/dom/dist/query-helpers.js:95:19
  src/modules/announcements/components/announcement-card.test.tsx:290:32
288| renderCard(service)
289|
290| const pinButton = screen.getByRole("button", { name: "actions.pi…
 | ^
291| fireEvent.click(pinButton)
292|
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[9/9]⎯