@dolphy-app/extension-sdk 0.3.0 → 0.5.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/README.md +40 -12
- package/dist/client.d.ts +40 -0
- package/dist/client.js +67 -0
- package/dist/define-entry-BTz2F3qv.js +22 -0
- package/dist/define-entry-lsuxzKdD.d.ts +77 -0
- package/dist/index-I_CXC6Lj.d.ts +1958 -0
- package/dist/index.d.ts +7 -103
- package/dist/index.js +5 -80
- package/dist/react.d.ts +51 -0
- package/dist/react.js +112 -0
- package/dist/rpc.d.ts +28 -0
- package/dist/rpc.js +37 -0
- package/dist/testing.d.ts +248 -121
- package/dist/testing.js +779 -241
- package/docs/debugging.md +228 -0
- package/docs/no-build.md +135 -0
- package/docs/quick-start.md +194 -0
- package/docs/recipe-command-panel.md +355 -0
- package/docs/recipe-event-storage.md +326 -0
- package/docs/recipe-exercise-type.md +467 -0
- package/docs/recipe-hooks.md +158 -0
- package/docs/recipe-import-export.md +236 -0
- package/docs/recipe-mountable.md +322 -0
- package/docs/recipe-react.md +352 -0
- package/docs/recipe-rpc-and-app.md +366 -0
- package/docs/recipe-settings.md +183 -0
- package/docs/recipe-theme.md +148 -0
- package/docs/recipe-when-dependencies.md +264 -0
- package/package.json +31 -8
- package/dist/answer-element-BOQcuxYh.js +0 -114
- package/dist/answer-view-D6wnyThb.d.ts +0 -28
- package/dist/runtime.d.ts +0 -14
- package/dist/runtime.js +0 -18
package/dist/testing.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { t as
|
|
2
|
-
import {
|
|
1
|
+
import { t as ExtensionEngine } from "./index-I_CXC6Lj.js";
|
|
2
|
+
import { a as MountContext$1, i as InjectionRegistration$1, l as ServerEntry$1, o as Mountable, r as ClientEntry, s as PanelRegistration$1, t as AppApi$1 } from "./define-entry-lsuxzKdD.js";
|
|
3
|
+
import { AnswerViewProps, AppLocale, AppTheme, ClientCommandRegistration, CommandOutcome, Disposable, ExportInput, ExportResult, ExtensionHookName, ExtensionLogger, ExtensionNotification, ExtensionNotifications, ExtensionSecrets, ExtensionSettings, ExtensionStats, ExtensionStorage, GradePolicyInput, GradeResult, GradeValue, HookRequest, HookResponse, ImportInput, ImportResult, JsonSchema, JsonValue, LearningEventName, LearningEventPayloads, LibraryReader, MarkdownBlockProps, RpcContract, ServerRegistration, SettingDefinition, SettingValue, ThemeRegistration } from "@dolphy-app/extension-api";
|
|
4
|
+
import { Component } from "vue";
|
|
3
5
|
//#region packages/extension-sdk/src/testing.d.ts
|
|
4
6
|
export declare const createMemoryLibrary: (files: Readonly<Record<string, string>>) => LibraryReader;
|
|
5
7
|
/**
|
|
@@ -8,6 +10,22 @@ export declare const createMemoryLibrary: (files: Readonly<Record<string, string
|
|
|
8
10
|
* JSON text and returned as copies; on rejection nothing changes.
|
|
9
11
|
*/
|
|
10
12
|
export declare const createMemoryStorage: () => ExtensionStorage;
|
|
13
|
+
/** In-memory secrets for tests: `ExtensionSecrets` plus a switch that imitates a missing system key store. */
|
|
14
|
+
export interface MemorySecrets extends ExtensionSecrets {
|
|
15
|
+
/** Imitates the system key store becoming (un)available; stored values are kept. */
|
|
16
|
+
setAvailable(available: boolean): void;
|
|
17
|
+
}
|
|
18
|
+
export interface MemorySecretsOptions {
|
|
19
|
+
/** Default `true`; `false` imitates Linux `basic_text`, no key store, or an app that is not ready. */
|
|
20
|
+
available?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* In-memory secrets with the engine's limits and errors
|
|
24
|
+
* (`EXTENSION_SECRET_LIMITS`, `StorageQuotaError`, `SecretsUnavailableError`):
|
|
25
|
+
* without a key store `set` and `get` of an existing key throw, `get` of a
|
|
26
|
+
* missing key gives `undefined` and `delete` works.
|
|
27
|
+
*/
|
|
28
|
+
export declare const createMemorySecrets: (options?: MemorySecretsOptions) => MemorySecrets;
|
|
11
29
|
export interface MemorySettings extends ExtensionSettings {
|
|
12
30
|
/**
|
|
13
31
|
* Changes the value as the user does in the dialog: the value is validated
|
|
@@ -15,54 +33,82 @@ export interface MemorySettings extends ExtensionSettings {
|
|
|
15
33
|
* Unlike the host, a handler failure is not swallowed but rejects the promise.
|
|
16
34
|
*/
|
|
17
35
|
set(id: string, value: SettingValue): Promise<void>;
|
|
36
|
+
/** Adds definitions, as `server.registerSettings` does; an id registered twice throws. The returned `Disposable` removes them. */
|
|
37
|
+
register(definitions: readonly SettingDefinition[]): Disposable;
|
|
18
38
|
}
|
|
19
|
-
/**
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
39
|
+
/**
|
|
40
|
+
* In-memory settings. `definitions` are registered at once, more come through
|
|
41
|
+
* `register`; `initial` provides user values in place of `default`, applied
|
|
42
|
+
* when the setting with that id is registered.
|
|
43
|
+
*/
|
|
44
|
+
export declare const createMemorySettings: (definitions?: readonly SettingDefinition[], initial?: Readonly<Record<string, SettingValue>>) => MemorySettings;
|
|
45
|
+
export interface MemoryStatsAttempt {
|
|
46
|
+
/** When the attempt happened: epoch milliseconds, a `Date`, or an ISO-8601 string. */
|
|
47
|
+
at: number | Date | string;
|
|
48
|
+
/** Grade 1-5; 3 and higher counts as correct, as in the app. */
|
|
49
|
+
grade: number;
|
|
50
|
+
/** Course of the attempt, for the `courseId` filter. Without it the attempt belongs to no course. */
|
|
51
|
+
courseId?: string;
|
|
28
52
|
}
|
|
29
|
-
export interface
|
|
30
|
-
/**
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
|
|
53
|
+
export interface MemoryStatsOptions {
|
|
54
|
+
/** Attempts the statistics start with; more arrive through `record`. */
|
|
55
|
+
attempts?: readonly MemoryStatsAttempt[];
|
|
56
|
+
/** IANA time zone whose local days are counted. Defaults to the time zone of this process. */
|
|
57
|
+
timeZone?: string;
|
|
58
|
+
/** The current time, for the `current` streak. Defaults to `Date.now`. */
|
|
59
|
+
now?: () => number;
|
|
34
60
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
61
|
+
export interface MemoryStats extends ExtensionStats {
|
|
62
|
+
/** Adds an attempt to the history. */
|
|
63
|
+
record(attempt: MemoryStatsAttempt): void;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* In-memory statistics with the semantics of the app: local days in a time zone,
|
|
67
|
+
* correct at grade 3 or higher, `current` streak not broken while today has no
|
|
68
|
+
* attempts yet, one `daily` entry per date (at most `EXTENSION_STATS_LIMITS.dailyDays`).
|
|
69
|
+
*/
|
|
70
|
+
export declare const createMemoryStats: (options?: MemoryStatsOptions) => MemoryStats;
|
|
71
|
+
export interface MemoryNotificationsOptions {
|
|
72
|
+
/** false — the operating system does not support notifications: `show` resolves `false`. Defaults to true. */
|
|
73
|
+
supported?: boolean;
|
|
74
|
+
/** false — the user switched notifications off for the extension: `show` resolves `false`. Defaults to true. */
|
|
75
|
+
enabled?: boolean;
|
|
76
|
+
/** The current time for the rate windows. Defaults to `Date.now`. */
|
|
77
|
+
now?: () => number;
|
|
78
|
+
}
|
|
79
|
+
export interface MemoryNotifications extends ExtensionNotifications {
|
|
80
|
+
/** Notifications handed to the (imitated) operating system, oldest first, as the app shows them: sanitized text. */
|
|
81
|
+
readonly shown: readonly ExtensionNotification[];
|
|
82
|
+
/** The user's switch "Notifications" of the extension. */
|
|
83
|
+
setEnabled(enabled: boolean): void;
|
|
84
|
+
/** Whether the imitated operating system supports notifications. */
|
|
85
|
+
setSupported(supported: boolean): void;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* In-memory notifications with the engine's rules: the text is sanitized and
|
|
89
|
+
* limited, `perMinute`/`perHour` windows throw `NotificationRateLimitError`,
|
|
90
|
+
* a switched-off extension or an unsupporting system resolves `false` (and
|
|
91
|
+
* does not use the rate limit). `shown` is the log the app's fake notifier
|
|
92
|
+
* would keep.
|
|
93
|
+
*/
|
|
94
|
+
export declare const createMemoryNotifications: (options?: MemoryNotificationsOptions) => MemoryNotifications;
|
|
95
|
+
export declare const createSchemaValidator: (schema: JsonSchema) => (value: unknown) => string[];
|
|
96
|
+
/** What a test replaces in the context of the server part; by default everything is in memory and silent. */
|
|
97
|
+
export interface TestServerOptions {
|
|
98
|
+
/** Default `test`. When set, every registered id must be equal to it or start with `<extensionId>.`, as the host checks. */
|
|
99
|
+
extensionId?: string;
|
|
57
100
|
library?: LibraryReader;
|
|
58
101
|
logger?: ExtensionLogger;
|
|
59
102
|
storage?: ExtensionStorage;
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
103
|
+
secrets?: MemorySecrets;
|
|
104
|
+
stats?: MemoryStats;
|
|
105
|
+
notifications?: MemoryNotifications;
|
|
106
|
+
/** User values of settings in place of `default`, by setting id; every id must be registered by the entry. */
|
|
107
|
+
settingValues?: Readonly<Record<string, SettingValue>>;
|
|
108
|
+
/** The engine `ctx.engine` gives to the entry; by default every use of it throws, as the test server has no engine. */
|
|
109
|
+
engine?: ExtensionEngine;
|
|
63
110
|
}
|
|
64
|
-
export
|
|
65
|
-
export interface LoadedExerciseType {
|
|
111
|
+
export interface TestExerciseType {
|
|
66
112
|
project(spec: unknown, options?: {
|
|
67
113
|
exerciseId?: string;
|
|
68
114
|
}): Promise<unknown>;
|
|
@@ -81,95 +127,176 @@ export interface LoadedExerciseType {
|
|
|
81
127
|
} | {
|
|
82
128
|
found: false;
|
|
83
129
|
}>;
|
|
84
|
-
/** Deactivates the extension module. */
|
|
85
|
-
dispose(): Promise<void>;
|
|
86
130
|
}
|
|
87
|
-
export
|
|
88
|
-
export interface LoadedGradePolicy {
|
|
131
|
+
export interface TestGradePolicy {
|
|
89
132
|
evaluate(input: GradePolicyInput): Promise<GradeValue | null>;
|
|
90
|
-
|
|
133
|
+
}
|
|
134
|
+
export interface TestImporter {
|
|
135
|
+
/**
|
|
136
|
+
* Runs the importer the way the host does: the input must have the form the
|
|
137
|
+
* importer declares and at most `EXTENSION_TRANSFER_LIMITS.inputBytes`; the
|
|
138
|
+
* result goes through `normalizeImportResult`. An invalid result rejects the
|
|
139
|
+
* promise. The handler timeout is not applied.
|
|
140
|
+
*/
|
|
141
|
+
run(input: ImportInput): Promise<ImportResult>;
|
|
142
|
+
}
|
|
143
|
+
export interface TestExporter {
|
|
144
|
+
/**
|
|
145
|
+
* Runs the exporter the way the host does: the input must match the
|
|
146
|
+
* exporter's `scope` and a course snapshot is at most
|
|
147
|
+
* `EXTENSION_TRANSFER_LIMITS.totalBytes`; the result goes through
|
|
148
|
+
* `normalizeExportResult`. An invalid result rejects the promise. The handler
|
|
149
|
+
* timeout is not applied.
|
|
150
|
+
*/
|
|
151
|
+
run(input: ExportInput): Promise<ExportResult>;
|
|
152
|
+
}
|
|
153
|
+
/** The server part of an extension, started on in-memory fakes. */
|
|
154
|
+
export interface TestServer {
|
|
155
|
+
readonly extensionId: string;
|
|
156
|
+
/** What the entry registered, as the host's registrar hands it to the engine (checked for types and unique ids only: the host checks the rest). */
|
|
157
|
+
readonly registration: ServerRegistration;
|
|
158
|
+
readonly library: LibraryReader;
|
|
159
|
+
readonly storage: ExtensionStorage;
|
|
160
|
+
readonly secrets: MemorySecrets;
|
|
161
|
+
readonly settings: MemorySettings;
|
|
162
|
+
readonly stats: MemoryStats;
|
|
163
|
+
readonly notifications: MemoryNotifications;
|
|
164
|
+
/** The engine of the context: `options.engine`. */
|
|
165
|
+
readonly engine: ExtensionEngine;
|
|
166
|
+
readonly commands: {
|
|
167
|
+
/**
|
|
168
|
+
* Runs a registered command the way the host does: the same argument and
|
|
169
|
+
* result bounds, the same result normalization. An unregistered command
|
|
170
|
+
* and an invalid result reject the promise. The handler timeout is not applied.
|
|
171
|
+
*/
|
|
172
|
+
run(id: string, args?: JsonValue): Promise<CommandOutcome>;
|
|
173
|
+
};
|
|
174
|
+
readonly events: {
|
|
175
|
+
/**
|
|
176
|
+
* Sends the event to the subscribed handler and awaits it. With no
|
|
177
|
+
* subscription the event is skipped, as in the host. Unlike the host, a
|
|
178
|
+
* handler failure is not swallowed but rejects the promise, and the
|
|
179
|
+
* handler timeout is not applied.
|
|
180
|
+
*/
|
|
181
|
+
emit<N extends LearningEventName>(name: N, payload: LearningEventPayloads[N]): Promise<void>;
|
|
182
|
+
};
|
|
183
|
+
/**
|
|
184
|
+
* Calls the handler registered with `server.before` the way the host does:
|
|
185
|
+
* the request must pass `EXTENSION_HOOKS[name].request` and the response
|
|
186
|
+
* `EXTENSION_HOOKS[name].response`. An unregistered hook, a schema
|
|
187
|
+
* violation and an error of the handler reject the promise. The handler
|
|
188
|
+
* timeout is not applied, and no other extension's handlers run.
|
|
189
|
+
*/
|
|
190
|
+
hook<N extends ExtensionHookName>(name: N, request: HookRequest<N>): Promise<HookResponse<N>>;
|
|
191
|
+
readonly schedule: {
|
|
192
|
+
/**
|
|
193
|
+
* Fires a registered schedule the way the host does and awaits the
|
|
194
|
+
* handler: resolves `true` once the handler returned, `false` while the
|
|
195
|
+
* handler of the previous firing is still running. An unregistered
|
|
196
|
+
* schedule rejects the promise. Unlike the host, a handler failure is not
|
|
197
|
+
* swallowed but rejects the promise.
|
|
198
|
+
*/
|
|
199
|
+
fire(id: string): Promise<boolean>;
|
|
200
|
+
};
|
|
201
|
+
exerciseType(id: string): TestExerciseType;
|
|
202
|
+
gradePolicy(id: string): TestGradePolicy;
|
|
203
|
+
importer(id: string): TestImporter;
|
|
204
|
+
exporter(id: string): TestExporter;
|
|
205
|
+
/**
|
|
206
|
+
* Calls the handler registered with `server.handle` under `contract.name`
|
|
207
|
+
* the way the host does: the input must serialize to at most
|
|
208
|
+
* `EXTENSION_RPC_LIMITS.inputChars` characters and pass the input schema
|
|
209
|
+
* the handler registered; the result must pass the output schema. An
|
|
210
|
+
* unregistered contract, a schema violation and an error of the handler
|
|
211
|
+
* reject the promise. The handler timeout is not applied.
|
|
212
|
+
*/
|
|
213
|
+
rpc<Input, Output>(contract: RpcContract<Input, Output>, input: Input): Promise<Output>;
|
|
214
|
+
/** Runs the cleanup the entry returned and removes the registrations. */
|
|
91
215
|
dispose(): Promise<void>;
|
|
92
216
|
}
|
|
93
|
-
|
|
94
|
-
export
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
217
|
+
/**
|
|
218
|
+
* Starts `entry` (the `server` export of an extension) with in-memory
|
|
219
|
+
* storage, secrets, settings, statistics, notifications and library, and
|
|
220
|
+
* returns a harness to call what it registered. Registration is all or
|
|
221
|
+
* nothing, as in the host: when `entry` throws, so does `createTestServer`.
|
|
222
|
+
*/
|
|
223
|
+
export declare const createTestServer: (entry: ServerEntry$1, options?: TestServerOptions) => Promise<TestServer>;
|
|
224
|
+
/** An answer view as registered: a Vue component or a `Mountable`. */
|
|
225
|
+
export type AnswerViewComponent = Component | Mountable<AnswerViewProps>;
|
|
226
|
+
/** A markdown renderer as registered: a Vue component or a `Mountable`. */
|
|
227
|
+
export type MarkdownRendererComponent = Component | Mountable<MarkdownBlockProps>;
|
|
228
|
+
/** The client part of an extension, started on a recording context. */
|
|
229
|
+
export interface TestClient {
|
|
230
|
+
readonly extensionId: string;
|
|
231
|
+
readonly panels: readonly PanelRegistration$1[];
|
|
232
|
+
/** Injections as registered, with `position` defaulted to `append`. */
|
|
233
|
+
readonly injections: readonly Required<InjectionRegistration$1>[];
|
|
234
|
+
/** Answer views by exercise type id, as registered (a Vue component or a `Mountable`). */
|
|
235
|
+
readonly answerViews: ReadonlyMap<string, AnswerViewComponent>;
|
|
236
|
+
/** Markdown renderers by block language, as registered (a Vue component or a `Mountable`). */
|
|
237
|
+
readonly markdownRenderers: ReadonlyMap<string, MarkdownRendererComponent>;
|
|
238
|
+
readonly themes: readonly ThemeRegistration[];
|
|
239
|
+
readonly commands: readonly ClientCommandRegistration[];
|
|
240
|
+
/** Runs the cleanup the entry returned and removes the registrations. */
|
|
100
241
|
dispose(): Promise<void>;
|
|
101
242
|
}
|
|
102
|
-
export interface
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
243
|
+
export interface TestClientOptions {
|
|
244
|
+
/** Default `test`. When set, every registered id must be equal to it or start with `<extensionId>.`, as the window checks. */
|
|
245
|
+
extensionId?: string;
|
|
246
|
+
/** The window API `client.app` gives to the entry; by default every use of it throws, as the test client has no window. */
|
|
247
|
+
app?: AppApi$1;
|
|
248
|
+
/** The engine `client.engine` gives to the entry; by default every use of it throws. */
|
|
249
|
+
engine?: ExtensionEngine;
|
|
108
250
|
}
|
|
109
251
|
/**
|
|
110
|
-
*
|
|
111
|
-
*
|
|
252
|
+
* Starts `entry` (the `client` export of an extension) on a context that
|
|
253
|
+
* records what it adds, so a test can mount the components and read the
|
|
254
|
+
* themes and commands. An id added twice and an injection with a bad target
|
|
255
|
+
* or position fail like in the window.
|
|
112
256
|
*/
|
|
113
|
-
export declare const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
257
|
+
export declare const createTestClient: (entry: ClientEntry, options?: TestClientOptions) => Promise<TestClient>;
|
|
258
|
+
/** What `mountForTest` gives `ctx`; everything is optional except `props`. */
|
|
259
|
+
export interface MountForTestOptions<Props, Handle = undefined> {
|
|
260
|
+
/** The first `ctx.props`. */
|
|
261
|
+
props: Props;
|
|
262
|
+
/** The element to draw into; by default a new `<div>` of the global `document`. Required without a DOM. */
|
|
263
|
+
el?: HTMLElement;
|
|
264
|
+
/** `ctx.handle`: a panel or injection handle; `undefined` by default. */
|
|
265
|
+
handle?: Handle;
|
|
266
|
+
/** `ctx.app`; by default every use of it throws, as the test has no window. */
|
|
267
|
+
app?: AppApi$1;
|
|
268
|
+
/** `ctx.engine`, the engine of `ctx.callRpc`; by default every use of it throws. */
|
|
269
|
+
engine?: ExtensionEngine;
|
|
270
|
+
/** Default `{ id: 'light', dark: false }`. */
|
|
271
|
+
theme?: AppTheme;
|
|
272
|
+
/** Default `en`. */
|
|
273
|
+
locale?: AppLocale;
|
|
274
|
+
/** Default `test`. */
|
|
275
|
+
extensionId?: string;
|
|
119
276
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
readonly submissions: number;
|
|
138
|
-
/** Sets element properties and waits for the view to apply the update. */
|
|
139
|
-
update(props: Partial<AnswerElementProps>): Promise<void>;
|
|
140
|
-
query<E extends Element = Element>(selector: string): E | null;
|
|
141
|
-
queryAll<E extends Element = Element>(selector: string): E[];
|
|
142
|
-
/** Removes the element from the document; the view receives `destroy()`. */
|
|
143
|
-
dispose(): void;
|
|
277
|
+
/** A `Mountable` mounted by `mountForTest`. */
|
|
278
|
+
export interface MountedForTest<Props, Handle = undefined> {
|
|
279
|
+
readonly el: HTMLElement;
|
|
280
|
+
/** The context the `Mountable` got. */
|
|
281
|
+
readonly ctx: MountContext$1<Props, Handle>;
|
|
282
|
+
/** Replaces `ctx.props` and calls the `onProps` listeners. */
|
|
283
|
+
setProps(next: Props): void;
|
|
284
|
+
/** Replaces `ctx.theme` and calls the `onTheme` listeners. */
|
|
285
|
+
setTheme(next: AppTheme): void;
|
|
286
|
+
/** Replaces `ctx.locale` and calls the `onLocale` listeners. */
|
|
287
|
+
setLocale(next: AppLocale): void;
|
|
288
|
+
/** Every `ctx.emit` call, in order: `[event, payload]`. */
|
|
289
|
+
readonly emitted: readonly (readonly [string, unknown])[];
|
|
290
|
+
/** Every `ctx.reportError` call, in order. */
|
|
291
|
+
readonly errors: readonly unknown[];
|
|
292
|
+
/** Aborts `ctx.signal` and runs the cleanup `mount` returned, once. */
|
|
293
|
+
unmount(): Promise<void>;
|
|
144
294
|
}
|
|
145
295
|
/**
|
|
146
|
-
* Mounts a
|
|
147
|
-
* the
|
|
296
|
+
* Mounts a `Mountable` into an element on a recording context, so a test can
|
|
297
|
+
* change the props, the theme and the language, read what the component
|
|
298
|
+
* emitted and reported, and unmount it. Rejects with what `mount` throws. Needs
|
|
299
|
+
* a DOM (`document`) or `options.el`.
|
|
148
300
|
*/
|
|
149
|
-
export declare const
|
|
150
|
-
export interface LoadPanelOptions {
|
|
151
|
-
/** Properties the panel was opened with (`openPanel(id, props)`). */
|
|
152
|
-
props?: JsonValue;
|
|
153
|
-
/** Reply to `ctx.call`; by default the call is rejected. */
|
|
154
|
-
call?: (commandId: string, args: JsonValue | undefined) => JsonValue | undefined | Promise<JsonValue | undefined>;
|
|
155
|
-
/** Where to mount; defaults to a new `div` in `document.body`. */
|
|
156
|
-
container?: HTMLElement;
|
|
157
|
-
}
|
|
158
|
-
export interface LoadedPanel {
|
|
159
|
-
/** Container the panel received in `mount`. */
|
|
160
|
-
readonly container: HTMLElement;
|
|
161
|
-
/** `ctx.call` invocations in order. */
|
|
162
|
-
readonly calls: readonly {
|
|
163
|
-
commandId: string;
|
|
164
|
-
args: JsonValue | undefined;
|
|
165
|
-
}[];
|
|
166
|
-
/** Whether `ctx.signal` was aborted (after `dispose()`). */
|
|
167
|
-
readonly aborted: boolean;
|
|
168
|
-
/** Sends new properties to the panel (`ctx.onProps`). */
|
|
169
|
-
setProps(props: JsonValue | undefined): void;
|
|
170
|
-
/** Closes the frame: aborts `ctx.signal` and removes the container. */
|
|
171
|
-
dispose(): void;
|
|
172
|
-
}
|
|
173
|
-
/** Mounts a panel from `panels[id]` in the test DOM environment with the same context the frame provides. */
|
|
174
|
-
export declare const loadPanel: (panels: Readonly<Record<string, PanelModule<HTMLElement>>>, id: string, options?: LoadPanelOptions) => Promise<LoadedPanel>;
|
|
301
|
+
export declare const mountForTest: <Props, Handle = undefined>(mountable: Mountable<Props, Handle>, options: MountForTestOptions<Props, Handle>) => Promise<MountedForTest<Props, Handle>>;
|
|
175
302
|
//#endregion
|