@lookit/record 0.0.3
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 +376 -0
- package/dist/consentVideo.d.ts +353 -0
- package/dist/errors.d.ts +158 -0
- package/dist/index.browser.js +26321 -0
- package/dist/index.browser.js.map +1 -0
- package/dist/index.browser.min.js +4 -0
- package/dist/index.browser.min.js.map +1 -0
- package/dist/index.cjs +26321 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +26319 -0
- package/dist/index.js.map +1 -0
- package/dist/mic_check.d.ts +33 -0
- package/dist/recorder.d.ts +146 -0
- package/dist/start.d.ts +24 -0
- package/dist/stop.d.ts +30 -0
- package/dist/trial.d.ts +28 -0
- package/dist/types.d.ts +5 -0
- package/dist/utils.d.ts +21 -0
- package/dist/video_config.d.ts +296 -0
- package/package.json +52 -0
- package/src/consentVideo.spec.ts +274 -0
- package/src/consentVideo.ts +284 -0
- package/src/environment.d.ts +10 -0
- package/src/errors.ts +243 -0
- package/src/img-import.d.ts +1 -0
- package/src/index.spec.ts +104 -0
- package/src/index.ts +13 -0
- package/src/mic_check.d.ts +1 -0
- package/src/mic_check.js +74 -0
- package/src/mic_check.ts +77 -0
- package/src/recorder.spec.ts +446 -0
- package/src/recorder.ts +353 -0
- package/src/start.ts +36 -0
- package/src/stop.ts +46 -0
- package/src/string-import.d.ts +14 -0
- package/src/trial.ts +47 -0
- package/src/types.ts +8 -0
- package/src/utils.spec.ts +55 -0
- package/src/utils.ts +119 -0
- package/src/video_config.spec.ts +1113 -0
- package/src/video_config.ts +665 -0
- package/src/video_config_mic_check.spec.ts +268 -0
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
import Data from "@lookit/data";
|
|
2
|
+
import Handlebars from "handlebars";
|
|
3
|
+
import { initJsPsych } from "jspsych";
|
|
4
|
+
import play_icon from "../img/play-icon.svg";
|
|
5
|
+
import record_icon from "../img/record-icon.svg";
|
|
6
|
+
import playbackFeed from "../templates/playback-feed.hbs";
|
|
7
|
+
import recordFeed from "../templates/record-feed.hbs";
|
|
8
|
+
import webcamFeed from "../templates/webcam-feed.hbs";
|
|
9
|
+
import {
|
|
10
|
+
CreateURLError,
|
|
11
|
+
NoStopPromiseError,
|
|
12
|
+
NoWebCamElementError,
|
|
13
|
+
RecorderInitializeError,
|
|
14
|
+
S3UndefinedError,
|
|
15
|
+
StreamActiveOnResetError,
|
|
16
|
+
StreamDataInitializeError,
|
|
17
|
+
StreamInactiveInitializeError,
|
|
18
|
+
} from "./errors";
|
|
19
|
+
import Recorder from "./recorder";
|
|
20
|
+
import { CSSWidthHeight } from "./types";
|
|
21
|
+
|
|
22
|
+
jest.mock("@lookit/data");
|
|
23
|
+
jest.mock("jspsych", () => ({
|
|
24
|
+
...jest.requireActual("jspsych"),
|
|
25
|
+
initJsPsych: jest.fn().mockReturnValue({
|
|
26
|
+
pluginAPI: {
|
|
27
|
+
getCameraRecorder: jest.fn().mockReturnValue({
|
|
28
|
+
addEventListener: jest.fn(),
|
|
29
|
+
start: jest.fn(),
|
|
30
|
+
stop: jest.fn(),
|
|
31
|
+
stream: {
|
|
32
|
+
active: true,
|
|
33
|
+
clone: jest.fn(),
|
|
34
|
+
getTracks: jest.fn().mockReturnValue([{ stop: jest.fn() }]),
|
|
35
|
+
},
|
|
36
|
+
}),
|
|
37
|
+
},
|
|
38
|
+
}),
|
|
39
|
+
}));
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Remove new lines, indents (tabs or spaces), and empty HTML property values.
|
|
43
|
+
*
|
|
44
|
+
* @param html - HTML string
|
|
45
|
+
* @returns Cleaned String
|
|
46
|
+
*/
|
|
47
|
+
const cleanHTML = (html: string) => {
|
|
48
|
+
return (
|
|
49
|
+
html
|
|
50
|
+
// attributes equals empty string (disabled="")
|
|
51
|
+
.replace(/(="")/gm, "")
|
|
52
|
+
// encoded greater than
|
|
53
|
+
.replace(/(>)/gm, ">")
|
|
54
|
+
// Space before string value of attributes (version=" 1.0")
|
|
55
|
+
.replace(/(=" )/gm, '="')
|
|
56
|
+
// Multiple whitespaces
|
|
57
|
+
.replace(/\s\s+/gm, " ")
|
|
58
|
+
// Whitespace and or slash before html element end (<img />)
|
|
59
|
+
.replace(/\s*\/*>/gm, ">")
|
|
60
|
+
);
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
afterEach(() => {
|
|
64
|
+
jest.clearAllMocks();
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test("Recorder start", async () => {
|
|
68
|
+
const jsPsych = initJsPsych();
|
|
69
|
+
const rec = new Recorder(jsPsych);
|
|
70
|
+
const media = jsPsych.pluginAPI.getCameraRecorder();
|
|
71
|
+
await rec.start("consent");
|
|
72
|
+
|
|
73
|
+
expect(media.addEventListener).toHaveBeenCalledTimes(2);
|
|
74
|
+
expect(media.start).toHaveBeenCalledTimes(1);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test("Recorder stop", async () => {
|
|
78
|
+
const jsPsych = initJsPsych();
|
|
79
|
+
const rec = new Recorder(jsPsych);
|
|
80
|
+
const stopPromise = Promise.resolve();
|
|
81
|
+
const media = jsPsych.pluginAPI.getCameraRecorder();
|
|
82
|
+
|
|
83
|
+
// manual mocks
|
|
84
|
+
rec["stopPromise"] = stopPromise;
|
|
85
|
+
|
|
86
|
+
// check that the "stop promise" is returned on stop
|
|
87
|
+
expect(rec.stop()).toStrictEqual(stopPromise);
|
|
88
|
+
|
|
89
|
+
await rec.stop();
|
|
90
|
+
|
|
91
|
+
expect(media.stop).toHaveBeenCalledTimes(2);
|
|
92
|
+
expect(media.stream.getTracks).toHaveBeenCalledTimes(2);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test("Recorder no stop promise", () => {
|
|
96
|
+
const jsPsych = initJsPsych();
|
|
97
|
+
const rec = new Recorder(jsPsych);
|
|
98
|
+
|
|
99
|
+
// no stop promise
|
|
100
|
+
rec["stopPromise"] = undefined;
|
|
101
|
+
|
|
102
|
+
expect(async () => await rec.stop()).rejects.toThrow(NoStopPromiseError);
|
|
103
|
+
});
|
|
104
|
+
test("Recorder initialize error", () => {
|
|
105
|
+
const jsPsych = initJsPsych();
|
|
106
|
+
const rec = new Recorder(jsPsych);
|
|
107
|
+
const getCameraRecorder = jsPsych.pluginAPI.getCameraRecorder;
|
|
108
|
+
|
|
109
|
+
// no recorder
|
|
110
|
+
jsPsych.pluginAPI.getCameraRecorder = jest.fn().mockReturnValue(undefined);
|
|
111
|
+
jsPsych.pluginAPI.getMicrophoneRecorder = jest
|
|
112
|
+
.fn()
|
|
113
|
+
.mockReturnValue(undefined);
|
|
114
|
+
|
|
115
|
+
expect(async () => await rec.start("consent")).rejects.toThrow(
|
|
116
|
+
RecorderInitializeError,
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
jsPsych.pluginAPI.getCameraRecorder = getCameraRecorder;
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
test("Recorder handleStop", async () => {
|
|
123
|
+
const rec = new Recorder(initJsPsych());
|
|
124
|
+
const download = jest.fn();
|
|
125
|
+
const resolve = jest.fn();
|
|
126
|
+
const handleStop = rec["handleStop"](resolve);
|
|
127
|
+
|
|
128
|
+
// manual mock
|
|
129
|
+
rec["download"] = download;
|
|
130
|
+
rec["blobs"] = ["some recorded data" as unknown as Blob];
|
|
131
|
+
URL.createObjectURL = jest.fn();
|
|
132
|
+
|
|
133
|
+
// let's download the file locally
|
|
134
|
+
rec["localDownload"] = true;
|
|
135
|
+
|
|
136
|
+
await handleStop();
|
|
137
|
+
|
|
138
|
+
// // Upload the file to s3
|
|
139
|
+
rec["localDownload"] = false;
|
|
140
|
+
rec["_s3"] = new Data.LookitS3("some key");
|
|
141
|
+
|
|
142
|
+
await handleStop();
|
|
143
|
+
|
|
144
|
+
expect(download).toHaveBeenCalledTimes(1);
|
|
145
|
+
expect(Data.LookitS3.prototype.completeUpload).toHaveBeenCalledTimes(1);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
test("Recorder handleStop error with no url", () => {
|
|
149
|
+
const rec = new Recorder(initJsPsych());
|
|
150
|
+
const resolve = jest.fn();
|
|
151
|
+
const handleStop = rec["handleStop"](resolve);
|
|
152
|
+
expect(async () => await handleStop()).rejects.toThrow(CreateURLError);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
test("Recorder handleDataAvailable", () => {
|
|
156
|
+
const rec = new Recorder(initJsPsych());
|
|
157
|
+
const handleDataAvailable = rec["handleDataAvailable"];
|
|
158
|
+
const event = jest.fn() as unknown as BlobEvent;
|
|
159
|
+
|
|
160
|
+
rec["localDownload"] = true;
|
|
161
|
+
handleDataAvailable(event);
|
|
162
|
+
expect(Data.LookitS3.prototype.onDataAvailable).toHaveBeenCalledTimes(0);
|
|
163
|
+
|
|
164
|
+
rec["localDownload"] = false;
|
|
165
|
+
rec["_s3"] = new Data.LookitS3("some key");
|
|
166
|
+
handleDataAvailable(event);
|
|
167
|
+
expect(Data.LookitS3.prototype.onDataAvailable).toHaveBeenCalledTimes(1);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
test("Recorder insert webcam display without height/width", () => {
|
|
171
|
+
// Add webcam container to document body.
|
|
172
|
+
const webcam_container_id = "webcam-container";
|
|
173
|
+
document.body.innerHTML = `<div id="${webcam_container_id}"></div>`;
|
|
174
|
+
const webcam_div = document.getElementById(
|
|
175
|
+
webcam_container_id,
|
|
176
|
+
) as HTMLDivElement;
|
|
177
|
+
|
|
178
|
+
const jsPsych = initJsPsych();
|
|
179
|
+
const rec = new Recorder(jsPsych);
|
|
180
|
+
|
|
181
|
+
// Should add the video element with webcam stream to the webcam container.
|
|
182
|
+
rec.insertWebcamFeed(webcam_div);
|
|
183
|
+
|
|
184
|
+
// Use the HTML template and settings to figure out what HTML should have been added.
|
|
185
|
+
const height: CSSWidthHeight = "auto";
|
|
186
|
+
const width: CSSWidthHeight = "100%";
|
|
187
|
+
const webcam_element_id: string = "lookit-jspsych-webcam";
|
|
188
|
+
const params = { height, width, webcam_element_id, record_icon };
|
|
189
|
+
|
|
190
|
+
const rendered_webcam_html = cleanHTML(
|
|
191
|
+
Handlebars.compile(webcamFeed)(params),
|
|
192
|
+
);
|
|
193
|
+
const displayed_html = cleanHTML(document.body.innerHTML);
|
|
194
|
+
|
|
195
|
+
expect(displayed_html).toContain(rendered_webcam_html);
|
|
196
|
+
|
|
197
|
+
// Reset the document body.
|
|
198
|
+
document.body.innerHTML = "";
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
test("Recorder insert webcam display with height/width", () => {
|
|
202
|
+
// Add webcam container to document body.
|
|
203
|
+
const webcam_container_id = "webcam-container";
|
|
204
|
+
document.body.innerHTML = `<div id="${webcam_container_id}"></div>`;
|
|
205
|
+
const webcam_div = document.getElementById(
|
|
206
|
+
webcam_container_id,
|
|
207
|
+
) as HTMLDivElement;
|
|
208
|
+
|
|
209
|
+
const jsPsych = initJsPsych();
|
|
210
|
+
const rec = new Recorder(jsPsych);
|
|
211
|
+
|
|
212
|
+
// Should add the video element with webcam stream to the webcam container,
|
|
213
|
+
// with the specified height and width.
|
|
214
|
+
const height: CSSWidthHeight = "400px";
|
|
215
|
+
const width: CSSWidthHeight = "auto";
|
|
216
|
+
rec.insertWebcamFeed(webcam_div, width, height);
|
|
217
|
+
|
|
218
|
+
// Use the HTML template and settings to figure out what HTML should have been added.
|
|
219
|
+
const webcam_element_id: string = "lookit-jspsych-webcam";
|
|
220
|
+
const params = { height, width, webcam_element_id, record_icon };
|
|
221
|
+
const rendered_webcam_html = cleanHTML(
|
|
222
|
+
Handlebars.compile(webcamFeed)(params),
|
|
223
|
+
);
|
|
224
|
+
const displayed_html = cleanHTML(document.body.innerHTML);
|
|
225
|
+
|
|
226
|
+
expect(displayed_html).toContain(rendered_webcam_html);
|
|
227
|
+
|
|
228
|
+
// Reset the document body.
|
|
229
|
+
document.body.innerHTML = "";
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
test("Webcam feed is removed when stream access stops", async () => {
|
|
233
|
+
// Add webcam container to document body.
|
|
234
|
+
const webcam_container_id = "webcam-container";
|
|
235
|
+
document.body.innerHTML = `<div id="${webcam_container_id}"></div>`;
|
|
236
|
+
const webcam_div = document.getElementById(
|
|
237
|
+
webcam_container_id,
|
|
238
|
+
) as HTMLDivElement;
|
|
239
|
+
|
|
240
|
+
const jsPsych = initJsPsych();
|
|
241
|
+
const rec = new Recorder(jsPsych);
|
|
242
|
+
const stopPromise = Promise.resolve();
|
|
243
|
+
|
|
244
|
+
rec["stopPromise"] = stopPromise;
|
|
245
|
+
rec.insertWebcamFeed(webcam_div);
|
|
246
|
+
expect(document.body.innerHTML).toContain("<video");
|
|
247
|
+
|
|
248
|
+
await rec.stop();
|
|
249
|
+
expect(document.body.innerHTML).not.toContain("<video");
|
|
250
|
+
|
|
251
|
+
// Reset the document body.
|
|
252
|
+
document.body.innerHTML = "";
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
test("Recorder initializeRecorder", () => {
|
|
256
|
+
const jsPsych = initJsPsych();
|
|
257
|
+
const rec = new Recorder(jsPsych);
|
|
258
|
+
const getCameraRecorder = jsPsych.pluginAPI.getCameraRecorder;
|
|
259
|
+
|
|
260
|
+
// MediaRecorder is not available in Jest/jsDom, so mock the implementation of jsPsych.pluginAPI.initializeCameraRecorder (which calls new MediaRecorder) and jsPsych.pluginAPI.getCameraRecorder (which gets the private recorder that was created via jsPsych's initializeCameraRecorder).
|
|
261
|
+
const stream = { fake: "stream" } as unknown as MediaStream;
|
|
262
|
+
const recorder = jest.fn((stream: MediaStream) => {
|
|
263
|
+
return {
|
|
264
|
+
stream: stream,
|
|
265
|
+
start: jest.fn(),
|
|
266
|
+
ondataavailable: jest.fn(),
|
|
267
|
+
onerror: jest.fn(),
|
|
268
|
+
state: "",
|
|
269
|
+
stop: jest.fn(),
|
|
270
|
+
pause: jest.fn(),
|
|
271
|
+
resume: jest.fn(),
|
|
272
|
+
};
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
jsPsych.pluginAPI.initializeCameraRecorder = jest
|
|
276
|
+
.fn()
|
|
277
|
+
.mockImplementation((stream: MediaStream) => {
|
|
278
|
+
return recorder(stream);
|
|
279
|
+
});
|
|
280
|
+
jsPsych.pluginAPI.getCameraRecorder = jest.fn().mockImplementation(() => {
|
|
281
|
+
return jsPsych.pluginAPI.initializeCameraRecorder(stream);
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
rec.initializeRecorder(stream);
|
|
285
|
+
|
|
286
|
+
expect(jsPsych.pluginAPI.initializeCameraRecorder).toHaveBeenCalled();
|
|
287
|
+
expect(rec["stream"]).toStrictEqual(stream);
|
|
288
|
+
|
|
289
|
+
jsPsych.pluginAPI.getCameraRecorder = getCameraRecorder;
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
test("Recorder download", () => {
|
|
293
|
+
const rec = new Recorder(initJsPsych());
|
|
294
|
+
rec["url"] = "some url";
|
|
295
|
+
rec["filename"] = "some filename";
|
|
296
|
+
const download = rec["download"];
|
|
297
|
+
const click = jest.spyOn(HTMLAnchorElement.prototype, "click");
|
|
298
|
+
|
|
299
|
+
download();
|
|
300
|
+
|
|
301
|
+
expect(click).toHaveBeenCalledTimes(1);
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
test("Recorder s3 get error when undefined", () => {
|
|
305
|
+
const jsPsych = initJsPsych();
|
|
306
|
+
const rec = new Recorder(jsPsych);
|
|
307
|
+
|
|
308
|
+
expect(() => rec["s3"]).toThrow(S3UndefinedError);
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
test("Recorder reset error when stream active", () => {
|
|
312
|
+
const jsPsych = initJsPsych();
|
|
313
|
+
const rec = new Recorder(jsPsych);
|
|
314
|
+
expect(() => rec.reset()).toThrow(StreamActiveOnResetError);
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
test("Recorder reset", () => {
|
|
318
|
+
const jsPsych = initJsPsych();
|
|
319
|
+
const rec = new Recorder(jsPsych);
|
|
320
|
+
const getCameraRecorder = jsPsych.pluginAPI.getCameraRecorder;
|
|
321
|
+
const streamClone = jest.fn();
|
|
322
|
+
|
|
323
|
+
jsPsych.pluginAPI.getCameraRecorder = jest
|
|
324
|
+
.fn()
|
|
325
|
+
.mockReturnValue({ stream: { active: false } });
|
|
326
|
+
rec["streamClone"] = {
|
|
327
|
+
clone: jest.fn().mockReturnValue(streamClone),
|
|
328
|
+
} as unknown as MediaStream;
|
|
329
|
+
rec["blobs"] = ["some stream data" as unknown as Blob];
|
|
330
|
+
|
|
331
|
+
expect(rec["blobs"]).not.toStrictEqual([]);
|
|
332
|
+
|
|
333
|
+
rec.reset();
|
|
334
|
+
|
|
335
|
+
expect(jsPsych.pluginAPI.initializeCameraRecorder).toHaveBeenCalledTimes(1);
|
|
336
|
+
expect(jsPsych.pluginAPI.initializeCameraRecorder).toHaveBeenCalledWith(
|
|
337
|
+
streamClone,
|
|
338
|
+
undefined,
|
|
339
|
+
);
|
|
340
|
+
expect(rec["blobs"]).toStrictEqual([]);
|
|
341
|
+
|
|
342
|
+
jsPsych.pluginAPI.getCameraRecorder = getCameraRecorder;
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
test("Record insert webcam feed error when no element", () => {
|
|
346
|
+
const jsPsych = initJsPsych();
|
|
347
|
+
const rec = new Recorder(jsPsych);
|
|
348
|
+
const div = { querySelector: jest.fn() } as unknown as HTMLDivElement;
|
|
349
|
+
expect(() => rec.insertWebcamFeed(div)).toThrow(NoWebCamElementError);
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
test("Record insert Playback feed", () => {
|
|
353
|
+
const jsPsych = initJsPsych();
|
|
354
|
+
const rec = new Recorder(jsPsych);
|
|
355
|
+
const webcam_container_id = "webcam-container";
|
|
356
|
+
const height: CSSWidthHeight = "auto";
|
|
357
|
+
const width: CSSWidthHeight = "100%";
|
|
358
|
+
const webcam_element_id: string = "lookit-jspsych-webcam";
|
|
359
|
+
|
|
360
|
+
rec["url"] = "some url";
|
|
361
|
+
|
|
362
|
+
const view = {
|
|
363
|
+
src: rec["url"],
|
|
364
|
+
width,
|
|
365
|
+
height,
|
|
366
|
+
webcam_element_id,
|
|
367
|
+
play_icon,
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
document.body.innerHTML = `<div id="${webcam_container_id}"></div>`;
|
|
371
|
+
const webcam_div = document.getElementById(
|
|
372
|
+
webcam_container_id,
|
|
373
|
+
) as HTMLDivElement;
|
|
374
|
+
|
|
375
|
+
rec.insertPlaybackFeed(webcam_div, () => {});
|
|
376
|
+
|
|
377
|
+
const tempHtml = cleanHTML(Handlebars.compile(playbackFeed)(view));
|
|
378
|
+
const docHtml = cleanHTML(
|
|
379
|
+
document.body.querySelector("#webcam-container")!.innerHTML,
|
|
380
|
+
);
|
|
381
|
+
|
|
382
|
+
expect(docHtml).toStrictEqual(tempHtml);
|
|
383
|
+
|
|
384
|
+
document.body.innerHTML = "";
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
test("Record insert Playback feed error if no container", () => {
|
|
388
|
+
const jsPsych = initJsPsych();
|
|
389
|
+
const rec = new Recorder(jsPsych);
|
|
390
|
+
const div = {
|
|
391
|
+
querySelector: jest.fn(),
|
|
392
|
+
insertAdjacentHTML: jest.fn(),
|
|
393
|
+
} as unknown as HTMLDivElement;
|
|
394
|
+
expect(() => rec.insertPlaybackFeed(div, () => {})).toThrow(
|
|
395
|
+
NoWebCamElementError,
|
|
396
|
+
);
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
test("Record initialize error inactive stream", () => {
|
|
400
|
+
const jsPsych = initJsPsych();
|
|
401
|
+
const rec = new Recorder(jsPsych);
|
|
402
|
+
const initializeCheck = rec["initializeCheck"];
|
|
403
|
+
const getCameraRecorder = jsPsych.pluginAPI.getCameraRecorder;
|
|
404
|
+
|
|
405
|
+
jsPsych.pluginAPI.getCameraRecorder = jest
|
|
406
|
+
.fn()
|
|
407
|
+
.mockReturnValue({ stream: { active: false } });
|
|
408
|
+
|
|
409
|
+
expect(() => initializeCheck()).toThrow(StreamInactiveInitializeError);
|
|
410
|
+
|
|
411
|
+
jsPsych.pluginAPI.getCameraRecorder = getCameraRecorder;
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
test("Record initialize error inactive stream", () => {
|
|
415
|
+
const jsPsych = initJsPsych();
|
|
416
|
+
const rec = new Recorder(jsPsych);
|
|
417
|
+
const initializeCheck = rec["initializeCheck"];
|
|
418
|
+
|
|
419
|
+
rec["blobs"] = ["some stream data" as unknown as Blob];
|
|
420
|
+
|
|
421
|
+
expect(() => initializeCheck()).toThrow(StreamDataInitializeError);
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
test("Recorder insert record Feed with height/width", () => {
|
|
425
|
+
const jsPsych = initJsPsych();
|
|
426
|
+
const rec = new Recorder(jsPsych);
|
|
427
|
+
const display = document.createElement("div");
|
|
428
|
+
|
|
429
|
+
const view = {
|
|
430
|
+
height: "auto",
|
|
431
|
+
width: "100%",
|
|
432
|
+
webcam_element_id: "lookit-jspsych-webcam",
|
|
433
|
+
record_icon,
|
|
434
|
+
};
|
|
435
|
+
|
|
436
|
+
jest.spyOn(Handlebars, "compile");
|
|
437
|
+
jest.spyOn(rec, "insertVideoFeed");
|
|
438
|
+
|
|
439
|
+
rec.insertRecordFeed(display);
|
|
440
|
+
|
|
441
|
+
expect(Handlebars.compile).toHaveBeenCalledWith(recordFeed);
|
|
442
|
+
expect(rec["insertVideoFeed"]).toHaveBeenCalledWith(
|
|
443
|
+
display,
|
|
444
|
+
Handlebars.compile(recordFeed)(view),
|
|
445
|
+
);
|
|
446
|
+
});
|