jsPsych/packages/jspsych/tests/utils.ts
bjoluc c119650471 Move experiment execution into jsPsych.run()
The `run()` method takes a timeline and returns a promise that is
resolved when the experiment finishes.
Hence, jsPsych can now be initialized without starting an experiment.
This re-enables usage of `jsPsych.timelineVariable()` in timeline
definitions and repairs exclusion checks and extension loading.
2021-07-19 17:10:37 +02:00

78 lines
2.4 KiB
TypeScript

import { setImmediate as flushMicroTasks } from "timers";
import { JsPsych } from "../src";
export function dispatchEvent(event: Event) {
document.querySelector(".jspsych-display-element").dispatchEvent(event);
}
export function keyDown(key: string) {
dispatchEvent(new KeyboardEvent("keydown", { key }));
}
export function keyUp(key: string) {
dispatchEvent(new KeyboardEvent("keyup", { key }));
}
export function pressKey(key: string) {
keyDown(key);
keyUp(key);
}
export function mouseDownMouseUpTarget(target: Element) {
target.dispatchEvent(new MouseEvent("mousedown", { bubbles: true }));
target.dispatchEvent(new MouseEvent("mouseup", { bubbles: true }));
}
export function clickTarget(target: Element) {
target.dispatchEvent(new MouseEvent("click", { bubbles: true }));
}
/**
* https://github.com/facebook/jest/issues/2157#issuecomment-279171856
*/
export function flushPromises() {
return new Promise((resolve) => flushMicroTasks(resolve));
}
/**
* Runs the given timeline by calling `jsPsych.run()` on the provided JsPsych object.
*
* @param timeline The timeline that is passed to `jsPsych.run()`
* @param jsPsych The jsPsych instance to be used. If left empty, a new instance will be created. If
* a settings object is passed instead, the settings will be used to create the jsPsych instance.
*
* @returns An object containing test helper functions, the jsPsych instance, and the jsPsych
* display element
*/
export async function startTimeline(timeline: any[], jsPsych: JsPsych | any = {}) {
const jsPsychInstance = jsPsych instanceof JsPsych ? jsPsych : new JsPsych(jsPsych);
let hasFinished = false;
const finished = jsPsychInstance.run(timeline).then(() => {
hasFinished = true;
});
await flushPromises();
const displayElement = jsPsychInstance.getDisplayElement();
return {
jsPsych: jsPsychInstance,
displayElement,
/** Shorthand for `jsPsych.getDisplayElement().innerHTML` */
getHTML: () => displayElement.innerHTML,
/** Shorthand for `jsPsych.data.get()` */
getData: () => jsPsychInstance.data.get(),
expectFinished: async () => {
await flushPromises();
expect(hasFinished).toBe(true);
},
expectRunning: async () => {
await flushPromises();
expect(hasFinished).toBe(false);
},
/** A promise that is resolved when `jsPsych.run()` is done. */
finished,
};
}