90 lines
3.1 KiB
JavaScript
90 lines
3.1 KiB
JavaScript
|
|
const { chromium } = require('playwright');
|
||
|
|
|
||
|
|
const input = process.argv[2];
|
||
|
|
const presenterNames = ['Zhihao Zhao', 'Zipeng Wang', 'Jiuqi Feng', 'Siyuan Zhang'];
|
||
|
|
|
||
|
|
function baseWithoutHash(url) {
|
||
|
|
const hashIndex = url.indexOf('#');
|
||
|
|
return hashIndex >= 0 ? url.slice(0, hashIndex) : url;
|
||
|
|
}
|
||
|
|
|
||
|
|
async function applyRequestedEdits(page) {
|
||
|
|
await page.evaluate((names) => {
|
||
|
|
const visible = Array.from(document.querySelectorAll('section')).find((section) => {
|
||
|
|
const style = getComputedStyle(section);
|
||
|
|
return style.visibility !== 'hidden' && style.opacity !== '0';
|
||
|
|
});
|
||
|
|
if (!visible) return;
|
||
|
|
|
||
|
|
if ((visible.getAttribute('data-label') || '').startsWith('01')) {
|
||
|
|
for (const el of Array.from(visible.querySelectorAll('div'))) {
|
||
|
|
const text = (el.innerText || '').replace(/\s+/g, ' ').trim();
|
||
|
|
if (text === 'PRESENTED [ Presentation Date ] 4-person team walkthrough · ~10 min') {
|
||
|
|
el.style.display = 'none';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if ((visible.getAttribute('data-label') || '').startsWith('15')) {
|
||
|
|
const placeholders = Array.from(visible.querySelectorAll('div'))
|
||
|
|
.filter((el) => (el.innerText || '').trim() === '[ name ]');
|
||
|
|
placeholders.forEach((el, index) => {
|
||
|
|
if (names[index]) {
|
||
|
|
el.textContent = names[index];
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}, presenterNames);
|
||
|
|
}
|
||
|
|
|
||
|
|
(async () => {
|
||
|
|
if (!input) {
|
||
|
|
throw new Error('Usage: node html_to_ppt_check_placeholders.js <file-url>');
|
||
|
|
}
|
||
|
|
|
||
|
|
const launchOptions = { headless: true };
|
||
|
|
if (process.env.BROWSER_EXE) {
|
||
|
|
launchOptions.executablePath = process.env.BROWSER_EXE;
|
||
|
|
}
|
||
|
|
|
||
|
|
const browser = await chromium.launch(launchOptions);
|
||
|
|
const baseUrl = baseWithoutHash(input);
|
||
|
|
const findings = [];
|
||
|
|
const nameChecks = [];
|
||
|
|
|
||
|
|
for (let i = 1; i <= 15; i += 1) {
|
||
|
|
const page = await browser.newPage({ viewport: { width: 1920, height: 1080 } });
|
||
|
|
await page.goto(`${baseUrl}#${i}`, { waitUntil: 'load', timeout: 30000 });
|
||
|
|
await page.waitForSelector('section', { state: 'attached', timeout: 10000 });
|
||
|
|
await page.waitForTimeout(500);
|
||
|
|
await applyRequestedEdits(page);
|
||
|
|
const result = await page.evaluate((names) => {
|
||
|
|
const visible = Array.from(document.querySelectorAll('section')).find((section) => {
|
||
|
|
const style = getComputedStyle(section);
|
||
|
|
return style.visibility !== 'hidden' && style.opacity !== '0';
|
||
|
|
});
|
||
|
|
const label = visible?.getAttribute('data-label') || '';
|
||
|
|
const text = visible?.innerText || '';
|
||
|
|
const placeholderMatches = text.match(/\[[^\]]+\]|Presentation Date|Slide Number|placeholder|PRESENTED\s+\[/gi) || [];
|
||
|
|
return {
|
||
|
|
label,
|
||
|
|
placeholderMatches,
|
||
|
|
presenterNamesPresent: names.map((name) => text.includes(name)),
|
||
|
|
};
|
||
|
|
}, presenterNames);
|
||
|
|
if (result.placeholderMatches.length) {
|
||
|
|
findings.push({ slide: i, label: result.label, matches: result.placeholderMatches });
|
||
|
|
}
|
||
|
|
if (i === 15) {
|
||
|
|
nameChecks.push(...result.presenterNamesPresent);
|
||
|
|
}
|
||
|
|
await page.close();
|
||
|
|
}
|
||
|
|
|
||
|
|
await browser.close();
|
||
|
|
console.log(JSON.stringify({ findings, slide15NamesPresent: nameChecks }, null, 2));
|
||
|
|
})().catch((err) => {
|
||
|
|
console.error(err);
|
||
|
|
process.exit(1);
|
||
|
|
});
|