@peter.naydenov/shortcuts 3.3.1 → 3.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.
Files changed (57) hide show
  1. package/Changelog.md +51 -1
  2. package/README.md +2 -0
  3. package/dist/main.d.ts +120 -0
  4. package/dist/methods/_normalizeWithPlugins.d.ts +2 -0
  5. package/dist/methods/_readShortcutWithPlugins.d.ts +2 -0
  6. package/dist/methods/_systemAction.d.ts +2 -0
  7. package/dist/methods/changeContext.d.ts +2 -0
  8. package/dist/methods/index.d.ts +17 -0
  9. package/dist/methods/listShortcuts.d.ts +17 -0
  10. package/dist/methods/load.d.ts +2 -0
  11. package/dist/methods/unload.d.ts +2 -0
  12. package/dist/plugins/click/_findTarget.d.ts +2 -0
  13. package/dist/plugins/click/_listenDOM.d.ts +5 -0
  14. package/dist/plugins/click/_normalizeShortcutName.d.ts +2 -0
  15. package/dist/plugins/click/_readClickEvent.d.ts +2 -0
  16. package/dist/plugins/click/_registerShortcutEvents.d.ts +2 -0
  17. package/dist/plugins/click/index.d.ts +15 -0
  18. package/dist/plugins/form/_defaults.d.ts +5 -0
  19. package/dist/plugins/form/_listenDOM.d.ts +5 -0
  20. package/dist/plugins/form/_normalizeShortcutName.d.ts +2 -0
  21. package/dist/plugins/form/_registerShortcutEvents.d.ts +2 -0
  22. package/dist/plugins/form/index.d.ts +10 -0
  23. package/dist/plugins/key/_listenDOM.d.ts +5 -0
  24. package/dist/plugins/key/_normalizeShortcutName.d.ts +2 -0
  25. package/dist/plugins/key/_readKeyEvent.d.ts +2 -0
  26. package/dist/plugins/key/_registerShortcutEvents.d.ts +2 -0
  27. package/dist/plugins/key/_specialChars.d.ts +32 -0
  28. package/dist/plugins/key/index.d.ts +15 -0
  29. package/dist/shortcuts.cjs +1 -1
  30. package/dist/shortcuts.esm.mjs +1 -1
  31. package/dist/shortcuts.umd.js +1 -1
  32. package/jsconfig.json +10 -0
  33. package/package.json +16 -7
  34. package/src/main.js +98 -28
  35. package/src/methods/_readShortcutWithPlugins.js +2 -1
  36. package/src/methods/changeContext.js +2 -1
  37. package/src/methods/listShortcuts.js +2 -1
  38. package/src/methods/load.js +10 -7
  39. package/src/methods/unload.js +3 -3
  40. package/src/plugins/click/_listenDOM.js +13 -3
  41. package/src/plugins/click/index.js +16 -6
  42. package/src/plugins/form/index.js +12 -17
  43. package/src/plugins/key/_listenDOM.js +13 -0
  44. package/src/plugins/key/index.js +11 -5
  45. package/test/01-general.test.js +158 -251
  46. package/test/02-key.test.js +272 -0
  47. package/test/03-click.test.js +352 -0
  48. package/test/04-form.test.js +90 -0
  49. package/test-helpers/setup.js +18 -0
  50. package/test-helpers/wait.js +8 -0
  51. package/tsconfig.json +23 -0
  52. package/vitest.config.js +21 -0
  53. package/vitest-example/HelloWorld.js +0 -9
  54. package/vitest-example/HelloWorld.test.js +0 -11
  55. package/vitest.workspace.js +0 -19
  56. /package/{test-components → test-helpers}/Block.jsx +0 -0
  57. /package/{test-components → test-helpers}/style.css +0 -0
@@ -0,0 +1,272 @@
1
+ import { beforeEach, afterEach, describe, it, expect } from 'vitest'
2
+ import { userEvent } from '@vitest/browser/context'
3
+ import {
4
+ getByLabelText,
5
+ getByText,
6
+ getByTestId,
7
+ queryByTestId,
8
+ // Tip: all queries are also exposed on an object
9
+ // called "queries" which you could import here as well
10
+ waitFor
11
+ } from '@testing-library/dom'
12
+
13
+
14
+
15
+ import '../test-helpers/style.css'
16
+ import Block from '../test-helpers/Block.jsx'
17
+ import VisaulController from '@peter.naydenov/visual-controller-for-react'
18
+ import wait from '../test-helpers/wait.js'
19
+ import {
20
+ shortcuts
21
+ , pluginKey
22
+ , pluginClick
23
+ , pluginForm
24
+ } from '../src/main.js'
25
+
26
+
27
+
28
+ const html = new VisaulController ();
29
+ let
30
+ a = false
31
+ , b = false
32
+ , c = null
33
+ ;
34
+
35
+ const contextDefinition = {
36
+ general : {
37
+ ' key : shift+a': [
38
+ () => a = true,
39
+ () => c = 'triggered'
40
+ ]
41
+ }
42
+ , touch : {
43
+ // Single click with left button
44
+ 'click: left-1': () => b = true,
45
+ // Double click with left button
46
+ 'click: left-2': () => b = true,
47
+ // Single click with right button
48
+ 'click: right-1': () => b = true
49
+ }
50
+ , extra : {
51
+ 'key : p,r,o,b,a': () => b = true
52
+ }
53
+ , extend : {
54
+ 'form : watch' : () => 'input'
55
+ , 'form : define' : () => 'input'
56
+ , 'form : action' : () => [
57
+ {
58
+ fn : (e) => console.log ( e.target )
59
+ , type : 'input'
60
+ , mode : 'in'
61
+ }
62
+ ]
63
+ }
64
+ }
65
+
66
+ let short = shortcuts ();
67
+
68
+
69
+
70
+
71
+
72
+ describe ( 'Key plugin', () => {
73
+
74
+ beforeEach ( async () => {
75
+ short.load ( contextDefinition )
76
+ let container = document.createElement ( 'div' )
77
+ container.id = 'app'
78
+ document.body.appendChild ( container )
79
+ await html.publish ( Block, {}, 'app' )
80
+ a = false, b = false
81
+ }) // beforeEach
82
+
83
+
84
+
85
+ afterEach ( async () => {
86
+ short.reset ()
87
+ a = false, b = false, c = null;
88
+ }) // afterEach
89
+
90
+
91
+
92
+ it ( 'No "key" plugin installed', () => {
93
+ let r = short.listShortcuts ('general');
94
+ // Shortcut name is the same as it was set
95
+ expect ( r[0]).to.equal ( ' key : shift+a' )
96
+ }) // it no 'key' plugin installed
97
+
98
+
99
+
100
+ it ( 'Key plugin installed', () => {
101
+ short.enablePlugin ( pluginKey )
102
+ const r = short.listShortcuts ( 'general' )
103
+ // Shortcut name is recognized by plugin and is normalized
104
+ expect ( r[0] ).to.equal ( 'KEY:A+SHIFT' )
105
+ }) // it key plugin installed
106
+
107
+
108
+
109
+ it ( 'Execute a key shortcut: shift+a', async () => {
110
+ expect ( a ).to.equal ( false )
111
+ // Enable key plugin, normalize shortcuts related to the plugin
112
+ short.enablePlugin ( pluginKey )
113
+ short.changeContext ( 'general' )
114
+ await userEvent.keyboard ( '{Shift>}A{/Shift}' ) // Write 'a' with shift
115
+ await wait ( 12 )
116
+ await waitFor ( () => {
117
+ expect ( a ).to.equal ( true )
118
+ expect ( c ).to.equal ( 'triggered' )
119
+ }, { timeout: 1000, interval: 12 })
120
+ }) // it execute a key shortcut
121
+
122
+
123
+
124
+ it ( 'Key sequence', async () => {
125
+ // enable key plugin and normalize shortcuts related to the plugin 'key'
126
+ short.enablePlugin ( pluginKey )
127
+ short.changeContext ( 'extra' )
128
+ // Execute key sequence: 'p,r,o,b,a'
129
+ await userEvent.keyboard ( 'proba' )
130
+ await wait ( 480 )
131
+ await waitFor ( () => {
132
+ expect ( b ).to.equal ( true )
133
+ }, { timeout: 1000, interval: 12 })
134
+ }) // it key sequence
135
+
136
+
137
+
138
+
139
+ it ( 'Mute and unmute key plugin', async () => {
140
+ const result = [];
141
+ let i = 0;
142
+ result.push ( 'init' )
143
+
144
+ short.enablePlugin ( pluginKey )
145
+ short.setDependencies ({ result })
146
+ short.load ({
147
+ 'local': {
148
+ 'key: x,y,z' : ({ dependencies }) => {
149
+ let { result } = dependencies;
150
+ result.push ( i++ )
151
+ }
152
+ }
153
+ })
154
+
155
+ short.changeContext ( 'local' )
156
+
157
+ // Test 1: Plugin should work normally
158
+ await userEvent.keyboard ( 'xyz' )
159
+ await waitFor ( () => {
160
+ // We checking if the shortcut works
161
+ expect ( result ).to.have.lengthOf ( 2 )
162
+ expect ( i ).to.equal ( 1 )
163
+ }, { timeout: 1000, interval: 12 })
164
+
165
+ // Test 2: Mute plugin - should not trigger
166
+ short.mutePlugin ( 'key' )
167
+ await userEvent.keyboard ( 'xyz' )
168
+ await waitFor ( () => {
169
+ // Plugin is muted, so we don't expect any changes
170
+ expect ( result ).to.have.lengthOf ( 2 )
171
+ expect ( i ).to.equal ( 1 )
172
+ }, { timeout: 1000, interval: 12 })
173
+
174
+ // Test 3: Unmute plugin - should work again
175
+ short.unmutePlugin ( 'key' )
176
+ await userEvent.keyboard ( 'xyz' )
177
+ await waitFor ( () => {
178
+ // Plugin is unmuted, should work again
179
+ expect ( result ).to.have.lengthOf ( 3 )
180
+ expect ( i ).to.equal ( 2 )
181
+ }, { timeout: 1000, interval: 12 })
182
+ }) // it mute and unmute key plugin
183
+
184
+
185
+
186
+ it ( 'Arguments of key handler', async () => {
187
+ /**
188
+ * Need to know arguments for 'key' handler
189
+ * function myKeyHandler ({
190
+ * wait // (function). Function to pause key sequence processing
191
+ * , end // (function). Function to end key sequence processing
192
+ * , ignore // (function). Function to ignore current key in sequence
193
+ * , isWaiting // (function). Check if sequence is waiting
194
+ * , note // (string). Current context note or null
195
+ * , context // (string). Current context name
196
+ * , dependencies // (object). External dependencies object
197
+ * , type // (string). Event type ('key')
198
+ * }) {
199
+ * // Body of the handler. Do something...
200
+ * }
201
+ */
202
+ let test = [];
203
+ let i = 0;
204
+ short.enablePlugin ( pluginKey )
205
+ short.setDependencies ({ test })
206
+ short.load ({
207
+ 'local' : {
208
+ 'key: a' : ({
209
+ wait
210
+ , end
211
+ , ignore
212
+ , isWaiting
213
+ , note
214
+ , context
215
+ , dependencies
216
+ , type
217
+ }) => {
218
+ const
219
+ { test } = dependencies
220
+ , result = {
221
+ wait: typeof wait
222
+ , end: typeof end
223
+ , ignore: typeof ignore
224
+ , isWaiting: typeof isWaiting
225
+ , note
226
+ , context
227
+ , type
228
+ }
229
+ ;
230
+ test.push ( result )
231
+ i++
232
+ }
233
+ } // local
234
+ })
235
+ short.changeContext ( 'local' )
236
+ await userEvent.keyboard ( 'a' )
237
+ await wait ( 50 ) // Wait for key processing
238
+ await waitFor ( () => {
239
+ expect ( i ).to.be.equal ( 1 )
240
+ let result = test[0];
241
+ expect ( result.wait ).to.be.equal ( 'function' )
242
+ expect ( result.end ).to.be.equal ( 'function' )
243
+ expect ( result.ignore ).to.be.equal ( 'function' )
244
+ expect ( result.isWaiting ).to.be.equal ( 'function' )
245
+ expect ( result.context ).to.be.equal ( 'local' )
246
+ expect ( result.type ).to.be.equal ( 'key' )
247
+ }, { timeout: 1000, interval: 12 })
248
+ }) // it arguments of key handler
249
+
250
+
251
+ it ( 'Pause and resume', async () => {
252
+ short.enablePlugin ( pluginKey )
253
+ expect ( b ).to.be.equal ( false )
254
+ short.changeContext ( 'extra' )
255
+ // Shortcut name will be normalized by the plugin
256
+ short.pause ( 'key : p,r,o,b,a' )
257
+ // Execute key sequence: 'p,r,o,b,a'
258
+ await userEvent.keyboard ( 'proba' )
259
+ await wait ( 500 )
260
+ await waitFor ( () => {
261
+ expect ( b ).to.be.equal ( false )
262
+ }, { timeout: 1000, interval: 30 })
263
+
264
+ short.resume ( 'key : p,r,o,b,a' )
265
+ await userEvent.keyboard ( 'proba' )
266
+ await wait ( 500 )
267
+ await waitFor ( () => {
268
+ expect ( b ).to.be.equal ( true )
269
+ }, { timeout: 1000, interval: 30 })
270
+ }) // it pause and resume
271
+
272
+ })
@@ -0,0 +1,352 @@
1
+ import { beforeEach, afterEach, describe, it, expect } from 'vitest'
2
+ import { userEvent } from '@vitest/browser/context'
3
+ import {
4
+ getByLabelText,
5
+ getByText,
6
+ getByTestId,
7
+ queryByTestId,
8
+ // Tip: all queries are also exposed on an object
9
+ // called "queries" which you could import here as well
10
+ waitFor
11
+ } from '@testing-library/dom'
12
+
13
+
14
+
15
+ import '../test-helpers/style.css'
16
+ import Block from '../test-helpers/Block.jsx'
17
+ import VisaulController from '@peter.naydenov/visual-controller-for-react'
18
+ import wait from '../test-helpers/wait.js'
19
+ import {
20
+ shortcuts
21
+ , pluginKey
22
+ , pluginClick
23
+ , pluginForm
24
+ } from '../src/main.js'
25
+
26
+
27
+
28
+ const html = new VisaulController ();
29
+ let
30
+ a = false
31
+ , b = false
32
+ , c = null
33
+ ;
34
+
35
+ const contextDefinition = {
36
+ general : {
37
+ ' key : shift+a': [
38
+ () => a = true,
39
+ () => c = 'triggered'
40
+ ]
41
+ }
42
+ , touch : {
43
+ // Single click with left button
44
+ ' click: left-1': ({ target }) => {
45
+ b = true
46
+ // Named argument 'target' should be available
47
+ c = target.dataset.click
48
+ },
49
+ // Double click with left button
50
+ 'click: left-2': ({ target }) => {
51
+ b = true
52
+ c = target.dataset.click
53
+ },
54
+ // Single click with right button
55
+ 'click: right-1': () => c = 'right'
56
+ }
57
+ , extra : {
58
+ 'key : p,r,o,b,a': () => b = true
59
+ }
60
+ , extend : {
61
+ 'form : watch' : () => 'input'
62
+ , 'form : define' : () => 'input'
63
+ , 'form : action' : () => [
64
+ {
65
+ fn : (e) => console.log ( e.target )
66
+ , type : 'input'
67
+ , mode : 'in'
68
+ }
69
+ ]
70
+ }
71
+ }
72
+
73
+
74
+ let short = shortcuts ();
75
+
76
+
77
+
78
+ describe ( 'Click plugin', () => {
79
+
80
+
81
+
82
+ beforeEach ( async () => {
83
+ short.load ( contextDefinition )
84
+ let container = document.createElement ( 'div' );
85
+ container.id = 'app'
86
+ document.body.appendChild ( container )
87
+ await html.publish ( Block, {}, 'app' )
88
+ a = false, b = false
89
+ }) // beforeEach
90
+
91
+
92
+
93
+ afterEach ( async () => {
94
+ short.reset ();
95
+ a = false, b = false, c = null;
96
+ }) // afterEach
97
+
98
+
99
+
100
+ it ( 'No "click" plugin installed', async () => {
101
+ let r = short.listShortcuts ('touch');
102
+ // Shortcuts are untouched if plugin is not installed
103
+ expect ( r[0]).to.equal ( ' click: left-1' )
104
+ }) // it no 'click' plugin installed
105
+
106
+
107
+
108
+ it ( 'Click plugin installed', async () => {
109
+ short.enablePlugin ( pluginClick )
110
+ let r = short.listShortcuts ( 'touch' );
111
+ // Shortcuts are normalized
112
+ expect ( r[0]).to.equal ( 'CLICK:LEFT-1' )
113
+ }) // it click plugin installed
114
+
115
+
116
+
117
+ it ( 'Single left click', async () => {
118
+ expect ( b ).to.equal ( false )
119
+ short.enablePlugin ( pluginClick )
120
+ short.changeContext ( 'touch' )
121
+ await userEvent.click ( document.querySelector ( '#rspan' ) )
122
+ await wait ( 330 )
123
+ await waitFor ( () => {
124
+ expect ( b ).to.equal ( true )
125
+ // Target is a element that contains data-click property!
126
+ expect ( c ).to.equal ( 'red' )
127
+ // We clicked on span, but target is the parent element
128
+ // that contains data-click property
129
+ }, { timeout: 1000, interval: 12 })
130
+ }) // it single left click
131
+
132
+
133
+
134
+ it ( 'Double left click', async () => {
135
+ expect ( b ).to.equal ( false )
136
+ short.enablePlugin ( pluginClick )
137
+ short.changeContext ( 'touch' )
138
+ await userEvent.dblClick ( document.querySelector ( '#rspan' ) )
139
+ await wait ( 20 )
140
+ // Default wait mouse timeout is 320 ms, but maxClicks is set to 2,
141
+ // so we don't need to wait for timeout
142
+ await waitFor ( () => {
143
+ expect ( b ).to.equal ( true )
144
+ // Target is a element that contains data-click property!
145
+ expect ( c ).to.equal ( 'red' )
146
+ // We clicked on span, but target is the parent element
147
+ // that contains data-click property
148
+ }, { timeout: 1000, interval: 12 })
149
+ }) // it double left click
150
+
151
+
152
+
153
+ it ( 'Triple left click', async () => {
154
+ short.enablePlugin ( pluginClick )
155
+ const hitItem = document.querySelector ( '#rspan' );
156
+ expect ( a ).to.equal ( false )
157
+ short.changeContext ( 'touch' )
158
+ // Load will restart the selected context
159
+ short.load ({
160
+ // load will overwrite existing 'touch' context definition
161
+ 'touch' : {
162
+ 'click: left-3' : () => a = true
163
+ }
164
+ })
165
+ await wait ( 12 )
166
+ await userEvent.tripleClick ( hitItem )
167
+ // Default wait mouse timeout is 320 ms, but maxClicks is set to 3,
168
+ // so we don't need to wait for timeout
169
+ await waitFor ( () => {
170
+ expect ( a ).to.equal ( true )
171
+ expect ( b ).to.equal ( false )
172
+ }, { timeout: 1000, interval: 12 })
173
+ }) // it triple left click
174
+
175
+
176
+
177
+ it ( 'Single right click', async () => {
178
+ short.enablePlugin ( pluginClick )
179
+ // Context 'touch' was changed during previous test
180
+ // Return to original context.
181
+ short.load ( contextDefinition )
182
+ short.changeContext ( 'touch' )
183
+ let find = null
184
+ await waitFor ( () => {
185
+ find = document.querySelector ( '#rspan' )
186
+ },{ timeout: 1000, interval: 12 })
187
+ if ( find ) await userEvent.click ( find , { button:'right' })
188
+ // Default wait mouse timeout is 320 ms
189
+ await wait ( 320 )
190
+ await waitFor ( () => {
191
+ expect ( c ).to.equal ( 'right' )
192
+ }, { timeout: 1000, interval: 12 })
193
+ }) // it single right click
194
+
195
+
196
+
197
+ it ( 'Arguments of click handler', async () => {
198
+ /**
199
+ * Need to know arguments for 'click' handler
200
+ * function myMouseHandler ({
201
+ * context // (string) Name of the current context;
202
+ * , note // (string) Name of the note or null if note isn't set;
203
+ * , dependencies // (object) Object with dependencies that you have set by calling `setDependencies` method;
204
+ * , target // (DOM element). Target element of the mouse event;
205
+ * , targetProps // (object). Coordinates of the target element (top, left, right, bottom, width, height) or null if target element is not available;
206
+ * , x // (number). X coordinate of the target element;
207
+ * , y // (number). Y coordinate of the target element;
208
+ * , event // (object). Original mouse event object;
209
+ * }) {
210
+ * // Body of the handler. Do something...
211
+ * }
212
+ */
213
+ // Ensure clean state for this test
214
+ let megaBtn = document.querySelector ( '[data-click="mega"]' )
215
+ let test = [];
216
+ let i = 0;
217
+ short.enablePlugin ( pluginClick )
218
+ short.setDependencies ({ test })
219
+ short.load ({
220
+ 'local' : {
221
+ 'click: left-1' : ({
222
+ dependencies
223
+ , target
224
+ , x
225
+ , y
226
+ , targetProps
227
+ , context
228
+ }) => {
229
+ const
230
+ { test } = dependencies
231
+ , result = {
232
+ x
233
+ , y
234
+ , targetProps
235
+ , context
236
+ }
237
+ ;
238
+ result.target = target.dataset.click
239
+ test.push ( result )
240
+ i++
241
+ }
242
+ } // local
243
+ })
244
+ short.changeContext ( 'local' )
245
+ expect ( megaBtn ).to.not.be.null
246
+ await userEvent.click ( megaBtn )
247
+ await wait ( 50 ) // Wait for click processing
248
+ await waitFor ( () => {
249
+ expect ( i ).to.be.equal ( 1 )
250
+ let result = test[0];
251
+ expect ( result.target ).to.be.equal ( 'mega' )
252
+ expect ( result.context ).to.be.equal ( 'local' )
253
+ }, { timeout: 1000, interval: 12 })
254
+ }) // it arguments of click handler
255
+
256
+
257
+
258
+ it ( 'Click on anchor', async () => {
259
+ // Click on anchor that don't have click-data attribute.
260
+ let result = 'none';
261
+ short.enablePlugin ( pluginClick )
262
+ short.load ({ 'extra' : {
263
+ 'click: 1 - left' : ({target, context, event }) => { // Order of button name and number of click is not important
264
+ event.preventDefault ()
265
+ expect ( context ).to.be.equal ( 'extra' )
266
+ expect ( target.nodeName ).to.be.equal ( 'A' )
267
+ result = target.nodeName
268
+ }
269
+ }
270
+ })
271
+ short.changeContext ( 'extra' )
272
+ let loc = document.querySelector ( '#anchor' ) || false;
273
+ if ( loc ) await userEvent.click ( loc )
274
+ expect ( result ).to.be.equal ( 'A' )
275
+ }) // it click on anchor
276
+
277
+
278
+
279
+ it ( 'Mute and unmute click plugin', async () => {
280
+ const
281
+ result = []
282
+ , trg = document.querySelector ( '#rspan' )
283
+ ;
284
+
285
+ let i = 0;
286
+ result.push ( 'init' )
287
+
288
+
289
+ short.load ({
290
+ 'local' : {
291
+ 'click: left-1 ' : ({dependencies}) => {
292
+ let { result } = dependencies;
293
+ result.push ( i++ )
294
+ }
295
+ }
296
+ })
297
+ short.setDependencies ({ result })
298
+ short.enablePlugin ( pluginClick )
299
+ short.changeContext ( 'local' )
300
+
301
+
302
+ await userEvent.click ( trg )
303
+ await wait( 330 )
304
+ await waitFor ( () => {
305
+ // We checking if the shortcut works
306
+ expect ( result ).to.have.lengthOf ( 2 )
307
+ expect ( i ).to.equal ( 1 )
308
+ }, { timeout: 1000, interval: 12 })
309
+
310
+ short.mutePlugin ( 'click' )
311
+
312
+ await userEvent.click ( trg )
313
+ await waitFor ( () => {
314
+ // Plugin is muted, so we don't expect any changes
315
+ expect ( result ).to.have.lengthOf ( 2 )
316
+ expect ( i ).to.equal ( 1 )
317
+ }, { timeout: 1000, interval: 12 })
318
+
319
+ short.unmutePlugin ( 'click' )
320
+
321
+ await userEvent.click ( trg )
322
+ await wait ( 330 )
323
+ await waitFor ( () => {
324
+ // Plugin is unmuted, should work again
325
+ expect ( result ).to.have.lengthOf ( 3 )
326
+ expect ( i ).to.equal ( 2 )
327
+ }, { timeout: 1000, interval: 12 })
328
+ }) // it mute and unmute click plugin
329
+
330
+
331
+
332
+ it ( 'Pause and resume', async () => {
333
+ let target = document.querySelector ( '#rspan' )
334
+ short.enablePlugin ( pluginClick )
335
+ expect ( b ).to.be.equal ( false )
336
+ short.changeContext ( 'touch' )
337
+ short.pause ( 'click: left-1' )
338
+ await userEvent.click ( target )
339
+ await wait ( 400 )
340
+ await waitFor ( () => {
341
+ expect ( b ).to.be.equal ( false )
342
+ }, { timeout: 1000, interval: 30 })
343
+ short.resume ( 'click: left-1' )
344
+ await userEvent.click ( target )
345
+ await wait ( 400 )
346
+ await waitFor ( () => {
347
+ expect ( b ).to.be.equal ( true )
348
+ expect ( c ).to.be.equal ( 'red' )
349
+ }, { timeout: 1000, interval: 30 })
350
+ }) // it pause and resume
351
+
352
+ }) // describe