@jspsych/test-utils 1.2.0 → 1.3.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/dist/index.cjs +15 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.js +15 -5
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +9 -4
package/dist/index.cjs
CHANGED
|
@@ -10,16 +10,20 @@ function dispatchEvent(event, target = document.body) {
|
|
|
10
10
|
target.dispatchEvent(event);
|
|
11
11
|
return flushPromises();
|
|
12
12
|
}
|
|
13
|
-
async function keyDown(key) {
|
|
14
|
-
await dispatchEvent(new KeyboardEvent("keydown", { key }));
|
|
13
|
+
async function keyDown(key, code) {
|
|
14
|
+
await dispatchEvent(new KeyboardEvent("keydown", { key, code }));
|
|
15
15
|
}
|
|
16
|
-
async function keyUp(key) {
|
|
17
|
-
await dispatchEvent(new KeyboardEvent("keyup", { key }));
|
|
16
|
+
async function keyUp(key, code) {
|
|
17
|
+
await dispatchEvent(new KeyboardEvent("keyup", { key, code }));
|
|
18
18
|
}
|
|
19
19
|
async function pressKey(key) {
|
|
20
20
|
await keyDown(key);
|
|
21
21
|
await keyUp(key);
|
|
22
22
|
}
|
|
23
|
+
async function windowBlur() {
|
|
24
|
+
window.dispatchEvent(new Event("blur"));
|
|
25
|
+
await flushPromises();
|
|
26
|
+
}
|
|
23
27
|
async function mouseDownMouseUpTarget(target) {
|
|
24
28
|
await dispatchEvent(new MouseEvent("mousedown", { bubbles: true }), target);
|
|
25
29
|
await dispatchEvent(new MouseEvent("mouseup", { bubbles: true }), target);
|
|
@@ -64,7 +68,9 @@ async function startTimeline(timeline, jsPsych = {}) {
|
|
|
64
68
|
return {
|
|
65
69
|
jsPsych: jsPsychInstance,
|
|
66
70
|
displayElement,
|
|
71
|
+
/** Shorthand for `jsPsych.getDisplayElement().innerHTML` */
|
|
67
72
|
getHTML: () => displayElement.innerHTML,
|
|
73
|
+
/** Shorthand for `jsPsych.data.get()` */
|
|
68
74
|
getData: () => jsPsychInstance.data.get(),
|
|
69
75
|
expectFinished: async () => {
|
|
70
76
|
await flushPromises();
|
|
@@ -74,6 +80,7 @@ async function startTimeline(timeline, jsPsych = {}) {
|
|
|
74
80
|
await flushPromises();
|
|
75
81
|
expect(hasFinished).toBe(false);
|
|
76
82
|
},
|
|
83
|
+
/** A promise that is resolved when `jsPsych.run()` is done. */
|
|
77
84
|
finished
|
|
78
85
|
};
|
|
79
86
|
}
|
|
@@ -88,7 +95,9 @@ async function simulateTimeline(timeline, simulation_mode, simulation_options =
|
|
|
88
95
|
return {
|
|
89
96
|
jsPsych: jsPsychInstance,
|
|
90
97
|
displayElement,
|
|
98
|
+
/** Shorthand for `jsPsych.getDisplayElement().innerHTML` */
|
|
91
99
|
getHTML: () => displayElement.innerHTML,
|
|
100
|
+
/** Shorthand for `jsPsych.data.get()` */
|
|
92
101
|
getData: () => jsPsychInstance.data.get(),
|
|
93
102
|
expectFinished: async () => {
|
|
94
103
|
await flushPromises();
|
|
@@ -98,6 +107,7 @@ async function simulateTimeline(timeline, simulation_mode, simulation_options =
|
|
|
98
107
|
await flushPromises();
|
|
99
108
|
expect(hasFinished).toBe(false);
|
|
100
109
|
},
|
|
110
|
+
/** A promise that is resolved when `jsPsych.simulate()` is done. */
|
|
101
111
|
finished
|
|
102
112
|
};
|
|
103
113
|
}
|
|
@@ -114,4 +124,5 @@ exports.mouseUp = mouseUp;
|
|
|
114
124
|
exports.pressKey = pressKey;
|
|
115
125
|
exports.simulateTimeline = simulateTimeline;
|
|
116
126
|
exports.startTimeline = startTimeline;
|
|
127
|
+
exports.windowBlur = windowBlur;
|
|
117
128
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/index.ts"],"sourcesContent":["import { setImmediate as flushMicroTasks } from \"timers\";\n\nimport { JsPsych } from \"jspsych\";\n\n/**\n * https://github.com/facebook/jest/issues/2157#issuecomment-279171856\n */\nexport function flushPromises() {\n return new Promise((resolve) => flushMicroTasks(resolve));\n}\n\nexport function dispatchEvent(event: Event, target: Element = document.body) {\n target.dispatchEvent(event);\n return flushPromises();\n}\n\nexport async function keyDown(key: string) {\n await dispatchEvent(new KeyboardEvent(\"keydown\", { key }));\n}\n\nexport async function keyUp(key: string) {\n await dispatchEvent(new KeyboardEvent(\"keyup\", { key }));\n}\n\nexport async function pressKey(key: string) {\n await keyDown(key);\n await keyUp(key);\n}\n\nexport async function mouseDownMouseUpTarget(target: Element) {\n await dispatchEvent(new MouseEvent(\"mousedown\", { bubbles: true }), target);\n await dispatchEvent(new MouseEvent(\"mouseup\", { bubbles: true }), target);\n}\n\nexport async function clickTarget(target: Element) {\n // Check if the target is a form element and if it's disabled\n if (target instanceof HTMLButtonElement || target instanceof HTMLInputElement) {\n if (target.disabled) {\n console.log(\"Target is disabled, not dispatching click event.\");\n return; // Exit the function if the target is disabled\n }\n }\n await dispatchEvent(new MouseEvent(\"click\", { bubbles: true }), target);\n}\n\n/**\n * Dispatch a `MouseEvent` of type `eventType`, with x and y defined relative to the container element.\n * @param x The x location of the event, relative to the x location of `container`.\n * @param y The y location of the event, relative to the y location of `container`.\n * @param container The DOM element for relative location of the event.\n */\nasync function dispatchMouseEvent(eventType: string, x: number, y: number, container: Element) {\n const containerRect = container.getBoundingClientRect();\n await dispatchEvent(\n new MouseEvent(eventType, {\n clientX: containerRect.x + x,\n clientY: containerRect.y + y,\n bubbles: true,\n }),\n container\n );\n}\n\n/**\n * Dispatch a `mousemove` event, with x and y defined relative to the container element.\n * @param x The x location of the event, relative to the x location of `container`.\n * @param y The y location of the event, relative to the y location of `container`.\n * @param container The DOM element for relative location of the event.\n */\nexport async function mouseMove(x: number, y: number, container: Element) {\n await dispatchMouseEvent(\"mousemove\", x, y, container);\n}\n\n/**\n * Dispatch a `mouseup` event, with x and y defined relative to the container element.\n * @param x The x location of the event, relative to the x location of `container`.\n * @param y The y location of the event, relative to the y location of `container`.\n * @param container The DOM element for relative location of the event.\n */\nexport async function mouseUp(x: number, y: number, container: Element) {\n await dispatchMouseEvent(\"mouseup\", x, y, container);\n}\n\n/**\n * Dispatch a `mousemove` event, with x and y defined relative to the container element.\n * @param x The x location of the event, relative to the x location of `container`.\n * @param y The y location of the event, relative to the y location of `container`.\n * @param container The DOM element for relative location of the event.\n */\nexport async function mouseDown(x: number, y: number, container: Element) {\n await dispatchMouseEvent(\"mousedown\", x, y, container);\n}\n\n/**\n * Runs the given timeline by calling `jsPsych.run()` on the provided JsPsych object.\n *\n * @param timeline The timeline that is passed to `jsPsych.run()`\n * @param jsPsych The jsPsych instance to be used. If left empty, a new instance will be created. If\n * a settings object is passed instead, the settings will be used to create the jsPsych instance.\n *\n * @returns An object containing test helper functions, the jsPsych instance, and the jsPsych\n * display element\n */\nexport async function startTimeline(timeline: any[], jsPsych: JsPsych | any = {}) {\n const jsPsychInstance = jsPsych instanceof JsPsych ? jsPsych : new JsPsych(jsPsych);\n\n let hasFinished = false;\n const finished = jsPsychInstance.run(timeline).then(() => {\n hasFinished = true;\n });\n await flushPromises();\n\n const displayElement = jsPsychInstance.getDisplayElement();\n\n return {\n jsPsych: jsPsychInstance,\n displayElement,\n /** Shorthand for `jsPsych.getDisplayElement().innerHTML` */\n getHTML: () => displayElement.innerHTML,\n /** Shorthand for `jsPsych.data.get()` */\n getData: () => jsPsychInstance.data.get(),\n expectFinished: async () => {\n await flushPromises();\n expect(hasFinished).toBe(true);\n },\n expectRunning: async () => {\n await flushPromises();\n expect(hasFinished).toBe(false);\n },\n /** A promise that is resolved when `jsPsych.run()` is done. */\n finished,\n };\n}\n\n/**\n * Runs the given timeline by calling `jsPsych.simulate()` on the provided JsPsych object.\n *\n * @param timeline The timeline that is passed to `jsPsych.run()`\n * @param simulation_mode Either 'data-only' mode or 'visual' mode.\n * @param simulation_options Options to pass to `jsPsych.simulate()`\n * @param jsPsych The jsPsych instance to be used. If left empty, a new instance will be created. If\n * a settings object is passed instead, the settings will be used to create the jsPsych instance.\n *\n * @returns An object containing test helper functions, the jsPsych instance, and the jsPsych\n * display element\n */\nexport async function simulateTimeline(\n timeline: any[],\n simulation_mode?: \"data-only\" | \"visual\",\n simulation_options: any = {},\n jsPsych: JsPsych | any = {}\n) {\n const jsPsychInstance = jsPsych instanceof JsPsych ? jsPsych : new JsPsych(jsPsych);\n\n let hasFinished = false;\n const finished = jsPsychInstance\n .simulate(timeline, simulation_mode, simulation_options)\n .then(() => {\n hasFinished = true;\n });\n await flushPromises();\n\n const displayElement = jsPsychInstance.getDisplayElement();\n\n return {\n jsPsych: jsPsychInstance,\n displayElement,\n /** Shorthand for `jsPsych.getDisplayElement().innerHTML` */\n getHTML: () => displayElement.innerHTML,\n /** Shorthand for `jsPsych.data.get()` */\n getData: () => jsPsychInstance.data.get(),\n expectFinished: async () => {\n await flushPromises();\n expect(hasFinished).toBe(true);\n },\n expectRunning: async () => {\n await flushPromises();\n expect(hasFinished).toBe(false);\n },\n /** A promise that is resolved when `jsPsych.simulate()` is done. */\n finished,\n };\n}\n"],"names":["flushMicroTasks","JsPsych"],"mappings":";;;;;AAOO,SAAS,aAAgB,GAAA;AAC9B,EAAA,OAAO,IAAI,OAAQ,CAAA,CAAC,OAAY,KAAAA,wBAAA,CAAgB,OAAO,CAAC,CAAA,CAAA;AAC1D,CAAA;AAEO,SAAS,aAAc,CAAA,KAAA,EAAc,MAAkB,GAAA,QAAA,CAAS,IAAM,EAAA;AAC3E,EAAA,MAAA,CAAO,cAAc,KAAK,CAAA,CAAA;AAC1B,EAAA,OAAO,aAAc,EAAA,CAAA;AACvB,CAAA;AAEA,eAAsB,QAAQ,GAAa,EAAA;AACzC,EAAA,MAAM,cAAc,IAAI,aAAA,CAAc,WAAW,EAAE,GAAA,EAAK,CAAC,CAAA,CAAA;AAC3D,CAAA;AAEA,eAAsB,MAAM,GAAa,EAAA;AACvC,EAAA,MAAM,cAAc,IAAI,aAAA,CAAc,SAAS,EAAE,GAAA,EAAK,CAAC,CAAA,CAAA;AACzD,CAAA;AAEA,eAAsB,SAAS,GAAa,EAAA;AAC1C,EAAA,MAAM,QAAQ,GAAG,CAAA,CAAA;AACjB,EAAA,MAAM,MAAM,GAAG,CAAA,CAAA;AACjB,CAAA;AAEA,eAAsB,uBAAuB,MAAiB,EAAA;AAC5D,EAAM,MAAA,aAAA,CAAc,IAAI,UAAW,CAAA,WAAA,EAAa,EAAE,OAAS,EAAA,IAAA,EAAM,CAAA,EAAG,MAAM,CAAA,CAAA;AAC1E,EAAM,MAAA,aAAA,CAAc,IAAI,UAAW,CAAA,SAAA,EAAW,EAAE,OAAS,EAAA,IAAA,EAAM,CAAA,EAAG,MAAM,CAAA,CAAA;AAC1E,CAAA;AAEA,eAAsB,YAAY,MAAiB,EAAA;AAEjD,EAAI,IAAA,MAAA,YAAkB,iBAAqB,IAAA,MAAA,YAAkB,gBAAkB,EAAA;AAC7E,IAAA,IAAI,OAAO,QAAU,EAAA;AACnB,MAAA,OAAA,CAAQ,IAAI,kDAAkD,CAAA,CAAA;AAC9D,MAAA,OAAA;AAAA,KACF;AAAA,GACF;AACA,EAAM,MAAA,aAAA,CAAc,IAAI,UAAW,CAAA,OAAA,EAAS,EAAE,OAAS,EAAA,IAAA,EAAM,CAAA,EAAG,MAAM,CAAA,CAAA;AACxE,CAAA;AAQA,eAAe,kBAAmB,CAAA,SAAA,EAAmB,CAAW,EAAA,CAAA,EAAW,SAAoB,EAAA;AAC7F,EAAM,MAAA,aAAA,GAAgB,UAAU,qBAAsB,EAAA,CAAA;AACtD,EAAM,MAAA,aAAA;AAAA,IACJ,IAAI,WAAW,SAAW,EAAA;AAAA,MACxB,OAAA,EAAS,cAAc,CAAI,GAAA,CAAA;AAAA,MAC3B,OAAA,EAAS,cAAc,CAAI,GAAA,CAAA;AAAA,MAC3B,OAAS,EAAA,IAAA;AAAA,KACV,CAAA;AAAA,IACD,SAAA;AAAA,GACF,CAAA;AACF,CAAA;AAQsB,eAAA,SAAA,CAAU,CAAW,EAAA,CAAA,EAAW,SAAoB,EAAA;AACxE,EAAA,MAAM,kBAAmB,CAAA,WAAA,EAAa,CAAG,EAAA,CAAA,EAAG,SAAS,CAAA,CAAA;AACvD,CAAA;AAQsB,eAAA,OAAA,CAAQ,CAAW,EAAA,CAAA,EAAW,SAAoB,EAAA;AACtE,EAAA,MAAM,kBAAmB,CAAA,SAAA,EAAW,CAAG,EAAA,CAAA,EAAG,SAAS,CAAA,CAAA;AACrD,CAAA;AAQsB,eAAA,SAAA,CAAU,CAAW,EAAA,CAAA,EAAW,SAAoB,EAAA;AACxE,EAAA,MAAM,kBAAmB,CAAA,WAAA,EAAa,CAAG,EAAA,CAAA,EAAG,SAAS,CAAA,CAAA;AACvD,CAAA;AAYA,eAAsB,aAAc,CAAA,QAAA,EAAiB,OAAyB,GAAA,EAAI,EAAA;AAChF,EAAA,MAAM,kBAAkB,OAAmB,YAAAC,eAAA,GAAU,OAAU,GAAA,IAAIA,gBAAQ,OAAO,CAAA,CAAA;AAElF,EAAA,IAAI,WAAc,GAAA,KAAA,CAAA;AAClB,EAAA,MAAM,WAAW,eAAgB,CAAA,GAAA,CAAI,QAAQ,CAAA,CAAE,KAAK,MAAM;AACxD,IAAc,WAAA,GAAA,IAAA,CAAA;AAAA,GACf,CAAA,CAAA;AACD,EAAA,MAAM,aAAc,EAAA,CAAA;AAEpB,EAAM,MAAA,cAAA,GAAiB,gBAAgB,iBAAkB,EAAA,CAAA;AAEzD,EAAO,OAAA;AAAA,IACL,OAAS,EAAA,eAAA;AAAA,IACT,cAAA;AAAA,IAEA,OAAA,EAAS,MAAM,cAAe,CAAA,SAAA;AAAA,IAE9B,OAAS,EAAA,MAAM,eAAgB,CAAA,IAAA,CAAK,GAAI,EAAA;AAAA,IACxC,gBAAgB,YAAY;AAC1B,MAAA,MAAM,aAAc,EAAA,CAAA;AACpB,MAAO,MAAA,CAAA,WAAW,CAAE,CAAA,IAAA,CAAK,IAAI,CAAA,CAAA;AAAA,KAC/B;AAAA,IACA,eAAe,YAAY;AACzB,MAAA,MAAM,aAAc,EAAA,CAAA;AACpB,MAAO,MAAA,CAAA,WAAW,CAAE,CAAA,IAAA,CAAK,KAAK,CAAA,CAAA;AAAA,KAChC;AAAA,IAEA,QAAA;AAAA,GACF,CAAA;AACF,CAAA;AAcsB,eAAA,gBAAA,CACpB,UACA,eACA,EAAA,kBAAA,GAA0B,EAC1B,EAAA,OAAA,GAAyB,EACzB,EAAA;AACA,EAAA,MAAM,kBAAkB,OAAmB,YAAAA,eAAA,GAAU,OAAU,GAAA,IAAIA,gBAAQ,OAAO,CAAA,CAAA;AAElF,EAAA,IAAI,WAAc,GAAA,KAAA,CAAA;AAClB,EAAM,MAAA,QAAA,GAAW,gBACd,QAAS,CAAA,QAAA,EAAU,iBAAiB,kBAAkB,CAAA,CACtD,KAAK,MAAM;AACV,IAAc,WAAA,GAAA,IAAA,CAAA;AAAA,GACf,CAAA,CAAA;AACH,EAAA,MAAM,aAAc,EAAA,CAAA;AAEpB,EAAM,MAAA,cAAA,GAAiB,gBAAgB,iBAAkB,EAAA,CAAA;AAEzD,EAAO,OAAA;AAAA,IACL,OAAS,EAAA,eAAA;AAAA,IACT,cAAA;AAAA,IAEA,OAAA,EAAS,MAAM,cAAe,CAAA,SAAA;AAAA,IAE9B,OAAS,EAAA,MAAM,eAAgB,CAAA,IAAA,CAAK,GAAI,EAAA;AAAA,IACxC,gBAAgB,YAAY;AAC1B,MAAA,MAAM,aAAc,EAAA,CAAA;AACpB,MAAO,MAAA,CAAA,WAAW,CAAE,CAAA,IAAA,CAAK,IAAI,CAAA,CAAA;AAAA,KAC/B;AAAA,IACA,eAAe,YAAY;AACzB,MAAA,MAAM,aAAc,EAAA,CAAA;AACpB,MAAO,MAAA,CAAA,WAAW,CAAE,CAAA,IAAA,CAAK,KAAK,CAAA,CAAA;AAAA,KAChC;AAAA,IAEA,QAAA;AAAA,GACF,CAAA;AACF;;;;;;;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/index.ts"],"sourcesContent":["import { setImmediate as flushMicroTasks } from \"timers\";\n\nimport { JsPsych } from \"jspsych\";\n\n/**\n * https://github.com/facebook/jest/issues/2157#issuecomment-279171856\n */\nexport function flushPromises() {\n return new Promise((resolve) => flushMicroTasks(resolve));\n}\n\nexport function dispatchEvent(event: Event, target: Element = document.body) {\n target.dispatchEvent(event);\n return flushPromises();\n}\n\nexport async function keyDown(key: string, code?: string) {\n await dispatchEvent(new KeyboardEvent(\"keydown\", { key, code }));\n}\n\nexport async function keyUp(key: string, code?: string) {\n await dispatchEvent(new KeyboardEvent(\"keyup\", { key, code }));\n}\n\nexport async function pressKey(key: string) {\n await keyDown(key);\n await keyUp(key);\n}\n\nexport async function windowBlur() {\n window.dispatchEvent(new Event(\"blur\"));\n await flushPromises();\n}\n\nexport async function mouseDownMouseUpTarget(target: Element) {\n await dispatchEvent(new MouseEvent(\"mousedown\", { bubbles: true }), target);\n await dispatchEvent(new MouseEvent(\"mouseup\", { bubbles: true }), target);\n}\n\nexport async function clickTarget(target: Element) {\n // Check if the target is a form element and if it's disabled\n if (target instanceof HTMLButtonElement || target instanceof HTMLInputElement) {\n if (target.disabled) {\n console.log(\"Target is disabled, not dispatching click event.\");\n return; // Exit the function if the target is disabled\n }\n }\n await dispatchEvent(new MouseEvent(\"click\", { bubbles: true }), target);\n}\n\n/**\n * Dispatch a `MouseEvent` of type `eventType`, with x and y defined relative to the container element.\n * @param x The x location of the event, relative to the x location of `container`.\n * @param y The y location of the event, relative to the y location of `container`.\n * @param container The DOM element for relative location of the event.\n */\nasync function dispatchMouseEvent(eventType: string, x: number, y: number, container: Element) {\n const containerRect = container.getBoundingClientRect();\n await dispatchEvent(\n new MouseEvent(eventType, {\n clientX: containerRect.x + x,\n clientY: containerRect.y + y,\n bubbles: true,\n }),\n container\n );\n}\n\n/**\n * Dispatch a `mousemove` event, with x and y defined relative to the container element.\n * @param x The x location of the event, relative to the x location of `container`.\n * @param y The y location of the event, relative to the y location of `container`.\n * @param container The DOM element for relative location of the event.\n */\nexport async function mouseMove(x: number, y: number, container: Element) {\n await dispatchMouseEvent(\"mousemove\", x, y, container);\n}\n\n/**\n * Dispatch a `mouseup` event, with x and y defined relative to the container element.\n * @param x The x location of the event, relative to the x location of `container`.\n * @param y The y location of the event, relative to the y location of `container`.\n * @param container The DOM element for relative location of the event.\n */\nexport async function mouseUp(x: number, y: number, container: Element) {\n await dispatchMouseEvent(\"mouseup\", x, y, container);\n}\n\n/**\n * Dispatch a `mousemove` event, with x and y defined relative to the container element.\n * @param x The x location of the event, relative to the x location of `container`.\n * @param y The y location of the event, relative to the y location of `container`.\n * @param container The DOM element for relative location of the event.\n */\nexport async function mouseDown(x: number, y: number, container: Element) {\n await dispatchMouseEvent(\"mousedown\", x, y, container);\n}\n\n/**\n * Runs the given timeline by calling `jsPsych.run()` on the provided JsPsych object.\n *\n * @param timeline The timeline that is passed to `jsPsych.run()`\n * @param jsPsych The jsPsych instance to be used. If left empty, a new instance will be created. If\n * a settings object is passed instead, the settings will be used to create the jsPsych instance.\n *\n * @returns An object containing test helper functions, the jsPsych instance, and the jsPsych\n * display element\n */\nexport async function startTimeline(timeline: any[], jsPsych: JsPsych | any = {}) {\n const jsPsychInstance = jsPsych instanceof JsPsych ? jsPsych : new JsPsych(jsPsych);\n\n let hasFinished = false;\n const finished = jsPsychInstance.run(timeline).then(() => {\n hasFinished = true;\n });\n await flushPromises();\n\n const displayElement = jsPsychInstance.getDisplayElement();\n\n return {\n jsPsych: jsPsychInstance,\n displayElement,\n /** Shorthand for `jsPsych.getDisplayElement().innerHTML` */\n getHTML: () => displayElement.innerHTML,\n /** Shorthand for `jsPsych.data.get()` */\n getData: () => jsPsychInstance.data.get(),\n expectFinished: async () => {\n await flushPromises();\n expect(hasFinished).toBe(true);\n },\n expectRunning: async () => {\n await flushPromises();\n expect(hasFinished).toBe(false);\n },\n /** A promise that is resolved when `jsPsych.run()` is done. */\n finished,\n };\n}\n\n/**\n * Runs the given timeline by calling `jsPsych.simulate()` on the provided JsPsych object.\n *\n * @param timeline The timeline that is passed to `jsPsych.run()`\n * @param simulation_mode Either 'data-only' mode or 'visual' mode.\n * @param simulation_options Options to pass to `jsPsych.simulate()`\n * @param jsPsych The jsPsych instance to be used. If left empty, a new instance will be created. If\n * a settings object is passed instead, the settings will be used to create the jsPsych instance.\n *\n * @returns An object containing test helper functions, the jsPsych instance, and the jsPsych\n * display element\n */\nexport async function simulateTimeline(\n timeline: any[],\n simulation_mode?: \"data-only\" | \"visual\",\n simulation_options: any = {},\n jsPsych: JsPsych | any = {}\n) {\n const jsPsychInstance = jsPsych instanceof JsPsych ? jsPsych : new JsPsych(jsPsych);\n\n let hasFinished = false;\n const finished = jsPsychInstance\n .simulate(timeline, simulation_mode, simulation_options)\n .then(() => {\n hasFinished = true;\n });\n await flushPromises();\n\n const displayElement = jsPsychInstance.getDisplayElement();\n\n return {\n jsPsych: jsPsychInstance,\n displayElement,\n /** Shorthand for `jsPsych.getDisplayElement().innerHTML` */\n getHTML: () => displayElement.innerHTML,\n /** Shorthand for `jsPsych.data.get()` */\n getData: () => jsPsychInstance.data.get(),\n expectFinished: async () => {\n await flushPromises();\n expect(hasFinished).toBe(true);\n },\n expectRunning: async () => {\n await flushPromises();\n expect(hasFinished).toBe(false);\n },\n /** A promise that is resolved when `jsPsych.simulate()` is done. */\n finished,\n };\n}\n"],"names":["flushMicroTasks","JsPsych"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,9 +6,10 @@ import { JsPsych } from 'jspsych';
|
|
|
6
6
|
*/
|
|
7
7
|
declare function flushPromises(): Promise<unknown>;
|
|
8
8
|
declare function dispatchEvent(event: Event, target?: Element): Promise<unknown>;
|
|
9
|
-
declare function keyDown(key: string): Promise<void>;
|
|
10
|
-
declare function keyUp(key: string): Promise<void>;
|
|
9
|
+
declare function keyDown(key: string, code?: string): Promise<void>;
|
|
10
|
+
declare function keyUp(key: string, code?: string): Promise<void>;
|
|
11
11
|
declare function pressKey(key: string): Promise<void>;
|
|
12
|
+
declare function windowBlur(): Promise<void>;
|
|
12
13
|
declare function mouseDownMouseUpTarget(target: Element): Promise<void>;
|
|
13
14
|
declare function clickTarget(target: Element): Promise<void>;
|
|
14
15
|
/**
|
|
@@ -79,4 +80,4 @@ declare function simulateTimeline(timeline: any[], simulation_mode?: "data-only"
|
|
|
79
80
|
finished: Promise<void>;
|
|
80
81
|
}>;
|
|
81
82
|
|
|
82
|
-
export { clickTarget, dispatchEvent, flushPromises, keyDown, keyUp, mouseDown, mouseDownMouseUpTarget, mouseMove, mouseUp, pressKey, simulateTimeline, startTimeline };
|
|
83
|
+
export { clickTarget, dispatchEvent, flushPromises, keyDown, keyUp, mouseDown, mouseDownMouseUpTarget, mouseMove, mouseUp, pressKey, simulateTimeline, startTimeline, windowBlur };
|
package/dist/index.js
CHANGED
|
@@ -8,16 +8,20 @@ function dispatchEvent(event, target = document.body) {
|
|
|
8
8
|
target.dispatchEvent(event);
|
|
9
9
|
return flushPromises();
|
|
10
10
|
}
|
|
11
|
-
async function keyDown(key) {
|
|
12
|
-
await dispatchEvent(new KeyboardEvent("keydown", { key }));
|
|
11
|
+
async function keyDown(key, code) {
|
|
12
|
+
await dispatchEvent(new KeyboardEvent("keydown", { key, code }));
|
|
13
13
|
}
|
|
14
|
-
async function keyUp(key) {
|
|
15
|
-
await dispatchEvent(new KeyboardEvent("keyup", { key }));
|
|
14
|
+
async function keyUp(key, code) {
|
|
15
|
+
await dispatchEvent(new KeyboardEvent("keyup", { key, code }));
|
|
16
16
|
}
|
|
17
17
|
async function pressKey(key) {
|
|
18
18
|
await keyDown(key);
|
|
19
19
|
await keyUp(key);
|
|
20
20
|
}
|
|
21
|
+
async function windowBlur() {
|
|
22
|
+
window.dispatchEvent(new Event("blur"));
|
|
23
|
+
await flushPromises();
|
|
24
|
+
}
|
|
21
25
|
async function mouseDownMouseUpTarget(target) {
|
|
22
26
|
await dispatchEvent(new MouseEvent("mousedown", { bubbles: true }), target);
|
|
23
27
|
await dispatchEvent(new MouseEvent("mouseup", { bubbles: true }), target);
|
|
@@ -62,7 +66,9 @@ async function startTimeline(timeline, jsPsych = {}) {
|
|
|
62
66
|
return {
|
|
63
67
|
jsPsych: jsPsychInstance,
|
|
64
68
|
displayElement,
|
|
69
|
+
/** Shorthand for `jsPsych.getDisplayElement().innerHTML` */
|
|
65
70
|
getHTML: () => displayElement.innerHTML,
|
|
71
|
+
/** Shorthand for `jsPsych.data.get()` */
|
|
66
72
|
getData: () => jsPsychInstance.data.get(),
|
|
67
73
|
expectFinished: async () => {
|
|
68
74
|
await flushPromises();
|
|
@@ -72,6 +78,7 @@ async function startTimeline(timeline, jsPsych = {}) {
|
|
|
72
78
|
await flushPromises();
|
|
73
79
|
expect(hasFinished).toBe(false);
|
|
74
80
|
},
|
|
81
|
+
/** A promise that is resolved when `jsPsych.run()` is done. */
|
|
75
82
|
finished
|
|
76
83
|
};
|
|
77
84
|
}
|
|
@@ -86,7 +93,9 @@ async function simulateTimeline(timeline, simulation_mode, simulation_options =
|
|
|
86
93
|
return {
|
|
87
94
|
jsPsych: jsPsychInstance,
|
|
88
95
|
displayElement,
|
|
96
|
+
/** Shorthand for `jsPsych.getDisplayElement().innerHTML` */
|
|
89
97
|
getHTML: () => displayElement.innerHTML,
|
|
98
|
+
/** Shorthand for `jsPsych.data.get()` */
|
|
90
99
|
getData: () => jsPsychInstance.data.get(),
|
|
91
100
|
expectFinished: async () => {
|
|
92
101
|
await flushPromises();
|
|
@@ -96,9 +105,10 @@ async function simulateTimeline(timeline, simulation_mode, simulation_options =
|
|
|
96
105
|
await flushPromises();
|
|
97
106
|
expect(hasFinished).toBe(false);
|
|
98
107
|
},
|
|
108
|
+
/** A promise that is resolved when `jsPsych.simulate()` is done. */
|
|
99
109
|
finished
|
|
100
110
|
};
|
|
101
111
|
}
|
|
102
112
|
|
|
103
|
-
export { clickTarget, dispatchEvent, flushPromises, keyDown, keyUp, mouseDown, mouseDownMouseUpTarget, mouseMove, mouseUp, pressKey, simulateTimeline, startTimeline };
|
|
113
|
+
export { clickTarget, dispatchEvent, flushPromises, keyDown, keyUp, mouseDown, mouseDownMouseUpTarget, mouseMove, mouseUp, pressKey, simulateTimeline, startTimeline, windowBlur };
|
|
104
114
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { setImmediate as flushMicroTasks } from \"timers\";\n\nimport { JsPsych } from \"jspsych\";\n\n/**\n * https://github.com/facebook/jest/issues/2157#issuecomment-279171856\n */\nexport function flushPromises() {\n return new Promise((resolve) => flushMicroTasks(resolve));\n}\n\nexport function dispatchEvent(event: Event, target: Element = document.body) {\n target.dispatchEvent(event);\n return flushPromises();\n}\n\nexport async function keyDown(key: string) {\n await dispatchEvent(new KeyboardEvent(\"keydown\", { key }));\n}\n\nexport async function keyUp(key: string) {\n await dispatchEvent(new KeyboardEvent(\"keyup\", { key }));\n}\n\nexport async function pressKey(key: string) {\n await keyDown(key);\n await keyUp(key);\n}\n\nexport async function mouseDownMouseUpTarget(target: Element) {\n await dispatchEvent(new MouseEvent(\"mousedown\", { bubbles: true }), target);\n await dispatchEvent(new MouseEvent(\"mouseup\", { bubbles: true }), target);\n}\n\nexport async function clickTarget(target: Element) {\n // Check if the target is a form element and if it's disabled\n if (target instanceof HTMLButtonElement || target instanceof HTMLInputElement) {\n if (target.disabled) {\n console.log(\"Target is disabled, not dispatching click event.\");\n return; // Exit the function if the target is disabled\n }\n }\n await dispatchEvent(new MouseEvent(\"click\", { bubbles: true }), target);\n}\n\n/**\n * Dispatch a `MouseEvent` of type `eventType`, with x and y defined relative to the container element.\n * @param x The x location of the event, relative to the x location of `container`.\n * @param y The y location of the event, relative to the y location of `container`.\n * @param container The DOM element for relative location of the event.\n */\nasync function dispatchMouseEvent(eventType: string, x: number, y: number, container: Element) {\n const containerRect = container.getBoundingClientRect();\n await dispatchEvent(\n new MouseEvent(eventType, {\n clientX: containerRect.x + x,\n clientY: containerRect.y + y,\n bubbles: true,\n }),\n container\n );\n}\n\n/**\n * Dispatch a `mousemove` event, with x and y defined relative to the container element.\n * @param x The x location of the event, relative to the x location of `container`.\n * @param y The y location of the event, relative to the y location of `container`.\n * @param container The DOM element for relative location of the event.\n */\nexport async function mouseMove(x: number, y: number, container: Element) {\n await dispatchMouseEvent(\"mousemove\", x, y, container);\n}\n\n/**\n * Dispatch a `mouseup` event, with x and y defined relative to the container element.\n * @param x The x location of the event, relative to the x location of `container`.\n * @param y The y location of the event, relative to the y location of `container`.\n * @param container The DOM element for relative location of the event.\n */\nexport async function mouseUp(x: number, y: number, container: Element) {\n await dispatchMouseEvent(\"mouseup\", x, y, container);\n}\n\n/**\n * Dispatch a `mousemove` event, with x and y defined relative to the container element.\n * @param x The x location of the event, relative to the x location of `container`.\n * @param y The y location of the event, relative to the y location of `container`.\n * @param container The DOM element for relative location of the event.\n */\nexport async function mouseDown(x: number, y: number, container: Element) {\n await dispatchMouseEvent(\"mousedown\", x, y, container);\n}\n\n/**\n * Runs the given timeline by calling `jsPsych.run()` on the provided JsPsych object.\n *\n * @param timeline The timeline that is passed to `jsPsych.run()`\n * @param jsPsych The jsPsych instance to be used. If left empty, a new instance will be created. If\n * a settings object is passed instead, the settings will be used to create the jsPsych instance.\n *\n * @returns An object containing test helper functions, the jsPsych instance, and the jsPsych\n * display element\n */\nexport async function startTimeline(timeline: any[], jsPsych: JsPsych | any = {}) {\n const jsPsychInstance = jsPsych instanceof JsPsych ? jsPsych : new JsPsych(jsPsych);\n\n let hasFinished = false;\n const finished = jsPsychInstance.run(timeline).then(() => {\n hasFinished = true;\n });\n await flushPromises();\n\n const displayElement = jsPsychInstance.getDisplayElement();\n\n return {\n jsPsych: jsPsychInstance,\n displayElement,\n /** Shorthand for `jsPsych.getDisplayElement().innerHTML` */\n getHTML: () => displayElement.innerHTML,\n /** Shorthand for `jsPsych.data.get()` */\n getData: () => jsPsychInstance.data.get(),\n expectFinished: async () => {\n await flushPromises();\n expect(hasFinished).toBe(true);\n },\n expectRunning: async () => {\n await flushPromises();\n expect(hasFinished).toBe(false);\n },\n /** A promise that is resolved when `jsPsych.run()` is done. */\n finished,\n };\n}\n\n/**\n * Runs the given timeline by calling `jsPsych.simulate()` on the provided JsPsych object.\n *\n * @param timeline The timeline that is passed to `jsPsych.run()`\n * @param simulation_mode Either 'data-only' mode or 'visual' mode.\n * @param simulation_options Options to pass to `jsPsych.simulate()`\n * @param jsPsych The jsPsych instance to be used. If left empty, a new instance will be created. If\n * a settings object is passed instead, the settings will be used to create the jsPsych instance.\n *\n * @returns An object containing test helper functions, the jsPsych instance, and the jsPsych\n * display element\n */\nexport async function simulateTimeline(\n timeline: any[],\n simulation_mode?: \"data-only\" | \"visual\",\n simulation_options: any = {},\n jsPsych: JsPsych | any = {}\n) {\n const jsPsychInstance = jsPsych instanceof JsPsych ? jsPsych : new JsPsych(jsPsych);\n\n let hasFinished = false;\n const finished = jsPsychInstance\n .simulate(timeline, simulation_mode, simulation_options)\n .then(() => {\n hasFinished = true;\n });\n await flushPromises();\n\n const displayElement = jsPsychInstance.getDisplayElement();\n\n return {\n jsPsych: jsPsychInstance,\n displayElement,\n /** Shorthand for `jsPsych.getDisplayElement().innerHTML` */\n getHTML: () => displayElement.innerHTML,\n /** Shorthand for `jsPsych.data.get()` */\n getData: () => jsPsychInstance.data.get(),\n expectFinished: async () => {\n await flushPromises();\n expect(hasFinished).toBe(true);\n },\n expectRunning: async () => {\n await flushPromises();\n expect(hasFinished).toBe(false);\n },\n /** A promise that is resolved when `jsPsych.simulate()` is done. */\n finished,\n };\n}\n"],"names":["flushMicroTasks"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { setImmediate as flushMicroTasks } from \"timers\";\n\nimport { JsPsych } from \"jspsych\";\n\n/**\n * https://github.com/facebook/jest/issues/2157#issuecomment-279171856\n */\nexport function flushPromises() {\n return new Promise((resolve) => flushMicroTasks(resolve));\n}\n\nexport function dispatchEvent(event: Event, target: Element = document.body) {\n target.dispatchEvent(event);\n return flushPromises();\n}\n\nexport async function keyDown(key: string, code?: string) {\n await dispatchEvent(new KeyboardEvent(\"keydown\", { key, code }));\n}\n\nexport async function keyUp(key: string, code?: string) {\n await dispatchEvent(new KeyboardEvent(\"keyup\", { key, code }));\n}\n\nexport async function pressKey(key: string) {\n await keyDown(key);\n await keyUp(key);\n}\n\nexport async function windowBlur() {\n window.dispatchEvent(new Event(\"blur\"));\n await flushPromises();\n}\n\nexport async function mouseDownMouseUpTarget(target: Element) {\n await dispatchEvent(new MouseEvent(\"mousedown\", { bubbles: true }), target);\n await dispatchEvent(new MouseEvent(\"mouseup\", { bubbles: true }), target);\n}\n\nexport async function clickTarget(target: Element) {\n // Check if the target is a form element and if it's disabled\n if (target instanceof HTMLButtonElement || target instanceof HTMLInputElement) {\n if (target.disabled) {\n console.log(\"Target is disabled, not dispatching click event.\");\n return; // Exit the function if the target is disabled\n }\n }\n await dispatchEvent(new MouseEvent(\"click\", { bubbles: true }), target);\n}\n\n/**\n * Dispatch a `MouseEvent` of type `eventType`, with x and y defined relative to the container element.\n * @param x The x location of the event, relative to the x location of `container`.\n * @param y The y location of the event, relative to the y location of `container`.\n * @param container The DOM element for relative location of the event.\n */\nasync function dispatchMouseEvent(eventType: string, x: number, y: number, container: Element) {\n const containerRect = container.getBoundingClientRect();\n await dispatchEvent(\n new MouseEvent(eventType, {\n clientX: containerRect.x + x,\n clientY: containerRect.y + y,\n bubbles: true,\n }),\n container\n );\n}\n\n/**\n * Dispatch a `mousemove` event, with x and y defined relative to the container element.\n * @param x The x location of the event, relative to the x location of `container`.\n * @param y The y location of the event, relative to the y location of `container`.\n * @param container The DOM element for relative location of the event.\n */\nexport async function mouseMove(x: number, y: number, container: Element) {\n await dispatchMouseEvent(\"mousemove\", x, y, container);\n}\n\n/**\n * Dispatch a `mouseup` event, with x and y defined relative to the container element.\n * @param x The x location of the event, relative to the x location of `container`.\n * @param y The y location of the event, relative to the y location of `container`.\n * @param container The DOM element for relative location of the event.\n */\nexport async function mouseUp(x: number, y: number, container: Element) {\n await dispatchMouseEvent(\"mouseup\", x, y, container);\n}\n\n/**\n * Dispatch a `mousemove` event, with x and y defined relative to the container element.\n * @param x The x location of the event, relative to the x location of `container`.\n * @param y The y location of the event, relative to the y location of `container`.\n * @param container The DOM element for relative location of the event.\n */\nexport async function mouseDown(x: number, y: number, container: Element) {\n await dispatchMouseEvent(\"mousedown\", x, y, container);\n}\n\n/**\n * Runs the given timeline by calling `jsPsych.run()` on the provided JsPsych object.\n *\n * @param timeline The timeline that is passed to `jsPsych.run()`\n * @param jsPsych The jsPsych instance to be used. If left empty, a new instance will be created. If\n * a settings object is passed instead, the settings will be used to create the jsPsych instance.\n *\n * @returns An object containing test helper functions, the jsPsych instance, and the jsPsych\n * display element\n */\nexport async function startTimeline(timeline: any[], jsPsych: JsPsych | any = {}) {\n const jsPsychInstance = jsPsych instanceof JsPsych ? jsPsych : new JsPsych(jsPsych);\n\n let hasFinished = false;\n const finished = jsPsychInstance.run(timeline).then(() => {\n hasFinished = true;\n });\n await flushPromises();\n\n const displayElement = jsPsychInstance.getDisplayElement();\n\n return {\n jsPsych: jsPsychInstance,\n displayElement,\n /** Shorthand for `jsPsych.getDisplayElement().innerHTML` */\n getHTML: () => displayElement.innerHTML,\n /** Shorthand for `jsPsych.data.get()` */\n getData: () => jsPsychInstance.data.get(),\n expectFinished: async () => {\n await flushPromises();\n expect(hasFinished).toBe(true);\n },\n expectRunning: async () => {\n await flushPromises();\n expect(hasFinished).toBe(false);\n },\n /** A promise that is resolved when `jsPsych.run()` is done. */\n finished,\n };\n}\n\n/**\n * Runs the given timeline by calling `jsPsych.simulate()` on the provided JsPsych object.\n *\n * @param timeline The timeline that is passed to `jsPsych.run()`\n * @param simulation_mode Either 'data-only' mode or 'visual' mode.\n * @param simulation_options Options to pass to `jsPsych.simulate()`\n * @param jsPsych The jsPsych instance to be used. If left empty, a new instance will be created. If\n * a settings object is passed instead, the settings will be used to create the jsPsych instance.\n *\n * @returns An object containing test helper functions, the jsPsych instance, and the jsPsych\n * display element\n */\nexport async function simulateTimeline(\n timeline: any[],\n simulation_mode?: \"data-only\" | \"visual\",\n simulation_options: any = {},\n jsPsych: JsPsych | any = {}\n) {\n const jsPsychInstance = jsPsych instanceof JsPsych ? jsPsych : new JsPsych(jsPsych);\n\n let hasFinished = false;\n const finished = jsPsychInstance\n .simulate(timeline, simulation_mode, simulation_options)\n .then(() => {\n hasFinished = true;\n });\n await flushPromises();\n\n const displayElement = jsPsychInstance.getDisplayElement();\n\n return {\n jsPsych: jsPsychInstance,\n displayElement,\n /** Shorthand for `jsPsych.getDisplayElement().innerHTML` */\n getHTML: () => displayElement.innerHTML,\n /** Shorthand for `jsPsych.data.get()` */\n getData: () => jsPsychInstance.data.get(),\n expectFinished: async () => {\n await flushPromises();\n expect(hasFinished).toBe(true);\n },\n expectRunning: async () => {\n await flushPromises();\n expect(hasFinished).toBe(false);\n },\n /** A promise that is resolved when `jsPsych.simulate()` is done. */\n finished,\n };\n}\n"],"names":["flushMicroTasks"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jspsych/test-utils",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Test utility functions for jsPsych-related test cases",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@types/jest": "*"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@jspsych/config": "^3.
|
|
38
|
-
"jspsych": "^8.
|
|
37
|
+
"@jspsych/config": "^3.3.4",
|
|
38
|
+
"jspsych": "^8.3.0"
|
|
39
39
|
}
|
|
40
40
|
}
|
package/src/index.ts
CHANGED
|
@@ -14,12 +14,12 @@ export function dispatchEvent(event: Event, target: Element = document.body) {
|
|
|
14
14
|
return flushPromises();
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
export async function keyDown(key: string) {
|
|
18
|
-
await dispatchEvent(new KeyboardEvent("keydown", { key }));
|
|
17
|
+
export async function keyDown(key: string, code?: string) {
|
|
18
|
+
await dispatchEvent(new KeyboardEvent("keydown", { key, code }));
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
export async function keyUp(key: string) {
|
|
22
|
-
await dispatchEvent(new KeyboardEvent("keyup", { key }));
|
|
21
|
+
export async function keyUp(key: string, code?: string) {
|
|
22
|
+
await dispatchEvent(new KeyboardEvent("keyup", { key, code }));
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
export async function pressKey(key: string) {
|
|
@@ -27,6 +27,11 @@ export async function pressKey(key: string) {
|
|
|
27
27
|
await keyUp(key);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
export async function windowBlur() {
|
|
31
|
+
window.dispatchEvent(new Event("blur"));
|
|
32
|
+
await flushPromises();
|
|
33
|
+
}
|
|
34
|
+
|
|
30
35
|
export async function mouseDownMouseUpTarget(target: Element) {
|
|
31
36
|
await dispatchEvent(new MouseEvent("mousedown", { bubbles: true }), target);
|
|
32
37
|
await dispatchEvent(new MouseEvent("mouseup", { bubbles: true }), target);
|