Scrape submitted text for past-due submissions, not just editable ones

Once a submission's due date passes, the legacy homework page renders the
student's text read-only in a `<div class="comment">` that is a sibling
*after* `</section id="submission">`, which then holds only the file list.
`parseHomeworkPage` searched for that div *inside* the submission section, so
for every past-due submission it silently returned no submitted text while
still reporting the grade and feedback — the reader would conclude the student
handed in nothing.

Search the whole page instead. `class="comment"` (quote right after the word)
stays specific: the teacher's feedback is `class="comment ckcontent"` and does
not match, and the editable-textarea branch is still tried first.

Found by standing up a local instance from the deployed images and reading a
real 33.40 page for a seeded past-due submission; the earlier test fixture had
nested the div inside the section, which is why the gap was invisible. The
fixtures now match the real DOM.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-09-13 14:17:14 +02:00
parent ab10bbcd14
commit 290b352b07
2 changed files with 32 additions and 3 deletions

View File

@@ -7,11 +7,12 @@ import { parseHomeworkPage } from '../src/core/homework-page.ts';
* as actually served — including the parts that are absent for a student, which
* is what makes every field optional.
*/
const page = (parts: { submission?: string; feedback?: string }) => `
const page = (parts: { submission?: string; feedback?: string; afterSubmission?: string }) => `
<html><body>
<nav class="nav tab-links"><a href="#activetabid=extended">Details</a></nav>
<section id="extended" class="tab-content">keine Beschreibung vorhanden</section>
<section id="submission" class="tab-content">${parts.submission ?? ''}</section>
${parts.afterSubmission ?? ''}
${parts.feedback === undefined ? '' : `<section id="feedback" class="tab-content">${parts.feedback}</section>`}
</body></html>`;
@@ -39,10 +40,30 @@ describe('parseHomeworkPage', () => {
});
it('reads the typed answer from the read-only form once submission closed', () => {
const html = page({ submission: `<div class="comment"><p>Abgegebener Text</p></div>` });
// The read-only `<div class="comment">` is a sibling *after* the closed
// submission section, not a child of it — verified against a real 33.40
// page for a past-due submission. A fixture that nested it inside the
// section (as an earlier one did) hid a bug where every past-due
// submission lost its text. See src/core/homework-page.ts.
const html = page({
submission: `<section class="files" data-testid="submissions-section-files"></section>`,
afterSubmission: `<div class="comment"><p>Abgegebener Text</p></div>`,
});
assert.equal(parseHomeworkPage(html)?.submittedText, 'Abgegebener Text');
});
it('does not confuse the submitted text with the teacher feedback comment', () => {
// Both are comment divs, distinguished only by the exact class: the
// student's is `class="comment"`, the teacher's `class="comment ckcontent"`.
const html = page({
afterSubmission: `<div class="comment"><p>Meine Abgabe</p></div>`,
feedback: `<div class="comment ckcontent" data-testid="feedback-comment"><p>Gut gemacht</p></div>`,
});
const detail = parseHomeworkPage(html);
assert.equal(detail?.submittedText, 'Meine Abgabe');
assert.equal(detail?.gradeComment, 'Gut gemacht');
});
it('separates submitted files from files the teacher returned', () => {
const html = page({
submission: fileCard('a'.repeat(24), 'meine-abgabe.pdf'),