playwright-ts/tools/domObserver.js

75 lines
3.0 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

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.

// 观察DOM变化对新增的按钮等进行disable或hidden,同时获取loading元素数量
const domObserver = new MutationObserver((mutationsList) => {
// 供apiObserver.js判断当前dom正在变动
window.domStatus = 1;
// listenElementsClassName中元素出现style.display属性将被设置为none,且不会被恢复,防止此类元素出现影响UI自动化操作其他元素
// 如需判断页面中存在这些这些元素,只需playwrigh locator.waitFor("attached")即可.
const listenElementsClassName = ["c7n-notification-notice request"];
// 临时被禁用,网络结束后启用的元素
const findAllElementsNeedToDisable = (element) => [
...(element.tagName === "BUTTON" && !element.disabled
? [(element.disabled = true && element)]
: []),
...(element.tagName === "INPUT" && !element.disabled
? [(element.disabled = true && element)]
: []),
...(element.tagName === "svg" &&
!element.ariaHidden &&
!element.closest("button")
? [(element.closest("div").hidden = true && element.closest("div"))]
: []),
...Array.from(element.children || []).flatMap(findAllElementsNeedToDisable),
];
let elementsToRestore = [];
for (const mutation of mutationsList) {
if (mutation.type === "childList") {
const { target, addedNodes } = mutation;
if (target instanceof HTMLElement && target.classList && addedNodes.length > 0) {
const disabledElements = Array.from(addedNodes || []).flatMap(findAllElementsNeedToDisable);
elementsToRestore = elementsToRestore.concat(disabledElements);
addedNodes.forEach((addedNode) => {
if (typeof addedNode.className === 'string') {
for (const className of listenElementsClassName) {
if (addedNode.className.includes(className)) {
addedNode.style.display = "none";
break;
}
}
}
});
}
}
}
// 当目前无loading,且最后一次网络请求结束timeOut时间以上,恢复元素状态.
if (elementsToRestore.length > 0) {
const timeOut = 50;
const intervalId = setInterval(() => {
const now = Date.now();
if (!window.apiCounter &&
now - window.lastResponseEndTime > timeOut &&
now - window.lastDomEndTime > timeOut + 20,
!window.domStatus) {
for (const element of elementsToRestore) {
if (
element instanceof HTMLButtonElement ||
element instanceof HTMLInputElement
) {
element.disabled = false;
} else if (element.tagName === "DIV") {
element.hidden = false;
}
}
clearInterval(intervalId);
}
}, timeOut);
}
window.lastDomEndTime = Date.now();
window.domStatus = 0;
});
if (document.body) {
domObserver.observe(document.body, { childList: true, subtree: true });
} else {
window.addEventListener("DOMContentLoaded", () =>
domObserver.observe(document.body, { childList: true, subtree: true })
);
}