@falkenslab/moodle-driver 0.0.0-stage → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +131 -2
- package/dist/areas/activities/build.d.ts +98 -0
- package/dist/areas/activities/build.js +248 -0
- package/dist/areas/activities/build.js.map +1 -0
- package/dist/areas/activities/content.d.ts +53 -0
- package/dist/areas/activities/content.js +113 -0
- package/dist/areas/activities/content.js.map +1 -0
- package/dist/areas/assignments/grader.d.ts +68 -0
- package/dist/areas/assignments/grader.js +169 -0
- package/dist/areas/assignments/grader.js.map +1 -0
- package/dist/areas/assignments/grading.d.ts +86 -0
- package/dist/areas/assignments/grading.js +162 -0
- package/dist/areas/assignments/grading.js.map +1 -0
- package/dist/areas/assignments/student.d.ts +57 -0
- package/dist/areas/assignments/student.js +115 -0
- package/dist/areas/assignments/student.js.map +1 -0
- package/dist/areas/calendar/calendar.d.ts +43 -0
- package/dist/areas/calendar/calendar.js +84 -0
- package/dist/areas/calendar/calendar.js.map +1 -0
- package/dist/areas/completion/completion.d.ts +50 -0
- package/dist/areas/completion/completion.js +112 -0
- package/dist/areas/completion/completion.js.map +1 -0
- package/dist/areas/courses/list.d.ts +59 -0
- package/dist/areas/courses/list.js +74 -0
- package/dist/areas/courses/list.js.map +1 -0
- package/dist/areas/courses/overview.d.ts +83 -0
- package/dist/areas/courses/overview.js +137 -0
- package/dist/areas/courses/overview.js.map +1 -0
- package/dist/areas/courses/state.d.ts +51 -0
- package/dist/areas/courses/state.js +45 -0
- package/dist/areas/courses/state.js.map +1 -0
- package/dist/areas/courses/structure.d.ts +89 -0
- package/dist/areas/courses/structure.js +104 -0
- package/dist/areas/courses/structure.js.map +1 -0
- package/dist/areas/forums/discussions.d.ts +57 -0
- package/dist/areas/forums/discussions.js +119 -0
- package/dist/areas/forums/discussions.js.map +1 -0
- package/dist/areas/forums/posts.d.ts +83 -0
- package/dist/areas/forums/posts.js +114 -0
- package/dist/areas/forums/posts.js.map +1 -0
- package/dist/areas/grades/gradebook.d.ts +104 -0
- package/dist/areas/grades/gradebook.js +250 -0
- package/dist/areas/grades/gradebook.js.map +1 -0
- package/dist/areas/grades/user-report.d.ts +26 -0
- package/dist/areas/grades/user-report.js +71 -0
- package/dist/areas/grades/user-report.js.map +1 -0
- package/dist/areas/h5p/h5p.d.ts +33 -0
- package/dist/areas/h5p/h5p.js +104 -0
- package/dist/areas/h5p/h5p.js.map +1 -0
- package/dist/areas/lessons/lessons.d.ts +60 -0
- package/dist/areas/lessons/lessons.js +145 -0
- package/dist/areas/lessons/lessons.js.map +1 -0
- package/dist/areas/messages/messages.d.ts +68 -0
- package/dist/areas/messages/messages.js +84 -0
- package/dist/areas/messages/messages.js.map +1 -0
- package/dist/areas/participants/participants.d.ts +57 -0
- package/dist/areas/participants/participants.js +135 -0
- package/dist/areas/participants/participants.js.map +1 -0
- package/dist/areas/questions/banks.d.ts +83 -0
- package/dist/areas/questions/banks.js +239 -0
- package/dist/areas/questions/banks.js.map +1 -0
- package/dist/areas/quizzes/attempts.d.ts +123 -0
- package/dist/areas/quizzes/attempts.js +300 -0
- package/dist/areas/quizzes/attempts.js.map +1 -0
- package/dist/areas/quizzes/results.d.ts +36 -0
- package/dist/areas/quizzes/results.js +93 -0
- package/dist/areas/quizzes/results.js.map +1 -0
- package/dist/areas/quizzes/structure.d.ts +42 -0
- package/dist/areas/quizzes/structure.js +100 -0
- package/dist/areas/quizzes/structure.js.map +1 -0
- package/dist/areas/scorm/scorm.d.ts +60 -0
- package/dist/areas/scorm/scorm.js +171 -0
- package/dist/areas/scorm/scorm.js.map +1 -0
- package/dist/areas/site/info.d.ts +25 -0
- package/dist/areas/site/info.js +45 -0
- package/dist/areas/site/info.js.map +1 -0
- package/dist/areas/site/users.d.ts +56 -0
- package/dist/areas/site/users.js +89 -0
- package/dist/areas/site/users.js.map +1 -0
- package/dist/areas/surveys/choice.d.ts +38 -0
- package/dist/areas/surveys/choice.js +105 -0
- package/dist/areas/surveys/choice.js.map +1 -0
- package/dist/areas/surveys/surveys.d.ts +51 -0
- package/dist/areas/surveys/surveys.js +201 -0
- package/dist/areas/surveys/surveys.js.map +1 -0
- package/dist/browser/chromium.d.ts +15 -0
- package/dist/browser/chromium.js +53 -0
- package/dist/browser/chromium.js.map +1 -0
- package/dist/browser/cookies.d.ts +11 -0
- package/dist/browser/cookies.js +31 -0
- package/dist/browser/cookies.js.map +1 -0
- package/dist/browser/manager.d.ts +57 -0
- package/dist/browser/manager.js +177 -0
- package/dist/browser/manager.js.map +1 -0
- package/dist/browser.d.ts +53 -0
- package/dist/browser.js +167 -0
- package/dist/browser.js.map +1 -0
- package/dist/categories.d.ts +28 -0
- package/dist/categories.js +225 -0
- package/dist/categories.js.map +1 -0
- package/dist/chromiumInstaller.d.ts +15 -0
- package/dist/chromiumInstaller.js +52 -0
- package/dist/chromiumInstaller.js.map +1 -0
- package/dist/cli/args.d.ts +33 -0
- package/dist/cli/args.js +194 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/commands.generated.d.ts +4 -0
- package/dist/cli/commands.generated.js +2217 -0
- package/dist/cli/commands.generated.js.map +1 -0
- package/dist/cli/config.d.ts +46 -0
- package/dist/cli/config.js +107 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/main.d.ts +2 -0
- package/dist/cli/main.js +19 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/output.d.ts +4 -0
- package/dist/cli/output.js +71 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/cli/run.d.ts +15 -0
- package/dist/cli/run.js +194 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli/spec.d.ts +42 -0
- package/dist/cli/spec.js +4 -0
- package/dist/cli/spec.js.map +1 -0
- package/dist/client.d.ts +224 -0
- package/dist/client.js +182 -0
- package/dist/client.js.map +1 -0
- package/dist/core/ajax.d.ts +25 -0
- package/dist/core/ajax.js +85 -0
- package/dist/core/ajax.js.map +1 -0
- package/dist/core/editor.d.ts +18 -0
- package/dist/core/editor.js +51 -0
- package/dist/core/editor.js.map +1 -0
- package/dist/core/errors.d.ts +12 -0
- package/dist/core/errors.js +10 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/files.d.ts +16 -0
- package/dist/core/files.js +58 -0
- package/dist/core/files.js.map +1 -0
- package/dist/core/forms.d.ts +45 -0
- package/dist/core/forms.js +200 -0
- package/dist/core/forms.js.map +1 -0
- package/dist/core/http.d.ts +18 -0
- package/dist/core/http.js +22 -0
- package/dist/core/http.js.map +1 -0
- package/dist/core/inPage.d.ts +8 -0
- package/dist/core/inPage.js +10 -0
- package/dist/core/inPage.js.map +1 -0
- package/dist/core/login.d.ts +40 -0
- package/dist/core/login.js +83 -0
- package/dist/core/login.js.map +1 -0
- package/dist/core/pace.d.ts +4 -0
- package/dist/core/pace.js +21 -0
- package/dist/core/pace.js.map +1 -0
- package/dist/core/session.d.ts +55 -0
- package/dist/core/session.js +157 -0
- package/dist/core/session.js.map +1 -0
- package/dist/core/site.d.ts +8 -0
- package/dist/core/site.js +36 -0
- package/dist/core/site.js.map +1 -0
- package/dist/core/text.d.ts +21 -0
- package/dist/core/text.js +113 -0
- package/dist/core/text.js.map +1 -0
- package/dist/home.d.ts +19 -0
- package/dist/home.js +54 -0
- package/dist/home.js.map +1 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.js +52 -0
- package/dist/index.js.map +1 -0
- package/dist/internals.d.ts +11 -0
- package/dist/internals.js +15 -0
- package/dist/internals.js.map +1 -0
- package/dist/moodle/activities.d.ts +94 -0
- package/dist/moodle/activities.js +240 -0
- package/dist/moodle/activities.js.map +1 -0
- package/dist/moodle/ajax.d.ts +22 -0
- package/dist/moodle/ajax.js +91 -0
- package/dist/moodle/ajax.js.map +1 -0
- package/dist/moodle/assign.d.ts +65 -0
- package/dist/moodle/assign.js +162 -0
- package/dist/moodle/assign.js.map +1 -0
- package/dist/moodle/calendar.d.ts +41 -0
- package/dist/moodle/calendar.js +80 -0
- package/dist/moodle/calendar.js.map +1 -0
- package/dist/moodle/choice.d.ts +33 -0
- package/dist/moodle/choice.js +100 -0
- package/dist/moodle/choice.js.map +1 -0
- package/dist/moodle/completion.d.ts +48 -0
- package/dist/moodle/completion.js +108 -0
- package/dist/moodle/completion.js.map +1 -0
- package/dist/moodle/content.d.ts +43 -0
- package/dist/moodle/content.js +105 -0
- package/dist/moodle/content.js.map +1 -0
- package/dist/moodle/course.d.ts +51 -0
- package/dist/moodle/course.js +45 -0
- package/dist/moodle/course.js.map +1 -0
- package/dist/moodle/courses.d.ts +57 -0
- package/dist/moodle/courses.js +70 -0
- package/dist/moodle/courses.js.map +1 -0
- package/dist/moodle/editor.d.ts +18 -0
- package/dist/moodle/editor.js +50 -0
- package/dist/moodle/editor.js.map +1 -0
- package/dist/moodle/files.d.ts +16 -0
- package/dist/moodle/files.js +57 -0
- package/dist/moodle/files.js.map +1 -0
- package/dist/moodle/forms.d.ts +44 -0
- package/dist/moodle/forms.js +199 -0
- package/dist/moodle/forms.js.map +1 -0
- package/dist/moodle/forum.d.ts +55 -0
- package/dist/moodle/forum.js +115 -0
- package/dist/moodle/forum.js.map +1 -0
- package/dist/moodle/forumPosts.d.ts +83 -0
- package/dist/moodle/forumPosts.js +113 -0
- package/dist/moodle/forumPosts.js.map +1 -0
- package/dist/moodle/gradebook.d.ts +102 -0
- package/dist/moodle/gradebook.js +246 -0
- package/dist/moodle/gradebook.js.map +1 -0
- package/dist/moodle/grades.d.ts +24 -0
- package/dist/moodle/grades.js +67 -0
- package/dist/moodle/grades.js.map +1 -0
- package/dist/moodle/grading.d.ts +92 -0
- package/dist/moodle/grading.js +161 -0
- package/dist/moodle/grading.js.map +1 -0
- package/dist/moodle/h5p.d.ts +31 -0
- package/dist/moodle/h5p.js +100 -0
- package/dist/moodle/h5p.js.map +1 -0
- package/dist/moodle/inPage.d.ts +8 -0
- package/dist/moodle/inPage.js +10 -0
- package/dist/moodle/inPage.js.map +1 -0
- package/dist/moodle/lesson.d.ts +57 -0
- package/dist/moodle/lesson.js +140 -0
- package/dist/moodle/lesson.js.map +1 -0
- package/dist/moodle/login.d.ts +37 -0
- package/dist/moodle/login.js +77 -0
- package/dist/moodle/login.js.map +1 -0
- package/dist/moodle/messages.d.ts +66 -0
- package/dist/moodle/messages.js +80 -0
- package/dist/moodle/messages.js.map +1 -0
- package/dist/moodle/overview.d.ts +83 -0
- package/dist/moodle/overview.js +137 -0
- package/dist/moodle/overview.js.map +1 -0
- package/dist/moodle/pace.d.ts +4 -0
- package/dist/moodle/pace.js +19 -0
- package/dist/moodle/pace.js.map +1 -0
- package/dist/moodle/participants.d.ts +55 -0
- package/dist/moodle/participants.js +131 -0
- package/dist/moodle/participants.js.map +1 -0
- package/dist/moodle/questionBank.d.ts +81 -0
- package/dist/moodle/questionBank.js +235 -0
- package/dist/moodle/questionBank.js.map +1 -0
- package/dist/moodle/quiz.d.ts +117 -0
- package/dist/moodle/quiz.js +291 -0
- package/dist/moodle/quiz.js.map +1 -0
- package/dist/moodle/quizResults.d.ts +36 -0
- package/dist/moodle/quizResults.js +93 -0
- package/dist/moodle/quizResults.js.map +1 -0
- package/dist/moodle/quizStructure.d.ts +42 -0
- package/dist/moodle/quizStructure.js +100 -0
- package/dist/moodle/quizStructure.js.map +1 -0
- package/dist/moodle/session.d.ts +39 -0
- package/dist/moodle/session.js +99 -0
- package/dist/moodle/session.js.map +1 -0
- package/dist/moodle/site.d.ts +8 -0
- package/dist/moodle/site.js +36 -0
- package/dist/moodle/site.js.map +1 -0
- package/dist/moodle/siteInfo.d.ts +25 -0
- package/dist/moodle/siteInfo.js +45 -0
- package/dist/moodle/siteInfo.js.map +1 -0
- package/dist/moodle/structure.d.ts +94 -0
- package/dist/moodle/structure.js +103 -0
- package/dist/moodle/structure.js.map +1 -0
- package/dist/moodle/submission.d.ts +48 -0
- package/dist/moodle/submission.js +109 -0
- package/dist/moodle/submission.js.map +1 -0
- package/dist/moodle/survey.d.ts +47 -0
- package/dist/moodle/survey.js +197 -0
- package/dist/moodle/survey.js.map +1 -0
- package/dist/moodle/text.d.ts +21 -0
- package/dist/moodle/text.js +113 -0
- package/dist/moodle/text.js.map +1 -0
- package/dist/moodle/user.d.ts +54 -0
- package/dist/moodle/user.js +78 -0
- package/dist/moodle/user.js.map +1 -0
- package/dist/options.d.ts +30 -0
- package/dist/options.js +35 -0
- package/dist/options.js.map +1 -0
- package/dist/sessionCookies.d.ts +11 -0
- package/dist/sessionCookies.js +31 -0
- package/dist/sessionCookies.js.map +1 -0
- package/dist/testing/fakeMoodle.d.ts +55 -0
- package/dist/testing/fakeMoodle.js +103 -0
- package/dist/testing/fakeMoodle.js.map +1 -0
- package/dist/testing/gradingPanel.d.ts +6 -0
- package/dist/testing/gradingPanel.js +22 -0
- package/dist/testing/gradingPanel.js.map +1 -0
- package/dist/testing/index.d.ts +5 -0
- package/dist/testing/index.js +18 -0
- package/dist/testing/index.js.map +1 -0
- package/package.json +78 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"choice.js","sourceRoot":"","sources":["../../../src/areas/surveys/choice.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { BrowserContext, Page } from "playwright-core";
|
|
2
|
+
import { MoodleError } from "../../core/errors.js";
|
|
3
|
+
/** The two survey modules: the questionnaire plugin (mod_questionnaire) and Moodle's feedback. */
|
|
4
|
+
export type SurveyType = "questionnaire" | "feedback";
|
|
5
|
+
export declare class SurveyError extends MoodleError {
|
|
6
|
+
name: string;
|
|
7
|
+
constructor(message: string);
|
|
8
|
+
}
|
|
9
|
+
/** One field of a survey question, by its form name. */
|
|
10
|
+
export interface SurveyField {
|
|
11
|
+
name: string;
|
|
12
|
+
kind: "choice" | "checkbox" | "text" | "select";
|
|
13
|
+
label?: string;
|
|
14
|
+
options?: {
|
|
15
|
+
value: string;
|
|
16
|
+
label: string;
|
|
17
|
+
}[];
|
|
18
|
+
value?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface SurveyQuestion {
|
|
21
|
+
page: number;
|
|
22
|
+
number?: string;
|
|
23
|
+
text: string;
|
|
24
|
+
required: boolean;
|
|
25
|
+
fields: SurveyField[];
|
|
26
|
+
}
|
|
27
|
+
/** The questions on a survey page, with their fields read from the form (names, options, labels). */
|
|
28
|
+
export declare function readSurveyPage(page: Page, type: SurveyType, pageNumber: number): Promise<SurveyQuestion[]>;
|
|
29
|
+
/** Which survey module an activity is, from the page each module answers with its own view (body id). */
|
|
30
|
+
export declare function surveyType(context: BrowserContext, siteUrl: string, activityId: number): Promise<SurveyType>;
|
|
31
|
+
/** A survey (questionnaire or feedback): whether it can be answered, its intro and messages, and its questions page by page. Its module is found when not given. */
|
|
32
|
+
export declare function getSurvey(context: BrowserContext, siteUrl: string, activityId: number, type?: SurveyType): Promise<{
|
|
33
|
+
questions: SurveyQuestion[];
|
|
34
|
+
canAnswer: boolean;
|
|
35
|
+
intro: string;
|
|
36
|
+
messages: string[];
|
|
37
|
+
}>;
|
|
38
|
+
/**
|
|
39
|
+
* Fills the survey page by page with `responses` (field name → value) and submits it on the last
|
|
40
|
+
* page. Every name is checked against the form first, so nothing is sent with a wrong one.
|
|
41
|
+
*/
|
|
42
|
+
export declare function submitSurvey(context: BrowserContext, siteUrl: string, activityId: number, type: SurveyType, responses: Record<string, string>): Promise<{
|
|
43
|
+
changed: string;
|
|
44
|
+
messages: string[];
|
|
45
|
+
}>;
|
|
46
|
+
export declare function submitSurvey(context: BrowserContext, siteUrl: string, activityId: number, responses: Record<string, string>, options?: {
|
|
47
|
+
type?: SurveyType;
|
|
48
|
+
}): Promise<{
|
|
49
|
+
changed: string;
|
|
50
|
+
messages: string[];
|
|
51
|
+
}>;
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { setFields } from "../../core/forms.js";
|
|
2
|
+
import { inPage } from "../../core/inPage.js";
|
|
3
|
+
import { openSitePage } from "../../core/session.js";
|
|
4
|
+
import { MoodleError } from "../../core/errors.js";
|
|
5
|
+
export class SurveyError extends MoodleError {
|
|
6
|
+
name = "SurveyError";
|
|
7
|
+
constructor(message) {
|
|
8
|
+
super(message, "survey");
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/** Where each module keeps its form, its questions, their text and their "required" mark. */
|
|
12
|
+
const LAYOUT = {
|
|
13
|
+
questionnaire: { form: "#phpesp_response", question: "fieldset.qn-container", text: ".qn-question", required: "img.req", number: ".qn-number", next: "next", finish: "submit" },
|
|
14
|
+
feedback: { form: "form.feedback_form", question: ".feedback_itemlist", text: ".col-form-label", required: ".col-form-label .text-danger", number: ".itemnr", next: "gonextpage", finish: "savevalues" },
|
|
15
|
+
};
|
|
16
|
+
/** The questions on a survey page, with their fields read from the form (names, options, labels). */
|
|
17
|
+
export function readSurveyPage(page, type, pageNumber) {
|
|
18
|
+
return inPage(page, ({ layout, pageNumber }) => {
|
|
19
|
+
const doc = globalThis.document;
|
|
20
|
+
// Text as shown, without what only screen readers get.
|
|
21
|
+
const text = (el) => {
|
|
22
|
+
if (!el)
|
|
23
|
+
return "";
|
|
24
|
+
const copy = el.cloneNode(true);
|
|
25
|
+
for (const hidden of Array.from(copy.querySelectorAll(".accesshide, .visually-hidden, .sr-only, input")))
|
|
26
|
+
hidden.remove();
|
|
27
|
+
doc.body.appendChild(copy);
|
|
28
|
+
const shown = copy.innerText ?? "";
|
|
29
|
+
copy.remove();
|
|
30
|
+
return shown.replace(/\s+/g, " ").trim();
|
|
31
|
+
};
|
|
32
|
+
// An option's label: its own <label for>, the label around it, or (a rating row) nothing.
|
|
33
|
+
const labelOf = (input) => {
|
|
34
|
+
const own = input.id ? doc.querySelector(`label[for="${input.id}"]:not(.accesshide)`) : null;
|
|
35
|
+
const around = input.closest("label");
|
|
36
|
+
return text(own ?? around) || undefined;
|
|
37
|
+
};
|
|
38
|
+
const form = doc.querySelector(layout.form);
|
|
39
|
+
if (!form)
|
|
40
|
+
return [];
|
|
41
|
+
return Array.from(form.querySelectorAll(layout.question)).map((question) => {
|
|
42
|
+
const fields = [];
|
|
43
|
+
for (const input of Array.from(question.querySelectorAll("input:not([type=hidden]), select, textarea"))) {
|
|
44
|
+
if (!input.name)
|
|
45
|
+
continue;
|
|
46
|
+
if (input.type === "radio") {
|
|
47
|
+
let field = fields.find((f) => f.name === input.name);
|
|
48
|
+
if (!field) {
|
|
49
|
+
// A rating row's item is the row's first cell.
|
|
50
|
+
const row = input.closest("tr.raterow");
|
|
51
|
+
field = { name: input.name, kind: "choice", options: [], ...(row ? { label: text(row.querySelector("td")) } : {}) };
|
|
52
|
+
fields.push(field);
|
|
53
|
+
}
|
|
54
|
+
const label = labelOf(input);
|
|
55
|
+
field.options.push({ value: input.value, label: label && !label.includes(",") ? label : input.value === "-999" ? "(no answer)" : (label ?? input.value) });
|
|
56
|
+
if (input.checked)
|
|
57
|
+
field.value = input.value;
|
|
58
|
+
}
|
|
59
|
+
else if (input.type === "checkbox") {
|
|
60
|
+
fields.push({ name: input.name, kind: "checkbox", label: labelOf(input), value: input.checked ? "1" : "0" });
|
|
61
|
+
}
|
|
62
|
+
else if (input.tagName === "SELECT") {
|
|
63
|
+
const options = Array.from(input.options);
|
|
64
|
+
fields.push({ name: input.name, kind: "select", options: options.map((o) => ({ value: o.value, label: o.text.trim() })), value: options.find((o) => o.selected)?.value });
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
fields.push({ name: input.name, kind: "text", ...(input.value ? { value: input.value } : {}) });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
page: pageNumber,
|
|
72
|
+
number: text(question.querySelector(layout.number)) || undefined,
|
|
73
|
+
text: text(question.querySelector(layout.text)),
|
|
74
|
+
required: question.querySelector(layout.required) !== null,
|
|
75
|
+
fields,
|
|
76
|
+
};
|
|
77
|
+
});
|
|
78
|
+
}, { layout: LAYOUT[type], pageNumber });
|
|
79
|
+
}
|
|
80
|
+
/** Whether the person can answer now, and the survey's page message (completed, closed…). */
|
|
81
|
+
async function surveyStatus(context, siteUrl, activityId, type) {
|
|
82
|
+
const page = await openSitePage(context, siteUrl, `mod/${type}/view.php?id=${activityId}`);
|
|
83
|
+
try {
|
|
84
|
+
if ((await page.locator(`body#page-mod-${type}-view`).count()) === 0)
|
|
85
|
+
throw new SurveyError(`Activity ${activityId} isn't a ${type} you can open. Take its id and module from the course structure.`);
|
|
86
|
+
return await page.evaluate(() => {
|
|
87
|
+
const doc = globalThis.document;
|
|
88
|
+
return {
|
|
89
|
+
canAnswer: doc.querySelector('#region-main a[href*="complete.php"]') !== null,
|
|
90
|
+
intro: (doc.querySelector(".activity-description, #intro")?.innerText ?? "").trim(),
|
|
91
|
+
messages: Array.from(doc.querySelectorAll("#region-main .alert, #region-main .notifymessage, #region-main .complete, #region-main .generalbox p"))
|
|
92
|
+
.map((e) => e.innerText.replace(/\s+/g, " ").trim())
|
|
93
|
+
.filter(Boolean)
|
|
94
|
+
.slice(0, 6),
|
|
95
|
+
};
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
finally {
|
|
99
|
+
await page.close().catch(() => undefined);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/** Every page of the survey's form: feedback pages through `gopage`, questionnaire sections through `sec`. */
|
|
103
|
+
async function readAllPages(context, siteUrl, activityId, type) {
|
|
104
|
+
const layout = LAYOUT[type];
|
|
105
|
+
const questions = [];
|
|
106
|
+
const page = await openSitePage(context, siteUrl, `mod/${type}/complete.php?id=${activityId}`);
|
|
107
|
+
try {
|
|
108
|
+
for (let p = 0; p < 50; p++) {
|
|
109
|
+
if (p > 0) {
|
|
110
|
+
const next = type === "feedback" ? `mod/feedback/complete.php?id=${activityId}&gopage=${p}` : `mod/questionnaire/complete.php?id=${activityId}&sec=${p + 1}`;
|
|
111
|
+
await page.goto(new URL(next, siteUrl).href, { waitUntil: "domcontentloaded" });
|
|
112
|
+
}
|
|
113
|
+
const found = await readSurveyPage(page, type, p);
|
|
114
|
+
if (found.length === 0)
|
|
115
|
+
break;
|
|
116
|
+
questions.push(...found);
|
|
117
|
+
if ((await page.locator(`${layout.form} [name="${layout.next}"]`).count()) === 0)
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
return questions;
|
|
121
|
+
}
|
|
122
|
+
finally {
|
|
123
|
+
await page.close().catch(() => undefined);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// A course module's module never changes: one look per survey and site, for the process.
|
|
127
|
+
const surveyTypes = new Map();
|
|
128
|
+
/** Which survey module an activity is, from the page each module answers with its own view (body id). */
|
|
129
|
+
export async function surveyType(context, siteUrl, activityId) {
|
|
130
|
+
const key = `${siteUrl}|${activityId}`;
|
|
131
|
+
const known = surveyTypes.get(key);
|
|
132
|
+
if (known)
|
|
133
|
+
return known;
|
|
134
|
+
for (const type of ["questionnaire", "feedback"]) {
|
|
135
|
+
const page = await openSitePage(context, siteUrl, `mod/${type}/view.php?id=${activityId}`, { follow: false });
|
|
136
|
+
try {
|
|
137
|
+
if ((await page.locator(`body#page-mod-${type}-view`).count()) > 0) {
|
|
138
|
+
surveyTypes.set(key, type);
|
|
139
|
+
return type;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
finally {
|
|
143
|
+
await page.close().catch(() => undefined);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
throw new SurveyError(`Activity ${activityId} isn't a questionnaire or a feedback activity you can open. Take its id and module from the course structure.`);
|
|
147
|
+
}
|
|
148
|
+
/** A survey (questionnaire or feedback): whether it can be answered, its intro and messages, and its questions page by page. Its module is found when not given. */
|
|
149
|
+
export async function getSurvey(context, siteUrl, activityId, type) {
|
|
150
|
+
type ??= await surveyType(context, siteUrl, activityId);
|
|
151
|
+
const status = await surveyStatus(context, siteUrl, activityId, type);
|
|
152
|
+
return { ...status, questions: status.canAnswer ? await readAllPages(context, siteUrl, activityId, type) : [] };
|
|
153
|
+
}
|
|
154
|
+
export async function submitSurvey(context, siteUrl, activityId, typeOrResponses, responsesOrOptions) {
|
|
155
|
+
// (activityId, type, responses), as before 0.2, or (activityId, responses, { type }), the module found when not given.
|
|
156
|
+
const responses = (typeof typeOrResponses === "string" ? responsesOrOptions : typeOrResponses);
|
|
157
|
+
const type = typeof typeOrResponses === "string" ? typeOrResponses : (responsesOrOptions?.type ?? (await surveyType(context, siteUrl, activityId)));
|
|
158
|
+
const layout = LAYOUT[type];
|
|
159
|
+
const status = await surveyStatus(context, siteUrl, activityId, type);
|
|
160
|
+
if (!status.canAnswer)
|
|
161
|
+
throw new SurveyError(`You can't answer ${type} ${activityId} now: ${status.messages.join(" ") || "it's completed, closed or not open yet"}.`);
|
|
162
|
+
const known = new Set((await readAllPages(context, siteUrl, activityId, type)).flatMap((q) => q.fields.map((f) => f.name)));
|
|
163
|
+
const unknown = Object.keys(responses).filter((name) => !known.has(name));
|
|
164
|
+
if (unknown.length > 0)
|
|
165
|
+
throw new SurveyError(`The survey has no field ${unknown.join(", ")}: take the names from the survey's questions.`);
|
|
166
|
+
const page = await openSitePage(context, siteUrl, `mod/${type}/complete.php?id=${activityId}`);
|
|
167
|
+
try {
|
|
168
|
+
for (let p = 0; p < 50; p++) {
|
|
169
|
+
const here = new Set((await readSurveyPage(page, type, p)).flatMap((q) => q.fields.map((f) => f.name)));
|
|
170
|
+
const values = Object.fromEntries(Object.entries(responses).filter(([name]) => here.has(name)));
|
|
171
|
+
await setFields(page, values, layout.form);
|
|
172
|
+
const last = (await page.locator(`${layout.form} [name="${layout.next}"]`).count()) === 0;
|
|
173
|
+
const [response] = await Promise.all([page.waitForNavigation({ waitUntil: "domcontentloaded" }), page.click(`${layout.form} [name="${last ? layout.finish : layout.next}"]`)]);
|
|
174
|
+
if (response && response.status() >= 500) {
|
|
175
|
+
throw new SurveyError(`The site answered ${response.status()} ${last ? "on submitting" : "on the way"}; it may or may not have recorded the answers. Read the survey again before trying again.`);
|
|
176
|
+
}
|
|
177
|
+
// Moodle sends the page back when something's missing or wrong.
|
|
178
|
+
const problems = await page.evaluate((form) => {
|
|
179
|
+
const doc = globalThis.document;
|
|
180
|
+
const messages = Array.from(doc.querySelectorAll(`${form} [id^="id_error_"], #region-main .alert-danger`)).map((e) => {
|
|
181
|
+
// Without the notification's close button ("Dismiss this notification").
|
|
182
|
+
const copy = e.cloneNode(true);
|
|
183
|
+
for (const button of Array.from(copy.querySelectorAll("button, .close, .visually-hidden")))
|
|
184
|
+
button.remove();
|
|
185
|
+
const text = (copy.innerText ?? e.innerText).replace(/\s+/g, " ").trim();
|
|
186
|
+
return text ? `${e.id ? e.id.replace("id_error_", "") + ": " : ""}${text}` : "";
|
|
187
|
+
});
|
|
188
|
+
return [...new Set(messages.filter(Boolean))];
|
|
189
|
+
}, layout.form);
|
|
190
|
+
if (problems.length > 0)
|
|
191
|
+
throw new SurveyError(`Moodle didn't accept the answers on page ${p + 1}: ${problems.join("; ")}`);
|
|
192
|
+
if (last)
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
finally {
|
|
197
|
+
await page.close().catch(() => undefined);
|
|
198
|
+
}
|
|
199
|
+
return { changed: `Submitted ${type} ${activityId}.`, messages: (await surveyStatus(context, siteUrl, activityId, type)).messages };
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=surveys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"surveys.js","sourceRoot":"","sources":["../../../src/areas/surveys/surveys.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ChildProcess } from "node:child_process";
|
|
2
|
+
export type InstallChromium = () => Promise<void>;
|
|
3
|
+
/**
|
|
4
|
+
* Starts a process that `killTree` can end with everything it starts: on Linux and macOS as the
|
|
5
|
+
* leader of its own process group; on Windows `taskkill /T` walks the tree, and no console opens.
|
|
6
|
+
*/
|
|
7
|
+
export declare function spawnTree(command: string, args: string[]): ChildProcess;
|
|
8
|
+
/** Ends a process started by `spawnTree` and its children, at once; nothing if it's gone. */
|
|
9
|
+
export declare function killTree(pid: number): void;
|
|
10
|
+
/**
|
|
11
|
+
* Downloads the Chromium this `playwright-core` expects with its own CLI (ADR-001), into
|
|
12
|
+
* `PLAYWRIGHT_BROWSERS_PATH` when set, else the user's `ms-playwright` cache. The CLI is in
|
|
13
|
+
* `node_modules`, where `playwright-core` is (a peer dependency).
|
|
14
|
+
*/
|
|
15
|
+
export declare const installChromium: InstallChromium;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { MoodleError } from "../core/errors.js";
|
|
5
|
+
/**
|
|
6
|
+
* Starts a process that `killTree` can end with everything it starts: on Linux and macOS as the
|
|
7
|
+
* leader of its own process group; on Windows `taskkill /T` walks the tree, and no console opens.
|
|
8
|
+
*/
|
|
9
|
+
export function spawnTree(command, args) {
|
|
10
|
+
return spawn(command, args, { stdio: ["ignore", "pipe", "pipe"], detached: process.platform !== "win32", windowsHide: true });
|
|
11
|
+
}
|
|
12
|
+
/** Ends a process started by `spawnTree` and its children, at once; nothing if it's gone. */
|
|
13
|
+
export function killTree(pid) {
|
|
14
|
+
try {
|
|
15
|
+
if (process.platform === "win32")
|
|
16
|
+
spawnSync("taskkill", ["/PID", String(pid), "/T", "/F"], { stdio: "ignore", windowsHide: true });
|
|
17
|
+
else
|
|
18
|
+
process.kill(-pid, "SIGKILL");
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
// Already gone.
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Downloads the Chromium this `playwright-core` expects with its own CLI (ADR-001), into
|
|
26
|
+
* `PLAYWRIGHT_BROWSERS_PATH` when set, else the user's `ms-playwright` cache. The CLI is in
|
|
27
|
+
* `node_modules`, where `playwright-core` is (a peer dependency).
|
|
28
|
+
*/
|
|
29
|
+
export const installChromium = () => new Promise((resolve, reject) => {
|
|
30
|
+
const cli = path.join(path.dirname(createRequire(import.meta.url).resolve("playwright-core/package.json")), "cli.js");
|
|
31
|
+
// --no-shell: the driver launches full Chromium headless too (channel "chromium").
|
|
32
|
+
// --no-remove: the cache is shared, and other installations' browsers aren't ours to remove.
|
|
33
|
+
const child = spawnTree(process.execPath, [cli, "install", "chromium", "--no-shell", "--no-remove", "--no-progress"]);
|
|
34
|
+
// The CLI downloads from a child of its own: when the program exits, the whole tree goes with it,
|
|
35
|
+
// instead of downloading on with nobody to use it (a partial download is started over next time).
|
|
36
|
+
const stop = () => killTree(child.pid);
|
|
37
|
+
process.on("exit", stop);
|
|
38
|
+
// A program's stdout may be a protocol (an MCP server's): whatever the installer prints goes to stderr.
|
|
39
|
+
child.stdout.pipe(process.stderr, { end: false });
|
|
40
|
+
child.stderr.pipe(process.stderr, { end: false });
|
|
41
|
+
child.on("error", (error) => {
|
|
42
|
+
process.off("exit", stop);
|
|
43
|
+
reject(error);
|
|
44
|
+
});
|
|
45
|
+
child.on("exit", (code) => {
|
|
46
|
+
process.off("exit", stop);
|
|
47
|
+
if (code === 0)
|
|
48
|
+
resolve();
|
|
49
|
+
else
|
|
50
|
+
reject(new MoodleError(`Chromium's installer exited with code ${code}`, "chromium-install-failed"));
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
//# sourceMappingURL=chromium.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chromium.js","sourceRoot":"","sources":["../../src/browser/chromium.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAqB,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIhD;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,OAAe,EAAE,IAAc;IACvD,OAAO,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;AAChI,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,QAAQ,CAAC,GAAW;IAClC,IAAI,CAAC;QACH,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;YAAE,SAAS,CAAC,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;;YAC9H,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,gBAAgB;IAClB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAoB,GAAG,EAAE,CACnD,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;IAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IACtH,mFAAmF;IACnF,6FAA6F;IAC7F,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,CAAC,CAAC,CAAC;IACtH,kGAAkG;IAClG,kGAAkG;IAClG,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAI,CAAC,CAAC;IACxC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACzB,wGAAwG;IACxG,KAAK,CAAC,MAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;IACnD,KAAK,CAAC,MAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;IACnD,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;QAC1B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC1B,MAAM,CAAC,KAAK,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;IACH,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;QACxB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC1B,IAAI,IAAI,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;;YACrB,MAAM,CAAC,IAAI,WAAW,CAAC,yCAAyC,IAAI,EAAE,EAAE,yBAAyB,CAAC,CAAC,CAAC;IAC3G,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { BrowserContext } from "playwright-core";
|
|
2
|
+
/**
|
|
3
|
+
* Chromium drops session cookies (no expiry) when a persistent profile closes, and Moodle's
|
|
4
|
+
* `MoodleSession` is one (confirmed empirically, Edge and playwright-core 1.64, Moodle 5.2): the
|
|
5
|
+
* profile alone would forget the login on every restart. They are kept in this file inside the
|
|
6
|
+
* profile, as sensitive as the profile itself (ADR-003).
|
|
7
|
+
*/
|
|
8
|
+
export declare const SESSION_COOKIES_FILE = "moodle-session.json";
|
|
9
|
+
export declare function saveSessionCookies(context: BrowserContext, profileDir: string): Promise<void>;
|
|
10
|
+
/** Puts back the session cookies saved last time; a missing or unreadable file means none. */
|
|
11
|
+
export declare function restoreSessionCookies(context: BrowserContext, profileDir: string): Promise<void>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* Chromium drops session cookies (no expiry) when a persistent profile closes, and Moodle's
|
|
5
|
+
* `MoodleSession` is one (confirmed empirically, Edge and playwright-core 1.64, Moodle 5.2): the
|
|
6
|
+
* profile alone would forget the login on every restart. They are kept in this file inside the
|
|
7
|
+
* profile, as sensitive as the profile itself (ADR-003).
|
|
8
|
+
*/
|
|
9
|
+
export const SESSION_COOKIES_FILE = "moodle-session.json";
|
|
10
|
+
export async function saveSessionCookies(context, profileDir) {
|
|
11
|
+
const sessionCookies = (await context.cookies()).filter((cookie) => cookie.expires === -1);
|
|
12
|
+
await writeFile(path.join(profileDir, SESSION_COOKIES_FILE), JSON.stringify(sessionCookies), { mode: 0o600 });
|
|
13
|
+
}
|
|
14
|
+
/** Puts back the session cookies saved last time; a missing or unreadable file means none. */
|
|
15
|
+
export async function restoreSessionCookies(context, profileDir) {
|
|
16
|
+
let cookies;
|
|
17
|
+
try {
|
|
18
|
+
cookies = JSON.parse(await readFile(path.join(profileDir, SESSION_COOKIES_FILE), "utf8"));
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (!Array.isArray(cookies) || cookies.length === 0)
|
|
24
|
+
return;
|
|
25
|
+
// Cookies the browser kept itself are newer than the file's.
|
|
26
|
+
const kept = new Set((await context.cookies()).map((c) => `${c.name}|${c.domain}|${c.path}`));
|
|
27
|
+
const missing = cookies.filter((c) => !kept.has(`${c.name}|${c.domain}|${c.path}`));
|
|
28
|
+
if (missing.length > 0)
|
|
29
|
+
await context.addCookies(missing).catch(() => undefined);
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=cookies.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cookies.js","sourceRoot":"","sources":["../../src/browser/cookies.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,qBAAqB,CAAC;AAE1D,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAAuB,EAAE,UAAkB;IAClF,MAAM,cAAc,GAAG,CAAC,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3F,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,oBAAoB,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAChH,CAAC;AAED,8FAA8F;AAC9F,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,OAAuB,EAAE,UAAkB;IACrF,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,oBAAoB,CAAC,EAAE,MAAM,CAAC,CAAa,CAAC;IACxG,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAC5D,6DAA6D;IAC7D,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC9F,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACpF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;AACnF,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { chromium, type BrowserContext, type Page } from "playwright-core";
|
|
2
|
+
import { type InstallChromium } from "./chromium.js";
|
|
3
|
+
import { type BrowserOptions, type Channel } from "../options.js";
|
|
4
|
+
import { MoodleError } from "../core/errors.js";
|
|
5
|
+
type LaunchPersistentContext = typeof chromium.launchPersistentContext;
|
|
6
|
+
export interface ContextOptions {
|
|
7
|
+
/** A visible window, whatever the options say (logging in by hand). */
|
|
8
|
+
headed?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/** The browser's single persistent context, opened on first use (ADR-002). */
|
|
11
|
+
export interface BrowserManager {
|
|
12
|
+
/**
|
|
13
|
+
* The open context, launching it if needed. A headed request relaunches a headless context with
|
|
14
|
+
* a window; a headless request reuses a headed one rather than closing a window the person may be using.
|
|
15
|
+
*/
|
|
16
|
+
context(options?: ContextOptions): Promise<BrowserContext>;
|
|
17
|
+
/** The channel of the open context, or `undefined` while none is open. */
|
|
18
|
+
openChannel(): Channel | undefined;
|
|
19
|
+
/** Whether Chromium is being downloaded, or the last download failed (ADR-001). */
|
|
20
|
+
chromiumDownload(): "downloading" | "failed" | undefined;
|
|
21
|
+
/** Whether the browser shows a window now: what `setVisible` asked for, else the options. */
|
|
22
|
+
visible(): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Shows the browser (relaunching it with a window now, session kept) and follows the pages functions open
|
|
25
|
+
* in it, or hides it (closing the window; the next call runs headless). ADR-007.
|
|
26
|
+
*/
|
|
27
|
+
setVisible(visible: boolean): Promise<void>;
|
|
28
|
+
/** While following, brings `url` (a site page) to the front of the window; best effort, never throws. */
|
|
29
|
+
show(url: string): Promise<void>;
|
|
30
|
+
/** The one working tab a program drives itself (ADR-007), the same one following shows; opens the browser if needed. */
|
|
31
|
+
tab(): Promise<Page>;
|
|
32
|
+
/** Saves the session cookies of the open context, if any (ADR-003). */
|
|
33
|
+
saveSession(): Promise<void>;
|
|
34
|
+
close(): Promise<void>;
|
|
35
|
+
}
|
|
36
|
+
/** No installed browser could be launched, and Chromium can't be downloaded (ADR-001). */
|
|
37
|
+
export declare class BrowserNotFoundError extends MoodleError {
|
|
38
|
+
name: string;
|
|
39
|
+
constructor(message: string);
|
|
40
|
+
}
|
|
41
|
+
/** No browser yet: Chromium is downloading in the background, and the call should be retried later. */
|
|
42
|
+
export declare class BrowserDownloadingError extends MoodleError {
|
|
43
|
+
name: string;
|
|
44
|
+
constructor(message: string);
|
|
45
|
+
}
|
|
46
|
+
/** A window was asked for where there's no screen to show it (a container, a server). */
|
|
47
|
+
export declare class NoDisplayError extends MoodleError {
|
|
48
|
+
name: string;
|
|
49
|
+
constructor(message: string);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Whether a window can be shown. On Linux it needs an X or Wayland display; without one (Docker, a
|
|
53
|
+
* server) the driver refuses rather than trying, so it never reaches a display it wasn't given.
|
|
54
|
+
*/
|
|
55
|
+
export declare function canShowWindow(env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): boolean;
|
|
56
|
+
export declare function createBrowserManager(config: BrowserOptions, launch?: LaunchPersistentContext, install?: InstallChromium, windowsPossible?: () => boolean): BrowserManager;
|
|
57
|
+
export {};
|