@ blockle/ blocks- react
测试
Dialog 财务报告和审定财务报表 Drawer 打开方式 HTMLDialogElement.showModal() 关闭 close(). jsdom 不执行这些, 因此在 jsdom 测试中打开 Dialog 保持关闭 <dialog>,而测试库无法从角色中找到它或其中的任何内容.
将此多填充添加到您的 Vest 或 Jest 设置文件中 。 它只定义了jsdom缺失的方法:
const DialogPrototype = HTMLDialogElement.prototype;
if (!DialogPrototype.showModal) {
DialogPrototype.showModal = function showModal() {
this.setAttribute('open', '');
};
}
if (!DialogPrototype.show) {
DialogPrototype.show = function show() {
this.setAttribute('open', '');
};
}
if (!DialogPrototype.close) {
DialogPrototype.close = function close() {
if (!this.hasAttribute('open')) {
return;
}
this.removeAttribute('open');
this.dispatchEvent(new Event('close'));
};
}
用它可以找到一个打开的对话框 getByRole('dialog')数字 :
render(
<Dialog open onRequestClose={() => {}} aria-label="Settings">
<button type="button">Save</button>
</Dialog>,
);
screen.getByRole('dialog', { name: 'Settings' });
screen.getByRole('button', { name: 'Save' });
在多填充下,对话框是开放的,但不是模式的:它不是在上层,它以外的任何东西都不是惰性的,所以它后面的内容仍然可以被询问和点击. 测试模式行为,在真实浏览器中聚焦并点击外部,例如使用Vitest浏览器模式或Playwright.
过量
Popover 以 showPopover() 关闭 hidePopover(). jsdom 不执行 Popover API,其默认样式表隐藏每个 [popover] 未打开的元素, 因此测试库将打开的 popover 内容视为隐藏 getByRole 里面什么都没有.
将此多填充添加到测试设置中 。 它只定义了 jsdom 缺少的方法, 并标记一个开放的弹出式 data-popover-open 测试样式表显示的属性 :
const PopoverPrototype = HTMLElement.prototype;
if (!PopoverPrototype.showPopover) {
PopoverPrototype.showPopover = function showPopover() {
this.setAttribute('data-popover-open', '');
};
}
if (!PopoverPrototype.hidePopover) {
PopoverPrototype.hidePopover = function hidePopover() {
this.removeAttribute('data-popover-open');
};
}
if (!PopoverPrototype.togglePopover) {
PopoverPrototype.togglePopover = function togglePopover(force?: boolean) {
return this.toggleAttribute('data-popover-open', force);
};
}
const popoverStyle = document.createElement('style');
popoverStyle.textContent = '[popover][data-popover-open] { display: block; }';
document.head.append(popoverStyle);
藉由它,一个开放的流行乐内容可以通过角色找到:
render(
<Popover open anchorElement={anchorRef} onRequestClose={() => {}}>
<button type="button">Inside</button>
</Popover>,
);
screen.getByRole('button', { name: 'Inside' });
其他图书馆可查询 showPopover 并且一旦存在,行为就不同;例如,dnd-kit拖动方式不同。 如果全局多填充器中断了这种试验,则仅在下列条件下进行: describe 打开弹出器,然后删除它之后添加的内容:
import { afterAll, beforeAll, describe } from 'vitest';
describe('with a popover open', () => {
const polyfills: Record<string, (this: HTMLElement, force?: boolean) => unknown> = {
showPopover() {
this.setAttribute('data-popover-open', '');
},
hidePopover() {
this.removeAttribute('data-popover-open');
},
togglePopover(force?: boolean) {
return this.toggleAttribute('data-popover-open', force);
},
};
const added: string[] = [];
const popoverStyle = document.createElement('style');
beforeAll(() => {
for (const [method, polyfill] of Object.entries(polyfills)) {
if (!(method in HTMLElement.prototype)) {
Reflect.set(HTMLElement.prototype, method, polyfill);
added.push(method);
}
}
popoverStyle.textContent = '[popover][data-popover-open] { display: block; }';
document.head.append(popoverStyle);
});
afterAll(() => {
for (const method of added) {
Reflect.deleteProperty(HTMLElement.prototype, method);
}
popoverStyle.remove();
});
// Tests that open a popover
});
如果缺少了 Popover API 而未应用多填充, Popover 警告它打开或关闭时,不要投掷。 其内容随后会隐藏在jsdom的默认样式下. 测试定位,顶层并用真实的浏览器点击外部.