@jspsych/plugin-audio-button-response 1.1.3 → 2.0.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.browser.js +326 -300
- package/dist/index.browser.js.map +1 -1
- package/dist/index.browser.min.js +2 -2
- package/dist/index.browser.min.js.map +1 -1
- package/dist/index.cjs +258 -285
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +159 -65
- package/dist/index.js +258 -285
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/index.spec.ts +262 -7
- package/src/index.ts +227 -210
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jspsych/plugin-audio-button-response",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "jsPsych plugin for playing an audio file and getting a button response",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"jspsych": ">=7.1.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@jspsych/config": "^
|
|
41
|
-
"@jspsych/test-utils": "^1.
|
|
40
|
+
"@jspsych/config": "^3.0.0",
|
|
41
|
+
"@jspsych/test-utils": "^1.2.0"
|
|
42
42
|
}
|
|
43
43
|
}
|
package/src/index.spec.ts
CHANGED
|
@@ -1,13 +1,60 @@
|
|
|
1
|
-
|
|
1
|
+
jest.mock("../../jspsych/src/modules/plugin-api/AudioPlayer");
|
|
2
|
+
|
|
3
|
+
import { clickTarget, flushPromises, simulateTimeline, startTimeline } from "@jspsych/test-utils";
|
|
2
4
|
import { initJsPsych } from "jspsych";
|
|
3
5
|
|
|
6
|
+
//@ts-expect-error mock
|
|
7
|
+
import { mockStop } from "../../jspsych/src/modules/plugin-api/AudioPlayer";
|
|
4
8
|
import audioButtonResponse from ".";
|
|
5
9
|
|
|
6
10
|
jest.useFakeTimers();
|
|
7
11
|
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
jest.clearAllMocks();
|
|
14
|
+
});
|
|
15
|
+
|
|
8
16
|
// skip this until we figure out how to mock the audio loading
|
|
9
|
-
describe
|
|
17
|
+
describe("audio-button-response", () => {
|
|
18
|
+
it.skip("works with all defaults", async () => {
|
|
19
|
+
const { expectFinished, expectRunning, displayElement, getHTML } = await startTimeline([
|
|
20
|
+
{
|
|
21
|
+
type: audioButtonResponse,
|
|
22
|
+
choices: ["choice1"],
|
|
23
|
+
stimulus: "foo.mp3",
|
|
24
|
+
},
|
|
25
|
+
]);
|
|
26
|
+
|
|
27
|
+
expectRunning();
|
|
28
|
+
|
|
29
|
+
clickTarget(displayElement.querySelector("button"));
|
|
30
|
+
|
|
31
|
+
expectFinished();
|
|
32
|
+
|
|
33
|
+
await flushPromises();
|
|
34
|
+
});
|
|
35
|
+
it("works with use_webaudio:false", async () => {
|
|
36
|
+
const jsPsych = initJsPsych({ use_webaudio: false });
|
|
37
|
+
|
|
38
|
+
const { expectFinished, expectRunning, displayElement } = await startTimeline(
|
|
39
|
+
[
|
|
40
|
+
{
|
|
41
|
+
type: audioButtonResponse,
|
|
42
|
+
choices: ["choice1"],
|
|
43
|
+
stimulus: "foo.mp3",
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
jsPsych
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
await expectRunning();
|
|
50
|
+
|
|
51
|
+
clickTarget(displayElement.querySelector("button"));
|
|
52
|
+
|
|
53
|
+
await expectFinished();
|
|
54
|
+
});
|
|
10
55
|
test("on_load event triggered after page setup complete", async () => {
|
|
56
|
+
const onLoadCallback = jest.fn();
|
|
57
|
+
|
|
11
58
|
const timeline = [
|
|
12
59
|
{
|
|
13
60
|
type: audioButtonResponse,
|
|
@@ -15,10 +62,210 @@ describe.skip("audio-button-response", () => {
|
|
|
15
62
|
prompt: "foo",
|
|
16
63
|
choices: ["choice1"],
|
|
17
64
|
on_load: () => {
|
|
18
|
-
|
|
65
|
+
onLoadCallback();
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
];
|
|
69
|
+
|
|
70
|
+
const jsPsych = initJsPsych({
|
|
71
|
+
use_webaudio: false,
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
await startTimeline(timeline, jsPsych);
|
|
75
|
+
|
|
76
|
+
expect(onLoadCallback).toHaveBeenCalled();
|
|
77
|
+
});
|
|
78
|
+
it("trial ends when button is clicked", async () => {
|
|
79
|
+
const jsPsych = initJsPsych({ use_webaudio: false });
|
|
80
|
+
|
|
81
|
+
const { expectFinished, expectRunning, displayElement } = await startTimeline(
|
|
82
|
+
[
|
|
83
|
+
{
|
|
84
|
+
type: audioButtonResponse,
|
|
85
|
+
stimulus: "foo.mp3",
|
|
86
|
+
prompt: "foo",
|
|
87
|
+
choices: ["choice1"],
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
jsPsych
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
await expectRunning();
|
|
94
|
+
|
|
95
|
+
clickTarget(displayElement.querySelector("button"));
|
|
96
|
+
|
|
97
|
+
await expectFinished();
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it("ends when trial_ends_after_audio is true and audio finishes", async () => {
|
|
101
|
+
const jsPsych = initJsPsych({ use_webaudio: false });
|
|
102
|
+
|
|
103
|
+
const { expectFinished, expectRunning } = await startTimeline(
|
|
104
|
+
[
|
|
105
|
+
{
|
|
106
|
+
type: audioButtonResponse,
|
|
107
|
+
stimulus: "foo.mp3",
|
|
108
|
+
choices: ["choice1"],
|
|
109
|
+
trial_duration: 30000,
|
|
110
|
+
trial_ends_after_audio: true,
|
|
111
|
+
},
|
|
112
|
+
],
|
|
113
|
+
jsPsych
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
await expectRunning();
|
|
117
|
+
|
|
118
|
+
jest.runAllTimers();
|
|
119
|
+
|
|
120
|
+
await expectFinished();
|
|
121
|
+
});
|
|
122
|
+
it("ends when trial_duration is shorter than the audio duration, stopping the audio", async () => {
|
|
123
|
+
const jsPsych = initJsPsych({ use_webaudio: false });
|
|
124
|
+
|
|
125
|
+
const { expectFinished, expectRunning } = await startTimeline(
|
|
126
|
+
[
|
|
127
|
+
{
|
|
128
|
+
type: audioButtonResponse,
|
|
129
|
+
stimulus: "foo.mp3",
|
|
130
|
+
choices: ["choice1"],
|
|
131
|
+
trial_duration: 500,
|
|
132
|
+
},
|
|
133
|
+
],
|
|
134
|
+
jsPsych
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
await expectRunning();
|
|
138
|
+
|
|
139
|
+
expect(mockStop).not.toHaveBeenCalled();
|
|
140
|
+
|
|
141
|
+
jest.advanceTimersByTime(500);
|
|
142
|
+
|
|
143
|
+
expect(mockStop).toHaveBeenCalled();
|
|
144
|
+
|
|
145
|
+
await expectFinished();
|
|
146
|
+
});
|
|
147
|
+
it("prevents responses when response_allowed_while_playing is false", async () => {
|
|
148
|
+
const jsPsych = initJsPsych({ use_webaudio: false });
|
|
149
|
+
|
|
150
|
+
const { expectFinished, expectRunning, displayElement, getHTML } = await startTimeline(
|
|
151
|
+
[
|
|
152
|
+
{
|
|
153
|
+
type: audioButtonResponse,
|
|
154
|
+
stimulus: "foo.mp3",
|
|
155
|
+
choices: ["choice1"],
|
|
156
|
+
response_allowed_while_playing: false,
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
jsPsych
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
await expectRunning();
|
|
163
|
+
|
|
164
|
+
clickTarget(displayElement.querySelector("button"));
|
|
165
|
+
|
|
166
|
+
await expectRunning();
|
|
167
|
+
|
|
168
|
+
jest.runAllTimers();
|
|
169
|
+
|
|
170
|
+
await expectRunning();
|
|
171
|
+
|
|
172
|
+
clickTarget(displayElement.querySelector("button"));
|
|
173
|
+
|
|
174
|
+
await expectFinished();
|
|
175
|
+
});
|
|
176
|
+
it("works when response_allowed_while_playing is true", async () => {
|
|
177
|
+
const jsPsych = initJsPsych({ use_webaudio: false });
|
|
178
|
+
|
|
179
|
+
const { expectFinished, expectRunning, displayElement } = await startTimeline(
|
|
180
|
+
[
|
|
181
|
+
{
|
|
182
|
+
type: audioButtonResponse,
|
|
183
|
+
stimulus: "foo.mp3",
|
|
184
|
+
choices: ["choice1"],
|
|
185
|
+
response_allowed_while_playing: true,
|
|
186
|
+
},
|
|
187
|
+
],
|
|
188
|
+
jsPsych
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
await expectRunning();
|
|
192
|
+
|
|
193
|
+
clickTarget(displayElement.querySelector("button"));
|
|
19
194
|
|
|
20
|
-
|
|
195
|
+
await expectFinished();
|
|
196
|
+
});
|
|
197
|
+
it("does not allow reponses when response_allowed_while_playing is false and enable_button_after is set, until after set time", async () => {
|
|
198
|
+
const jsPsych = initJsPsych({ use_webaudio: false });
|
|
199
|
+
|
|
200
|
+
const { expectFinished, expectRunning, displayElement } = await startTimeline(
|
|
201
|
+
[
|
|
202
|
+
{
|
|
203
|
+
type: audioButtonResponse,
|
|
204
|
+
stimulus: "foo.mp3",
|
|
205
|
+
choices: ["choice1"],
|
|
206
|
+
response_allowed_while_playing: false,
|
|
207
|
+
enable_button_after: 1000,
|
|
21
208
|
},
|
|
209
|
+
],
|
|
210
|
+
jsPsych
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
await expectRunning();
|
|
214
|
+
|
|
215
|
+
clickTarget(displayElement.querySelector("button"));
|
|
216
|
+
|
|
217
|
+
await expectRunning();
|
|
218
|
+
|
|
219
|
+
jest.advanceTimersByTime(1000);
|
|
220
|
+
|
|
221
|
+
clickTarget(displayElement.querySelector("button"));
|
|
222
|
+
|
|
223
|
+
await expectRunning();
|
|
224
|
+
|
|
225
|
+
jest.advanceTimersByTime(1000);
|
|
226
|
+
|
|
227
|
+
clickTarget(displayElement.querySelector("button"));
|
|
228
|
+
|
|
229
|
+
await expectFinished();
|
|
230
|
+
});
|
|
231
|
+
it("does not allow reponses when response_allowed_while_playing is true and enable_button_after is set, until after set time", async () => {
|
|
232
|
+
const jsPsych = initJsPsych({ use_webaudio: false });
|
|
233
|
+
|
|
234
|
+
const { expectFinished, expectRunning, displayElement } = await startTimeline(
|
|
235
|
+
[
|
|
236
|
+
{
|
|
237
|
+
type: audioButtonResponse,
|
|
238
|
+
stimulus: "foo.mp3",
|
|
239
|
+
choices: ["choice1"],
|
|
240
|
+
response_allowed_while_playing: true,
|
|
241
|
+
enable_button_after: 500,
|
|
242
|
+
},
|
|
243
|
+
],
|
|
244
|
+
jsPsych
|
|
245
|
+
);
|
|
246
|
+
|
|
247
|
+
await expectRunning();
|
|
248
|
+
|
|
249
|
+
clickTarget(displayElement.querySelector("button"));
|
|
250
|
+
|
|
251
|
+
await expectRunning();
|
|
252
|
+
|
|
253
|
+
jest.advanceTimersByTime(500);
|
|
254
|
+
|
|
255
|
+
clickTarget(displayElement.querySelector("button"));
|
|
256
|
+
|
|
257
|
+
await expectFinished();
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
test("enable buttons during audio playback", async () => {
|
|
261
|
+
const timeline = [
|
|
262
|
+
{
|
|
263
|
+
type: audioButtonResponse,
|
|
264
|
+
stimulus: "mymp3.mp3",
|
|
265
|
+
prompt: "foo",
|
|
266
|
+
choices: ["choice1"],
|
|
267
|
+
response_allowed_while_playing: true,
|
|
268
|
+
enable_button_after: 500,
|
|
22
269
|
},
|
|
23
270
|
];
|
|
24
271
|
|
|
@@ -26,11 +273,19 @@ describe.skip("audio-button-response", () => {
|
|
|
26
273
|
use_webaudio: false,
|
|
27
274
|
});
|
|
28
275
|
|
|
29
|
-
|
|
276
|
+
await startTimeline(timeline, jsPsych);
|
|
277
|
+
|
|
278
|
+
const btns = document.querySelectorAll(".jspsych-html-button-response-button button");
|
|
279
|
+
|
|
280
|
+
for (let i = 0; i < btns.length; i++) {
|
|
281
|
+
expect(btns[i].getAttribute("disabled")).toBe(true);
|
|
282
|
+
}
|
|
30
283
|
|
|
31
|
-
|
|
284
|
+
jest.advanceTimersByTime(500);
|
|
32
285
|
|
|
33
|
-
|
|
286
|
+
for (let i = 0; i < btns.length; i++) {
|
|
287
|
+
expect(btns[i].hasAttribute("disabled")).toBe(false);
|
|
288
|
+
}
|
|
34
289
|
});
|
|
35
290
|
});
|
|
36
291
|
|