// Shared test helper — completes the real ROOT 01-04 foundations sequence for a given session. // Phase 6E gave ROOT 01-04 real content, so ROOT 05's own prerequisite (root-04) is no longer // vacuously satisfied: any e2e suite that drives a student into ROOT 05+ content now needs this // as real test setup first (not this file's own subject — see e2e-phase6e.js for the actual // ROOT 01-04 acceptance coverage). Extracted here once other suites needed the identical // sequence, rather than duplicating it in e2e-phase6a/6b/6c/6d.js. async function completeRootFoundations01Through04(session) { async function act(id) { const r = await session.request('POST', `/api/student/activities/${id}/complete`); if (r.status !== 200) throw new Error(`completing ${id} failed: ${r.status} ${JSON.stringify(r.body)}`); } async function scen(sid) { const r = await session.request('POST', '/api/progress/record', { scenario_id: sid, status: 'completed' }); if (r.status !== 200) throw new Error(`completing scenario ${sid} failed: ${r.status}`); } await act('root-01-m01-a01-lesson'); await act('root-01-m01-a02-guided-exercise'); await scen('linux-inspect-hardware'); await act('root-01-m01-a04-reflection'); const l1 = { m02: 'linux-shell-basics', m03: 'linux-filesystem-navigation', m04: 'linux-files-and-text', m05: 'linux-process-management', m06: 'linux-permissions-foundations' }; for (const m of ['m02', 'm03', 'm04', 'm05', 'm06']) { await act(`root-01-${m}-a01-lesson`); await act(`root-01-${m}-a02-demonstration`); await act(`root-01-${m}-a03-knowledge-check`); await act(`root-01-${m}-a04-guided-exercise`); await scen(l1[m]); await act(`root-01-${m}-a06-reflection`); } let r = await session.request('POST', '/api/assessments/rootnode-linux-foundations-assessment/start'); for (const s of r.body.scenarios) await scen(s.scenario_id); await act('root-02-m01-a01-lesson'); await act('root-02-m01-a02-demonstration'); await act('root-02-m01-a03-knowledge-check'); await act('root-02-m01-a04-guided-exercise'); await scen('linux-service-inspection'); await scen('linux-service-lifecycle'); await act('root-02-m01-a07-reflection'); await act('root-02-m02-a01-lesson'); await act('root-02-m02-a02-demonstration'); await act('root-02-m02-a03-knowledge-check'); await act('root-02-m02-a04-guided-exercise'); await scen('linux-storage-inspection'); await act('root-02-m02-a06-reflection'); await act('root-02-m03-a01-lesson'); await act('root-02-m03-a02-demonstration'); await act('root-02-m03-a03-knowledge-check'); await act('root-02-m03-a04-guided-exercise'); await act('root-02-m03-a05-reflection'); await act('root-02-m04-a01-lesson'); await act('root-02-m04-a02-demonstration'); await act('root-02-m04-a03-knowledge-check'); await act('root-02-m04-a04-guided-exercise'); await scen('linux-network-inspection'); await act('root-02-m04-a06-reflection'); await act('root-02-m05-a01-lesson'); await act('root-02-m05-a02-demonstration'); await act('root-02-m05-a03-knowledge-check'); await act('root-02-m05-a04-guided-exercise'); await scen('linux-dns-http-diagnosis'); await act('root-02-m05-a06-reflection'); await act('root-02-m06-a01-lesson'); await act('root-02-m06-a02-demonstration'); await act('root-02-m06-a03-knowledge-check'); await act('root-02-m06-a04-guided-exercise'); await scen('linux-troubleshooting-framework'); await act('root-02-m06-a06-reflection'); r = await session.request('POST', '/api/assessments/rootnode-linux-networking-assessment/start'); for (const s of r.body.scenarios) await scen(s.scenario_id); await act('root-03-m01-a01-lesson'); await act('root-03-m01-a02-knowledge-check'); await act('root-03-m01-a03-reflection'); await act('root-03-m02-a01-lesson'); await act('root-03-m02-a02-demonstration'); await act('root-03-m02-a03-knowledge-check'); await act('root-03-m02-a04-guided-exercise'); await act('root-03-m02-a05-reflection'); await act('root-03-m03-a01-lesson'); await act('root-03-m03-a02-demonstration'); await act('root-03-m03-a03-knowledge-check'); await act('root-03-m03-a04-guided-exercise'); await scen('git-everyday-basics'); await act('root-03-m03-a06-reflection'); await act('root-03-m04-a01-lesson'); await act('root-03-m04-a02-demonstration'); await act('root-03-m04-a03-knowledge-check'); await act('root-03-m04-a04-guided-exercise'); await scen('git-branching-and-merge'); await act('root-03-m04-a06-reflection'); await act('root-03-m05-a01-lesson'); await act('root-03-m05-a02-demonstration'); await act('root-03-m05-a03-knowledge-check'); await act('root-03-m05-a04-guided-exercise'); await scen('git-remote-clone-push'); await act('root-03-m05-a06-reflection'); await act('root-03-m06-a01-lesson'); await act('root-03-m06-a02-demonstration'); await act('root-03-m06-a03-knowledge-check'); await act('root-03-m06-a04-reflection'); r = await session.request('POST', '/api/assessments/rootnode-git-fundamentals-assessment/start'); for (const s of r.body.scenarios) await scen(s.scenario_id); await act('root-04-m01-a01-lesson'); await act('root-04-m01-a02-demonstration'); await act('root-04-m01-a03-knowledge-check'); await act('root-04-m01-a04-reflection'); await act('root-04-m02-a01-lesson'); await act('root-04-m02-a02-demonstration'); await act('root-04-m02-a03-knowledge-check'); await act('root-04-m02-a04-guided-exercise'); await act('root-04-m02-a05-reflection'); const l4 = { m03: 'docker-cli-basics', m04: 'docker-container-networking', m05: 'docker-container-storage', m06: 'docker-build-image', m07: 'docker-compose-multiservice' }; for (const m of ['m03', 'm04', 'm05', 'm06', 'm07']) { await act(`root-04-${m}-a01-lesson`); await act(`root-04-${m}-a02-demonstration`); await act(`root-04-${m}-a03-knowledge-check`); await act(`root-04-${m}-a04-guided-exercise`); await scen(l4[m]); await act(`root-04-${m}-a06-reflection`); } await act('root-04-m08-a01-lesson'); await act('root-04-m08-a02-knowledge-check'); await act('root-04-m08-a03-reflection'); r = await session.request('POST', '/api/assessments/rootnode-containers-assessment/start'); for (const s of r.body.scenarios) await scen(s.scenario_id); } // Completes ROOT 01-04, then ROOT 05 (m00 + m01), then ROOT 06 (m01/m02/m03) fully — the // complete real prerequisite chain any suite needs before touching ROOT 09/10/11 content // (their course-level prerequisite is root-06 complete, or a course chained behind it). async function completeThroughRoot06(session) { await completeRootFoundations01Through04(session); async function act(id) { const r = await session.request('POST', `/api/student/activities/${id}/complete`); if (r.status !== 200) throw new Error(`completing ${id} failed: ${r.status} ${JSON.stringify(r.body)}`); } async function scen(sid) { const r = await session.request('POST', '/api/progress/record', { scenario_id: sid, status: 'completed' }); if (r.status !== 200) throw new Error(`completing scenario ${sid} failed: ${r.status}`); } await act('root-05-m00-a01-lesson-mental-model'); await act('root-05-m00-a02-demonstration-desired-state'); await act('root-05-m00-a03-knowledge-check'); await act('root-05-m00-a04-guided-exercise-namespaces'); await scen('namespaces-basics'); await act('root-05-m00-a06-reflection'); const root05m01Scenarios = ['pod-basics-mcq', 'kubectl-essentials-mcq', 'labels-selectors-mcq', 'init-containers-mcq', 'namespaces-basics', 'multi-container-pod-basics', 'pod-labeling-basics', 'jsonpath-basics', 'dry-run-manifest-basics', 'delete-by-label-basics', 'annotate-resource-basics', 'init-container-task-basics', 'restart-policy-mcq', 'kubectl-output-format-mcq', 'kubectl-explain-basics', 'kubectl-patch-basics', 'field-selector-basics', 'sort-by-basics', 'kubectl-diff-basics', 'static-pods-mcq']; for (const sid of root05m01Scenarios) await scen(sid); await act('root-05-m01-a00-lesson-kubectl-fluency'); await act('root-05-m01-a21-reflection'); for (const sid of ['deploy-nginx', 'scale-deployment', 'rolling-update-task', 'liveness-probe-task', 'jobs-cronjobs-mcq', 'daemonset-mcq', 'edit-deployment-basics', 'deployment-strategy-mcq', 'deployment-rollback']) await scen(sid); await act('root-06-m02-a01-lesson-deployments'); await act('root-06-m02-a02-demonstration-rollout'); await act('root-06-m02-a03-knowledge-check'); await act('root-06-m02-a04-guided-exercise-rollout-strategy'); await act('root-06-m02-a06-reflection'); for (const sid of ['job-task', 'cronjob-task']) await scen(sid); await act('root-06-m03-a01-lesson-jobs-cronjobs-daemonsets'); await act('root-06-m03-a01b-demonstration-job-lifecycle'); await act('root-06-m03-a02-knowledge-check'); await act('root-06-m03-a02b-guided-exercise-choosing-primitive'); await act('root-06-m03-a05-reflection'); } // Completes through ROOT 06, then ROOT 10 (m01/m02/m03) fully — the real prerequisite ROOT 11 // (and anything else chained behind ROOT 10) needs. async function completeThroughRoot10(session) { await completeThroughRoot06(session); async function act(id) { const r = await session.request('POST', `/api/student/activities/${id}/complete`); if (r.status !== 200) throw new Error(`completing ${id} failed: ${r.status} ${JSON.stringify(r.body)}`); } async function scen(sid) { const r = await session.request('POST', '/api/progress/record', { scenario_id: sid, status: 'completed' }); if (r.status !== 200) throw new Error(`completing scenario ${sid} failed: ${r.status}`); } await act('root-10-m01-a01-lesson-health-check-concepts'); await act('root-10-m01-a02-demonstration-probes-in-action'); await act('root-10-m01-a03-knowledge-check'); await act('root-10-m01-a04-guided-exercise-readiness-probe'); await scen('rootnode-probe-port-mismatch'); await act('root-10-m01-a06-reflection-real-ops-takeaway'); await act('root-10-m03-a01-lesson-framework'); await act('root-10-m03-a02-demonstration-crashloop'); await act('root-10-m03-a03-knowledge-check'); await act('root-10-m03-a03b-guided-exercise-endpoint-mismatch'); await scen('crashloop-fix'); await scen('endpoint-fix-task'); await act('root-10-m03-a06-reflection'); for (const sid of ['extract-logs-basics', 'kubectl-cp-basics', 'exec-command-basics', 'node-cordon-basics', 'pod-node-assignment-mcq', 'container-logging-mcq']) await scen(sid); } module.exports = { completeRootFoundations01Through04, completeThroughRoot06, completeThroughRoot10 };