all feature
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
const puppeteer = require('puppeteer');
|
||||
|
||||
(async () => {
|
||||
const browser = await puppeteer.launch({ args: ['--no-sandbox', '--disable-setuid-sandbox'] });
|
||||
const page = await browser.newPage();
|
||||
await page.goto('http://127.0.0.1:8000/test-modal');
|
||||
|
||||
// Make modal visible for accurate computed CSS
|
||||
await page.evaluate(() => {
|
||||
const modal = document.getElementById('deleteModal');
|
||||
if (modal) {
|
||||
modal.classList.remove('hidden');
|
||||
modal.style.display = 'flex';
|
||||
}
|
||||
});
|
||||
|
||||
const data = await page.evaluate(() => {
|
||||
const modal = document.getElementById('deleteModal');
|
||||
if (!modal) return { error: 'Modal not found' };
|
||||
|
||||
// 1. DOM Path
|
||||
let current = modal;
|
||||
let path = [];
|
||||
while (current && current.nodeType === 1) {
|
||||
let desc = current.tagName.toLowerCase();
|
||||
if (current.id) desc += '#' + current.id;
|
||||
if (current.className && typeof current.className === 'string') {
|
||||
desc += '.' + current.className.split(' ').join('.');
|
||||
}
|
||||
path.unshift(desc);
|
||||
current = current.parentNode;
|
||||
}
|
||||
|
||||
// 2. Computed CSS for modal
|
||||
const getStyles = (el) => {
|
||||
const cs = window.getComputedStyle(el);
|
||||
return {
|
||||
position: cs.position,
|
||||
top: cs.top,
|
||||
right: cs.right,
|
||||
bottom: cs.bottom,
|
||||
left: cs.left,
|
||||
display: cs.display,
|
||||
zIndex: cs.zIndex,
|
||||
transform: cs.transform !== 'none' ? cs.transform : 'none',
|
||||
contain: cs.contain !== 'none' ? cs.contain : 'none',
|
||||
filter: cs.filter !== 'none' ? cs.filter : 'none',
|
||||
backdropFilter: cs.backdropFilter !== 'none' ? cs.backdropFilter : 'none',
|
||||
perspective: cs.perspective !== 'none' ? cs.perspective : 'none',
|
||||
overflow: cs.overflow,
|
||||
overflowY: cs.overflowY,
|
||||
willChange: cs.willChange !== 'auto' ? cs.willChange : 'auto'
|
||||
};
|
||||
};
|
||||
|
||||
const modalCSS = getStyles(modal);
|
||||
|
||||
// 4. Ancestor trace
|
||||
let ancestors = [];
|
||||
current = modal.parentNode;
|
||||
while (current && current.nodeType === 1) {
|
||||
const cs = window.getComputedStyle(current);
|
||||
const hasContext = cs.transform !== 'none' || cs.filter !== 'none' || cs.perspective !== 'none' || cs.contain !== 'none' || cs.willChange !== 'auto' || cs.position !== 'static' || cs.zIndex !== 'auto' || cs.isolation !== 'auto' || cs.overflow !== 'visible';
|
||||
|
||||
if (hasContext) {
|
||||
ancestors.push({
|
||||
tagName: current.tagName,
|
||||
id: current.id,
|
||||
className: current.className,
|
||||
position: cs.position,
|
||||
zIndex: cs.zIndex,
|
||||
transform: cs.transform !== 'none' ? cs.transform : 'none',
|
||||
filter: cs.filter !== 'none' ? cs.filter : 'none',
|
||||
perspective: cs.perspective !== 'none' ? cs.perspective : 'none',
|
||||
contain: cs.contain !== 'none' ? cs.contain : 'none',
|
||||
willChange: cs.willChange !== 'auto' ? cs.willChange : 'auto',
|
||||
overflow: cs.overflow,
|
||||
isolation: cs.isolation !== 'auto' ? cs.isolation : 'auto'
|
||||
});
|
||||
}
|
||||
current = current.parentNode;
|
||||
}
|
||||
|
||||
// Find element that has large scrollHeight
|
||||
const bodyHeight = document.body.scrollHeight;
|
||||
const mainContent = document.querySelector('.main-content');
|
||||
const scrollContainer = document.querySelector('.overflow-y-auto');
|
||||
|
||||
return {
|
||||
path,
|
||||
modalCSS,
|
||||
ancestors,
|
||||
scrollHeights: {
|
||||
body: bodyHeight,
|
||||
mainContent: mainContent ? mainContent.scrollHeight : null,
|
||||
scrollContainer: scrollContainer ? scrollContainer.scrollHeight : null
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
console.log(JSON.stringify(data, null, 2));
|
||||
await browser.close();
|
||||
})();
|
||||
Reference in New Issue
Block a user