const isPromise = require("./ispromise") const IFRAME_SELECTOR = 'iframe[title="Hoofdinhoud"]'; const CELL_SELECTOR = 'a[title="Sectie uitvouwen Algemene opleidingsonderdelen"]'; const CELL_SELECTOR_OPEN = "a[title='Sectie samenvouwen Algemene opleidingsonderdelen']"; const STUDENT_NAME_CELL_SELECTOR = 'span[id="DERIVED_SCC_SUM_PERSON_NAME$5$"]'; const STUDENT_ID_CELL_SELECTOR = 'span[id="SCC_PERS_SA_VW_EMPLID"]'; const STPKT_KEUZE_CELL_SELECTOR = 'a[title="Sectie uitvouwen Keuzeopleidingsonderdelen"]'; const STPKT_KEUZE_CELL_SELECTOR_OPEN = 'a[title="Sectie samenvouwen Keuzeopleidingsonderdelen"]' /** * Extracted function to get the text content of a node. * @param {ElementHandle} node - The node to get the text content from. * @returns {Promise} The text content of the node. */ async function getNodeTextContent(node) { return await node.evaluate((node) => node.textContent); } /** * Extracted function to retrieve the content frame. * @param {Page} page - The Puppeteer page object. * @returns {Promise} The content frame. */ async function getContentFrame(page) { await page.waitForSelector(IFRAME_SELECTOR); const iframe = await page.$(IFRAME_SELECTOR); if (!iframe) { throw new Error("Could not find iframe on the AA-page"); } console.log("iframe found on AA-page"); return await iframe.contentFrame(); } /** * Checks if the 'Startpakket' is available by verifying text content in a cell * and the `aria-expanded` attribute. * * @param {Page} page - The Puppeteer page object. * @returns {Promise} True if the 'Startpakket' is available, false otherwise. */ async function isStartPakketAvailable(page) { const contentFrame = await getContentFrame(page); let cell let isCollapsed_main_before_function = true try { await contentFrame.waitForSelector(CELL_SELECTOR, { timeout: 5000 }); // Adjust timeout as needed cell = await contentFrame.$(CELL_SELECTOR); } catch (error) { console.warn("CELL_SELECTOR not found, trying CELL_SELECTOR_OPEN"); await contentFrame.waitForSelector(CELL_SELECTOR_OPEN, { timeout: 5000 }); // Adjust timeout as needed cell = await contentFrame.$(CELL_SELECTOR_OPEN); isCollapsed_main_before_function = false } let cell_keuze = await contentFrame.$(STPKT_KEUZE_CELL_SELECTOR) if (!cell_keuze) { cell_keuze = contentFrame.$(STPKT_KEUZE_CELL_SELECTOR_OPEN) } if (!cell ) { throw new Error( "Cell inside function isStartPakketAvailable is not defined" ); } //object vars const isCollapsed_main = isCollapsed_main_before_function ? await isAriaExpandedFalse(cell) : isCollapsed_main_before_function; const isCollapsed_keuze = await getIsCollapsedKeuze(cell_keuze); const isCollapsed = isCollapsed_main && isCollapsed_keuze; const studName = await getStudName(contentFrame); const studId = await getStudId(contentFrame); const containsVZP = await hasVZP(cell) const containsVZP_keuze = await hasVZP(cell_keuze) return { isCollapsed: isCollapsed, isCollapsed_main: isCollapsed_main, isCollapsed_keuze: isCollapsed_keuze, studName: studName, studId: studId, containsVZP: containsVZP, containsVZP_keuze: containsVZP_keuze, // more properties here }; } /** * Checks if the given cell node has an `aria-expanded` attribute with a value of 'false'. * * @param {ElementHandle} node - The node to check the `aria-expanded` attribute. * @returns {Promise} True if the `aria-expanded` attribute is 'false', false otherwise. */ async function isAriaExpandedFalse(node) { if (isPromise(node)) { throw new Error("Node is not defined"); } return await node.evaluate( (element) => element.getAttribute("aria-expanded") === "false" ); } async function getIsCollapsedKeuze(cell_keuze) { if (!isPromise(cell_keuze)) { return await isAriaExpandedFalse(cell_keuze); } else { return false; } } async function getStudName(frame) { const cell = await frame.$(STUDENT_NAME_CELL_SELECTOR); if (!cell) { throw new Error("Cell student name is not defined"); } return await getNodeTextContent(cell); } async function getStudId(frame) { const cell = await frame.$(STUDENT_ID_CELL_SELECTOR); if (!cell) { throw new Error("Cell student id is not defined"); } return await getNodeTextContent(cell); } /** * Checks if the closest parent of the given node contains the 'VZP' string. * * @param {ElementHandle} node - The node to find the closest parent of. * @returns {Promise} True if the closest parent contains 'VZP', false otherwise. */ async function hasVZP(node) { if (isPromise(node) ){ return false; } return await node.evaluate((element) => { let parent = element.closest('table'); if (parent) { return parent.textContent.includes('VZP') ; } return false; }); } module.exports = isStartPakketAvailable;