@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.
- package/Changelog.md +51 -1
- package/README.md +2 -0
- package/dist/main.d.ts +120 -0
- package/dist/methods/_normalizeWithPlugins.d.ts +2 -0
- package/dist/methods/_readShortcutWithPlugins.d.ts +2 -0
- package/dist/methods/_systemAction.d.ts +2 -0
- package/dist/methods/changeContext.d.ts +2 -0
- package/dist/methods/index.d.ts +17 -0
- package/dist/methods/listShortcuts.d.ts +17 -0
- package/dist/methods/load.d.ts +2 -0
- package/dist/methods/unload.d.ts +2 -0
- package/dist/plugins/click/_findTarget.d.ts +2 -0
- package/dist/plugins/click/_listenDOM.d.ts +5 -0
- package/dist/plugins/click/_normalizeShortcutName.d.ts +2 -0
- package/dist/plugins/click/_readClickEvent.d.ts +2 -0
- package/dist/plugins/click/_registerShortcutEvents.d.ts +2 -0
- package/dist/plugins/click/index.d.ts +15 -0
- package/dist/plugins/form/_defaults.d.ts +5 -0
- package/dist/plugins/form/_listenDOM.d.ts +5 -0
- package/dist/plugins/form/_normalizeShortcutName.d.ts +2 -0
- package/dist/plugins/form/_registerShortcutEvents.d.ts +2 -0
- package/dist/plugins/form/index.d.ts +10 -0
- package/dist/plugins/key/_listenDOM.d.ts +5 -0
- package/dist/plugins/key/_normalizeShortcutName.d.ts +2 -0
- package/dist/plugins/key/_readKeyEvent.d.ts +2 -0
- package/dist/plugins/key/_registerShortcutEvents.d.ts +2 -0
- package/dist/plugins/key/_specialChars.d.ts +32 -0
- package/dist/plugins/key/index.d.ts +15 -0
- package/dist/shortcuts.cjs +1 -1
- package/dist/shortcuts.esm.mjs +1 -1
- package/dist/shortcuts.umd.js +1 -1
- package/jsconfig.json +10 -0
- package/package.json +16 -7
- package/src/main.js +98 -28
- package/src/methods/_readShortcutWithPlugins.js +2 -1
- package/src/methods/changeContext.js +2 -1
- package/src/methods/listShortcuts.js +2 -1
- package/src/methods/load.js +10 -7
- package/src/methods/unload.js +3 -3
- package/src/plugins/click/_listenDOM.js +13 -3
- package/src/plugins/click/index.js +16 -6
- package/src/plugins/form/index.js +12 -17
- package/src/plugins/key/_listenDOM.js +13 -0
- package/src/plugins/key/index.js +11 -5
- package/test/01-general.test.js +158 -251
- package/test/02-key.test.js +272 -0
- package/test/03-click.test.js +352 -0
- package/test/04-form.test.js +90 -0
- package/test-helpers/setup.js +18 -0
- package/test-helpers/wait.js +8 -0
- package/tsconfig.json +23 -0
- package/vitest.config.js +21 -0
- package/vitest-example/HelloWorld.js +0 -9
- package/vitest-example/HelloWorld.test.js +0 -11
- package/vitest.workspace.js +0 -19
- /package/{test-components → test-helpers}/Block.jsx +0 -0
- /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
|