我正在尝试通过 p-menu 命令打开确认对话框。我可以通过单击 p 菜单来显示菜单项。但是当我点击menitem时,命令没有执行,也没有显示确认对话框。
这是我的组件模板:
<div>
<div role="list">
<div
*ngFor="let user of users"
role="listitem"
[attr.aria-label]="user.firstName + ' ' + user.lastName"
>
<span>{{ user.firstName }} {{ user.lastName }}</span>
<button
class="as-button p-button-transparent"
aria-label="Menu"
type="button"
pButton
icon="pi pi-ellipsis-v"
(click)="activeMenu = user; menu.toggle($event)"
></button>
<p-menu #menu [model]="menuItems" [popup]="true"></p-menu>
</div>
</div>
<p-confirmDialog></p-confirmDialog>
相关组件代码:
activeMenu: ConnectionUser | null = null
public menuItems = [
{
label: 'Remove',
command: () => {
this.showConfirmationDialog()
}
}
]
showConfirmationDialog() {
this.confirmationService.confirm({
message: 'Are you sure you want to remove the connection?',
header: 'Remove connection',
rejectButtonStyleClass: 'p-button-secondary',
acceptButtonStyleClass: 'p-button-danger',
acceptLabel: 'Remove',
rejectLabel: 'Cancel',
defaultFocus: 'reject',
accept: () => {
if (this.activeMenu) {
this.removeConnection(this.activeMenu._id)
}
}
})
}
这是我的笑话导入:
imports: [ConnectionsModule, NoopAnimationsModule, SharedModule, RouterTestingModule],
以及失败的玩笑测试:
it('should remove connection', async () => {
const userEv = userEvent.setup({ delay: null })
await userEv.click(
within(await screen.findByRole('listitem', { name: 'Joe Doe' })).getByRole('button', {
name: 'Menu'
})
)
fixture.detectChanges()
await userEv.click(await screen.findByRole('menuitem', { name: 'Remove' }))
fixture.detectChanges()
// ERROR: The button has not been found
await userEv.click(await screen.findByRole('button', { name: 'Remove' }))
expect(screen.queryByRole('listitem')).not.toBeInTheDocument()
})
我尝试过 detectorChanges 和 waitFor 但没有一个会显示确认。
这是 jest 渲染的 p 菜单:
<p-menu
class="p-element ng-tns-c215187649-2 ng-star-inserted"
ng-reflect-model="[object Object]"
ng-reflect-popup="true"
>
<div
class="ng-trigger ng-trigger-overlayAnimation ng-tns-c215187649-2 p-menu p-component p-menu-overlay ng-star-inserted"
data-pc-name="menu"
id="pn_id_5"
ng-reflect-ng-class="[object Object]"
style="z-index: 1001; visibility: visible; display: none; transform-origin: top; top: 0px; left: 0px;"
>
<ul
class="p-menu-list p-reset ng-tns-c215187649-2"
data-pc-section="menu"
id="pn_id_5_list"
role="menu"
tabindex="0"
>
<li
aria-disabled="false"
aria-label="Remove"
class="p-element p-menuitem ng-tns-c215187649-2 ng-star-inserted"
data-p-disabled="false"
data-p-focused="false"
data-pc-section="menuitem"
id="pn_id_5_0"
ng-reflect-content=""
ng-reflect-id="pn_id_5_0"
ng-reflect-item="[object Object]"
ng-reflect-ng-class="[object Object]"
ptooltip=""
role="menuitem"
style=""
>
<div
class="p-menuitem-content"
data-pc-section="content"
>
<a
aria-hidden="true"
class="p-ripple p-element p-menuitem-link ng-star-inserted"
data-pc-section="action"
ng-reflect-ng-class="[object Object]"
pripple=""
tabindex="-1"
target="undefined"
>
<span
class="p-menuitem-text ng-star-inserted"
>
Remove
</span>
</a>
</div>
</li>
</ul>
</div>
</p-menu>
它是否不会被触发,因为在渲染的 html 中,p-menu-overlay 具有 display: none; 样式?另一方面,通过玩笑找到了 menuitem 按钮,并且单击并未失败。
我已在命令函数 (this.showConfirmationDialog()) 中放置了调试,但它从未被调用。
我无法弄清楚为什么它没有被调用,所以我采用了一种解决方法来直接调用该命令。
component.menuItems[0].command()
我还添加了缺少的 ConfirmationService 提供程序,以显示确认对话框。
这就是我最终得到的:
component.menuItems[0].command()
fixture.detectChanges()
// Confirm dialog
await userEvent.click(await screen.findByRole('button', { name: 'Remove' }))
fixture.detectChanges()