Compare commits

...

3 Commits

6 changed files with 180 additions and 12 deletions

13
config.js Normal file
View File

@ -0,0 +1,13 @@
module.exports = {
excelFilename: "DashboardResults.xlsx",
//Selectors for the dashboard page
tableBodySelector: "#QQ_RPT_OIS_TEMP\\$scroll\\$0 tbody",
iframeSelector: 'iframe[title="Hoofdinhoud"]',
//Selectors for the AA-page
uitvouwenSelector: 'input[id="DERIVED_SAA_DPR_SSS_EXPAND_ALL"]',
collapsArrowSelector:'a.PSHYPERLINK.PTCOLLAPSE_ARROW',
excludeFromCollapsingSelector: 'a[title="Sectie samenvouwen AFSTUDEERVEREISTEN BACHELOR GESCHIEDENIS"]',
excludedTitle: 'Sectie samenvouwen AFSTUDEERVEREISTEN BACHELOR GESCHIEDENIS',
}

108
coursesEnrolled.js Normal file
View File

@ -0,0 +1,108 @@
const puppeteer = require('puppeteer');
const IFRAME_SELECTOR = 'iframe[title="Hoofdinhoud"]';
const wait = require("./wait");
const config = require("./config.js");
//Er zijn een aantal helperfuncties die nog verwijderd moeten worden
//zo is de functie van de contentFrame te verwijderen want staat dubbel in evaluatestartpakket.js
//de iframeselector is eveneens van belang om te verwijderen want staat ook dubbel in evaluatestartpakket.js
async function coursesEnrolled(page) {
/*connection to local host
const browser = await puppeteer.connect({
browserURL: "http://localhost:9222", // Connect to the browser's debugging address
});
// Get all open pages (tabs)
const pages = await browser.pages();
console.log(`Found ${pages.length} open pages on the browser.`);
// Interact with the last tab (or any tab of choice)
let page = pages[pages.length - 1]; // Choose the last opened tab
console.log("Current URL:", page.url()); */
let contentFrame= await getContentFrame(page);
const uitvouwenButton = await contentFrame.$(config.uitvouwenSelector);
if (uitvouwenButton) {
await uitvouwenButton.click();
console.log("uitvouwen button clicked");
await wait(2000);
contentFrame= await getContentFrame(page)
}
//logic to collapse all sections except the one with the excluded title
const collapseArrows = await contentFrame.$$(config.collapsArrowSelector);
const excludedArrow = await contentFrame.$(config.excludeFromCollapsingSelector);
const excludedTbody = await excludedArrow.evaluate(el => el.closest('tbody'));
for (const arrow of collapseArrows) {
const isExcluded = await arrow.evaluate((el, excludedTbody) => {
const title = el.getAttribute('title');
const tbody = el.closest('tbody');
return title === 'Sectie samenvouwen AFSTUDEERVEREISTEN BACHELOR GESCHIEDENIS' || tbody === excludedTbody;
}, excludedTbody);
if (!isExcluded) {
const isStillInDOM = await arrow.evaluate(el => document.body.contains(el));
if (isStillInDOM) {
await arrow.click();
await wait(500); // Adjust the wait time as needed
}
}
}
contentFrame= await getContentFrame(page)
const rowData = await contentFrame.$$eval(
'span',
(spans) => {
const uniqueEntries = new Set();
return spans
.filter((span) => span.innerText.trim().includes('Academiejaar'))
.map((span) => {
const tr = span.closest('tr');
if (!tr) return null;
const tds = tr.querySelectorAll('td');
const getInnerHtml = (element) => {
const aElement = element.querySelector('a');
return aElement ? aElement.innerHTML.trim() : element.innerHTML.trim();
};
const studiegidsNummer = tds[0] ? getInnerHtml(tds[0].querySelector('span')) : '';
const opleidingsOnderdeel = tds[1] ? getInnerHtml(tds[1].querySelector('span')) : '';
const studiepunten = tds[2] ? getInnerHtml(tds[2].querySelector('span')) : '';
if (uniqueEntries.has(studiegidsNummer)) return null;
uniqueEntries.add(studiegidsNummer);
return {
studiegidsNummer,
opleidingsOnderdeel,
studiepunten,
};
})
.filter((entry) => entry);
}
);
const totalStudiepunten = sumStudiepunten(rowData);
return {rowData, totalStudiepunten};
}
function sumStudiepunten(rowData) {
return rowData.reduce((total, row) => {
const studiepunten = parseFloat(row.studiepunten) || 0;
return total + studiepunten;
}, 0);
}
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();
}
module.exports = coursesEnrolled;

View File

@ -2,6 +2,7 @@
open chrome in debug modus open chrome in debug modus
start chrome --remote-debugging-port=9222 --user-data-dir="C:\ChromeDebug" start chrome --remote-debugging-port=9222 --user-data-dir="C:\ChromeDebug"
navigeer naar het dashboard en roep de lijst met startpakket studenten op die relevant zijn voor de test navigeer naar het dashboard en roep de lijst met startpakket studenten op die relevant zijn voor de test
wees er zeker van dat de tab waarin je moet werken de meest rechtse tab is in de tabbladenbalk
start dan het script start dan het script
*/ */
const puppeteer = require("puppeteer"); const puppeteer = require("puppeteer");
@ -10,11 +11,14 @@ const fs = require("fs");
const saveResultsToExcel = require("./saveResultsToExcel"); const saveResultsToExcel = require("./saveResultsToExcel");
const appendToExcel = require("./appendResultsToExcel"); const appendToExcel = require("./appendResultsToExcel");
const wait = require("./wait"); const wait = require("./wait");
const courseEnrolled = require("./coursesEnrolled");
const parseCourseResults = require('./utils/parseCourseResults');
const config = require("./config.js");
async function iterateOverDashboardTable() { async function iterateOverDashboardTable() {
/*connection to local host */ /*connection to local host */
const browser = await puppeteer.connect({ const browser = await puppeteer.connect({
browserURL: "http://localhost:9222", // Connect to the browser's debugging address browserURL: "http://localhost:9222"
}); });
//array to store results for Excel export //array to store results for Excel export
@ -31,7 +35,7 @@ async function iterateOverDashboardTable() {
// Select the table body by ID // Select the table body by ID
const iframeElement = await page.waitForSelector( const iframeElement = await page.waitForSelector(
'iframe[title="Hoofdinhoud"]' config.iframeSelector
); );
const iframe = await iframeElement.contentFrame(); const iframe = await iframeElement.contentFrame();
@ -40,11 +44,8 @@ async function iterateOverDashboardTable() {
return; return;
} }
// Select the table body within the iframe
const tableBodySelector = "#QQ_RPT_OIS_TEMP\\$scroll\\$0 tbody";
// Check if the table exists inside the iframe // Check if the table exists inside the iframe
const tableExists = await iframe.$(tableBodySelector); const tableExists = await iframe.$(config.tableBodySelector);
if (!tableExists) { if (!tableExists) {
console.log("Table not found inside iframe!"); console.log("Table not found inside iframe!");
return; return;
@ -53,7 +54,7 @@ async function iterateOverDashboardTable() {
// Get all rows within the table body // Get all rows within the table body
const links = await iframe.$$( const links = await iframe.$$(
`${tableBodySelector} tr span[title="AA-rapport"] a` `${config.tableBodySelector} tr span[title="AA-rapport"] a`
); );
console.log(`Found ${links.length} AA-links to process.`); console.log(`Found ${links.length} AA-links to process.`);
@ -68,12 +69,12 @@ async function iterateOverDashboardTable() {
console.log(`Processing link ${i + 1}`); console.log(`Processing link ${i + 1}`);
const iframeElement = await page.waitForSelector( const iframeElement = await page.waitForSelector(
'iframe[title="Hoofdinhoud"]' config.iframeSelector
); );
const iframe = await iframeElement.contentFrame(); const iframe = await iframeElement.contentFrame();
const links = await iframe.$$( const links = await iframe.$$(
`${tableBodySelector} tr span[title="AA-rapport"] a` `${config.tableBodySelector} tr span[title="AA-rapport"] a`
); );
// Get the parent row of the current link // Get the parent row of the current link
const parentRow = await links[i].evaluateHandle((link) => const parentRow = await links[i].evaluateHandle((link) =>
@ -109,6 +110,7 @@ async function iterateOverDashboardTable() {
try { try {
const evaluationResult = await isStartPakketAvailable(newPage); const evaluationResult = await isStartPakketAvailable(newPage);
const coursesResult = await courseEnrolled(newPage)
//Save results for Excel //Save results for Excel
result = { result = {
@ -119,8 +121,11 @@ async function iterateOverDashboardTable() {
IsCollapsedKeuze: evaluationResult.isCollapsed_keuze ? "Yes" : "No", IsCollapsedKeuze: evaluationResult.isCollapsed_keuze ? "Yes" : "No",
IsCollapsedMain: evaluationResult.isCollapsed_main ? "Yes" : "No", IsCollapsedMain: evaluationResult.isCollapsed_main ? "Yes" : "No",
ContainsVZP: evaluationResult.containsVZP ? "Yes" : "No", ContainsVZP: evaluationResult.containsVZP ? "Yes" : "No",
ContainsVZPKeuze: evaluationResult.containsVZP_keuze ? "Yes" : "No" ContainsVZPKeuze: evaluationResult.containsVZP_keuze ? "Yes" : "No",
coursesResult: parseCourseResults(coursesResult.rowData),
totalStudiepunten: coursesResult.totalStudiepunten
}; };
console.log("Courses enrolled: ", coursesResult.rowData);
console.log(`Link ${i + 1} processed successfully.`); console.log(`Link ${i + 1} processed successfully.`);
} catch (error) { } catch (error) {
console.error(`Error processing link ${i + 1}:`, error.message); console.error(`Error processing link ${i + 1}:`, error.message);
@ -143,8 +148,9 @@ async function iterateOverDashboardTable() {
appendToExcel(result, filename); appendToExcel(result, filename);
} }
console.log("All links processed."); console.log("All links processed.");
saveResultsToExcel(results, "DashboardResults.xlsx"); saveResultsToExcel(results, config.excelFilename);
console.log("Results saved successfully to DashboardResults.xlsx"); console.log("Results saved successfully to DashboardResults.xlsx");
} }

View File

@ -1,7 +1,28 @@
const xlsx = require("xlsx"); const xlsx = require("xlsx");
function saveResultsToExcel(data, filename) { function saveResultsToExcel(data, filename) {
const workbook = xlsx.utils.book_new(); // Create a new workbook const workbook = xlsx.utils.book_new(); // Create a new workbook
const worksheet = xlsx.utils.json_to_sheet(data); // Convert data to worksheet const worksheetData = [];
data.forEach(item => {
const courses = item.coursesResult.split('. ').filter(course => course.trim() !== '');
courses.forEach(course => {
worksheetData.push({
LinkNumber: item.LinkNumber,
StudentName: item.StudentName,
StudentID: item.StudentID,
IsCollapsed: item.IsCollapsed,
IsCollapsedKeuze: item.IsCollapsedKeuze,
IsCollapsedMain: item.IsCollapsedMain,
ContainsVZP: item.ContainsVZP,
ContainsVZPKeuze: item.ContainsVZPKeuze,
Course: course.trim(),
TotalStudiepunten: item.totalStudiepunten
});
});
});
const worksheet = xlsx.utils.json_to_sheet(worksheetData); // Convert data to worksheet
xlsx.utils.book_append_sheet(workbook, worksheet, "Results"); // Add worksheet to workbook xlsx.utils.book_append_sheet(workbook, worksheet, "Results"); // Add worksheet to workbook
// Write workbook to file // Write workbook to file

7
todo.md Normal file
View File

@ -0,0 +1,7 @@
# TODO
## High Priority
- [ ] adviesrapport geeft geen buizen weer voor het huidige aj. Vakken verschijnen dan ook niet in de functie
coursesenrolled. Hoe oplossen? Rapport deliberatie?
- dit is eig geen probleem voor het begin van het aj wanneer nog geen examenperiode heeft
plaatsgevonden.

View File

@ -0,0 +1,13 @@
const parseCourseResults = (listOfObj) => {
result = listOfObj.map(obj => {
const studiegidsNummer = obj.studiegidsNummer.slice(-10);
return `${studiegidsNummer} ${obj.opleidingsOnderdeel} - ${obj.studiepunten}SP, `;
});
return result.join("\n");
}
module.exports = parseCourseResults;