Retrieve and structurally extract a candidate's WAEC Ghana examination result from the official checker. Include candidate details, examination centre, card usage, subjects, grades, interpretations, disclaimers, visible errors, and screenshot/PDF artifacts when requested.
Use Cases
Use when the caller provides the candidate/index number, examination type, examination year, voucher serial number, PIN, and confirmation candidate number required by the form.
Automation Flow
- Navigate directly to
https://ghana.waecdirect.org/and populate the legacy form in one browser batch:input#candid={candidate-number}select#examtype={exam-type-code}; WASSCE School is01select#examyear={exam-year}input#serial={serial-number}input#pin={pin}input#ccandid={candidate-number}select[name='cexamyear']orselect#select={exam-year}- Leave the date-of-birth controls blank for WASSCE School unless the site explicitly requires them.
- Submit
input[name='Submit']. For WASSCE School, wait for the jQuery UI dialog[role='dialog'], then activate the button whose trimmed visible text is exactlyAgree. The dialog's handler opens a named popupresultsand submits the form toresults.asp. If the dialog closes without submitting, submit the form once more after agreement. - Capture the newly opened same-site popup, excluding the opener. Prefer the page whose URL is
https://ghana.waecdirect.org/displayresults.asp; otherwise identify it by titleWAECDIRECT ONLINE INFORMATION SERVICE - RESULTSor body text containingCandidate's Details,Result Checking, orIndex Number. Wait for its result table before extracting. - Bring the result popup to the front. For screenshots or PDF generation, request the browser-level maximize/window-management operation; a page-side
window.moveTo(0,0); window.resizeTo(screen.availWidth,screen.availHeight)attempt is only a best effort. - Run this evaluator once in the loaded result-popup page context:
(() => {
const clean = (value) => (value || "").replace(/\s+/g, " ").trim();
const rows = [...document.querySelectorAll("table tr")]
.map((tr) =>
[...tr.querySelectorAll(":scope > th, :scope > td")].map((cell) =>
clean(cell.innerText),
),
)
.filter((row) => row.some(Boolean));
const findValue = (label) => {
const row = rows.find(
(r) => r.length >= 2 && clean(r[0]).toLowerCase() === label.toLowerCase(),
);
return row ? clean(row.slice(1).join(" ")) : "";
};
const cardStart = rows.findIndex((r) =>
r.some((c) => c.toLowerCase() === "card details"),
);
const resultStart = rows.findIndex((r) =>
r.some((c) => c.toLowerCase() === "results"),
);
const cardEnd = resultStart > cardStart ? resultStart : rows.length;
const cardDetails =
cardStart >= 0
? rows
.slice(cardStart + 1, cardEnd)
.filter((r) => r.length >= 2)
.map((r) => ({ label: r[0], value: clean(r.slice(1).join(" ")) }))
: [];
const results =
resultStart >= 0
? rows
.slice(resultStart + 1)
.filter(
(r) =>
r.length >= 3 &&
r[0] &&
r[1] &&
r[2] &&
!r[0].toLowerCase().includes("click to print"),
)
.map((r) => ({
subject: r[0],
grade: r[1],
interpretation: clean(r.slice(2).join(" ")),
}))
: [];
const disclaimer = [...document.querySelectorAll(".disclaimer")]
.map((e) => clean(e.innerText))
.filter(Boolean);
const errorMessages = [
...document.querySelectorAll(
'.error, .errors, [class*="error"], [id*="error"], [role="alert"]',
),
]
.map((e) => clean(e.innerText))
.filter(Boolean);
return {
url: location.href,
title: document.title,
viewport: { width: innerWidth, height: innerHeight },
candidate: {
indexNumber: findValue("Index Number"),
candidateName: findValue("Candidate Name"),
examType: findValue("Type of Examination"),
examinationCentre: findValue("Examination Centre"),
},
cardDetails,
results,
disclaimer,
errorMessages,
text: clean(document.body.innerText),
tables: rows,
};
})();- If requested, capture a screenshot of the result popup after maximizing it. For PDF output, use the result page's
a[href='javascript:window.print()']link or browser print-to-PDF facility, and report the saved artifact or any print/PDF failure.
Possible Friction Points
- The checker is a legacy POST form whose action is
/results.asp; the final result is normally returned at/displayresults.asp. Do not fabricate a direct result URL or omit the POST/session flow. - Form controls submit option values rather than labels. WASSCE School is exam-type value
01. - The candidate/index number must be entered in both
#candidand#ccandid, and the year must be entered in both examination-year selectors. - The agreement is a jQuery UI modal. Locate
Agreeby exact visible text rather than button position; the dialog may render only after a short delay. - Submission opens a small named popup
results; popup detection should exclude the opener and tolerate an initially blank URL before navigation to/displayresults.asp. - The result page uses nested legacy tables. Candidate metadata and card details occur before the
Resultsheading; subject rows contain subject, grade, and interpretation. Preserve values such asXandABSENT. - The result page clears the PIN and confirmation fields in the opener after loading. Never return the PIN or voucher serial in extracted output unless explicitly requested.
- The print link commonly invokes
javascript:window.print(). Browser print dialogs, popup creation, viewport maximization, and PDF support vary by environment. - The evaluator reads only the current result page and performs no network requests.