@testim/testim-cli 3.273.0 → 3.275.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/npm-shrinkwrap.json +80 -37
- package/package.json +1 -1
- package/player/stepActions/dropFileStepAction.js +1 -2
- package/player/stepActions/scripts/dispatchEvents.js +100 -89
- package/player/stepActions/scripts/doClick.js +82 -84
- package/player/stepActions/scripts/doDragPath.js +84 -85
- package/player/stepActions/scripts/doubleClick.js +38 -36
- package/player/stepActions/scripts/dropEvent.js +27 -24
- package/player/stepActions/scripts/focusElement.js +9 -13
- package/player/stepActions/scripts/html5dragAction.js +15 -15
- package/player/stepActions/scripts/html5dragActionV2.js +44 -45
- package/player/stepActions/scripts/runCode.js +24 -33
- package/player/stepActions/scripts/scroll.js +27 -27
- package/player/stepActions/scripts/selectOption.js +6 -6
- package/player/stepActions/scripts/setText.js +111 -116
- package/player/stepActions/scripts/wheel.js +18 -16
- package/polyfills/index.js +4 -0
- package/testRunStatus.js +1 -25
- package/testimNpmDriver.js +1 -1
- package/player/stepActions/scripts/createDropEventLegacy.js +0 -61
|
@@ -2,19 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
'use strict';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
var context = {
|
|
5
|
+
const setText = function (eventData, done) {
|
|
6
|
+
const eventConstructorSupported = typeof Event === 'function';
|
|
7
|
+
const element = eventData.isRoot ? document.documentElement : getLocatedElement(eventData.locatedElement);
|
|
8
|
+
const context = {
|
|
10
9
|
eventIndex: 0,
|
|
11
|
-
element
|
|
10
|
+
element,
|
|
12
11
|
events: eventData.events,
|
|
13
12
|
eventType: eventData.eventType,
|
|
14
|
-
quirks: eventData.quirks
|
|
13
|
+
quirks: eventData.quirks,
|
|
15
14
|
};
|
|
16
15
|
|
|
17
|
-
if(!element) {
|
|
16
|
+
if (!element) {
|
|
18
17
|
throw new Error('element not found');
|
|
19
18
|
}
|
|
20
19
|
|
|
@@ -22,10 +21,10 @@ var setText = function (eventData, done) {
|
|
|
22
21
|
resolve();
|
|
23
22
|
};
|
|
24
23
|
|
|
25
|
-
window.addEventListener(
|
|
24
|
+
window.addEventListener('unload', window.__unloadNavigator);
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
const keyboardEventNames = ['keydown', 'keyup', 'keypress'];
|
|
27
|
+
const MAX_KEYBOARD_EVENT_TIMEOUT = 15; //max msec between keyboard events
|
|
29
28
|
|
|
30
29
|
function getTextInputEventObject(userEvent) {
|
|
31
30
|
try {
|
|
@@ -33,28 +32,28 @@ var setText = function (eventData, done) {
|
|
|
33
32
|
return undefined;
|
|
34
33
|
}
|
|
35
34
|
|
|
36
|
-
|
|
35
|
+
const event = new CustomEvent('textInput', {
|
|
37
36
|
bubbles: true,
|
|
38
|
-
cancelable: true
|
|
37
|
+
cancelable: true,
|
|
39
38
|
});
|
|
40
39
|
if (userEvent.eventData) {
|
|
41
40
|
event.data = userEvent.eventData.data;
|
|
42
41
|
}
|
|
43
42
|
return event;
|
|
44
|
-
} catch (err) {
|
|
45
|
-
|
|
43
|
+
} catch (err) { /* ignored */ }
|
|
44
|
+
return undefined;
|
|
46
45
|
}
|
|
47
46
|
|
|
48
47
|
function initTextInputEvent(userEvent) {
|
|
49
48
|
try {
|
|
50
|
-
|
|
49
|
+
const event = document.createEvent('TextEvent');
|
|
51
50
|
event.data = userEvent.eventData.data;
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
const method = 1; // keyboard
|
|
52
|
+
const locale = userEvent.eventData.locale || 'en-US';
|
|
54
53
|
event.initTextEvent('textInput', true, true, window, userEvent.eventData.data, method, locale);
|
|
55
54
|
return event;
|
|
56
|
-
} catch (err) {
|
|
57
|
-
|
|
55
|
+
} catch (err) { /* ignored */ }
|
|
56
|
+
return undefined;
|
|
58
57
|
}
|
|
59
58
|
|
|
60
59
|
function getTextInputEvent(userEvent) {
|
|
@@ -67,48 +66,50 @@ var setText = function (eventData, done) {
|
|
|
67
66
|
bubbles: true,
|
|
68
67
|
cancelable: true,
|
|
69
68
|
location: eventData.location || 0,
|
|
70
|
-
key: eventData.key ||
|
|
69
|
+
key: eventData.key || '',
|
|
71
70
|
ctrlKey: Boolean(modifiers.ctrl),
|
|
72
71
|
shiftKey: Boolean(modifiers.shift),
|
|
73
72
|
altKey: Boolean(modifiers.alt),
|
|
74
|
-
metaKey: Boolean(modifiers.meta)
|
|
73
|
+
metaKey: Boolean(modifiers.meta),
|
|
75
74
|
});
|
|
76
|
-
} catch (err) {
|
|
77
|
-
|
|
75
|
+
} catch (err) { /* ignored */ }
|
|
76
|
+
return undefined;
|
|
78
77
|
}
|
|
79
78
|
|
|
80
79
|
function initKeyboardEvent(eventType, eventData, modifiers) {
|
|
81
80
|
try {
|
|
82
|
-
|
|
81
|
+
const event = document.createEvent('KeyboardEvent');
|
|
83
82
|
|
|
84
|
-
event.initKeyEvent(
|
|
85
|
-
|
|
86
|
-
true
|
|
87
|
-
|
|
83
|
+
event.initKeyEvent(
|
|
84
|
+
eventType, // typeArg,
|
|
85
|
+
true, // canBubbleArg,
|
|
86
|
+
true, // cancelableArg,
|
|
87
|
+
null, // viewArg, Specifies UIEvent.view. This value may be null.
|
|
88
88
|
Boolean(modifiers.ctrl),
|
|
89
89
|
Boolean(modifiers.alt),
|
|
90
90
|
Boolean(modifiers.shift),
|
|
91
91
|
Boolean(modifiers.meta),
|
|
92
|
-
eventData.key ||
|
|
93
|
-
0
|
|
92
|
+
eventData.key || '',
|
|
93
|
+
0, // charCodeArg
|
|
94
|
+
);
|
|
94
95
|
|
|
95
96
|
return event;
|
|
96
|
-
} catch (err) {
|
|
97
|
-
|
|
97
|
+
} catch (err) { /* ignored */ }
|
|
98
|
+
return undefined;
|
|
98
99
|
}
|
|
99
100
|
|
|
100
101
|
function createKeyboardEvents(eventType, eventData, modifiers) {
|
|
101
102
|
try {
|
|
102
|
-
|
|
103
|
+
const event = document.createEvent('Events');
|
|
103
104
|
event.initEvent(eventType, true, true);
|
|
104
105
|
event.altKey = Boolean(modifiers.alt);
|
|
105
106
|
event.ctrlKey = Boolean(modifiers.ctrl);
|
|
106
107
|
event.metaKey = Boolean(modifiers.meta);
|
|
107
108
|
event.shiftKey = Boolean(modifiers.shift);
|
|
108
|
-
event.keyCode = eventData.key ||
|
|
109
|
+
event.keyCode = eventData.key || '';
|
|
109
110
|
return event;
|
|
110
|
-
} catch (err) {
|
|
111
|
-
|
|
111
|
+
} catch (err) { /* ignored */ }
|
|
112
|
+
return undefined;
|
|
112
113
|
}
|
|
113
114
|
|
|
114
115
|
function createKeyboardEvent(eventType, eventData, modifiers) {
|
|
@@ -119,36 +120,36 @@ var setText = function (eventData, done) {
|
|
|
119
120
|
|
|
120
121
|
function getKeyboardEvent(userEvent) {
|
|
121
122
|
// some apps override Array.indexOf to return undefined if element not found (like Arkia)
|
|
122
|
-
|
|
123
|
-
if ((typeof index !==
|
|
123
|
+
const index = keyboardEventNames.indexOf(userEvent.event);
|
|
124
|
+
if ((typeof index !== 'number') || (index < 0)) {
|
|
124
125
|
return null;
|
|
125
126
|
}
|
|
126
127
|
|
|
127
|
-
|
|
128
|
-
|
|
128
|
+
const eventData = userEvent.eventData;
|
|
129
|
+
const modifiers = eventData.modifiers || {};
|
|
129
130
|
|
|
130
|
-
|
|
131
|
+
const event = createKeyboardEvent(userEvent.event, eventData, modifiers);
|
|
131
132
|
|
|
132
133
|
// workaround for chromium bugs which make keycode etc readonly
|
|
133
134
|
Object.defineProperties(event, {
|
|
134
135
|
keyCode: {
|
|
135
136
|
enumerable: true,
|
|
136
|
-
get
|
|
137
|
+
get() {
|
|
137
138
|
return this._keyCode_;
|
|
138
|
-
}
|
|
139
|
+
},
|
|
139
140
|
},
|
|
140
141
|
charCode: {
|
|
141
142
|
enumerable: true,
|
|
142
|
-
get
|
|
143
|
+
get() {
|
|
143
144
|
return this._charCode_;
|
|
144
|
-
}
|
|
145
|
+
},
|
|
145
146
|
},
|
|
146
147
|
which: {
|
|
147
148
|
enumerable: true,
|
|
148
|
-
get
|
|
149
|
+
get() {
|
|
149
150
|
return this._keyCode_;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
151
|
+
},
|
|
152
|
+
},
|
|
152
153
|
});
|
|
153
154
|
event._keyCode_ = eventData.keyCode;
|
|
154
155
|
event._charCode_ = eventData.charCode || 0;
|
|
@@ -156,42 +157,42 @@ var setText = function (eventData, done) {
|
|
|
156
157
|
}
|
|
157
158
|
|
|
158
159
|
function getEvent(userEvent) {
|
|
159
|
-
return userEvent.event ===
|
|
160
|
+
return userEvent.event === 'textInput' ?
|
|
160
161
|
getTextInputEvent(userEvent) :
|
|
161
162
|
getKeyboardEvent(userEvent);
|
|
162
163
|
}
|
|
163
164
|
|
|
164
165
|
function shouldSkipEvent(currentEvent, context) {
|
|
165
|
-
|
|
166
|
-
return currentEvent.event ===
|
|
166
|
+
const isTextInputAuth0Form = function () {
|
|
167
|
+
return currentEvent.event === 'textInput' && !context.quirks?.isAuth0Form;
|
|
167
168
|
};
|
|
168
169
|
return isTextInputAuth0Form();
|
|
169
170
|
}
|
|
170
171
|
|
|
171
172
|
function getTextEventTimeout(currentEvent, nextEvent) {
|
|
172
|
-
return ((currentEvent.event ===
|
|
173
|
+
return ((currentEvent.event === 'keyup') && (nextEvent.event === 'keydown')) ?
|
|
173
174
|
MAX_KEYBOARD_EVENT_TIMEOUT :
|
|
174
175
|
0;
|
|
175
176
|
}
|
|
176
177
|
|
|
177
178
|
function getTimeBetweenFiringEvents(context, currentEvent, nextEvent) {
|
|
178
|
-
|
|
179
|
+
const maxTimeout = getTextEventTimeout(currentEvent, nextEvent);
|
|
179
180
|
return Math.min(nextEvent.timeStamp - currentEvent.timeStamp, maxTimeout);
|
|
180
181
|
}
|
|
181
182
|
|
|
182
183
|
function handleReactFormFocus(element) {
|
|
183
184
|
// solution taken partially from https://github.com/vitalyq/react-trigger-change
|
|
184
|
-
|
|
185
|
+
const descriptor = Object.getOwnPropertyDescriptor(element, 'value');
|
|
185
186
|
if (!descriptor) {
|
|
186
187
|
return;
|
|
187
188
|
}
|
|
188
|
-
|
|
189
|
-
element.value = initialValue
|
|
189
|
+
const initialValue = element.value;
|
|
190
|
+
element.value = `${initialValue}#`;
|
|
190
191
|
if (descriptor.configurable) {
|
|
191
192
|
delete element.value;
|
|
192
193
|
}
|
|
193
194
|
element.value = initialValue;
|
|
194
|
-
|
|
195
|
+
const event = document.createEvent('HTMLEvents');
|
|
195
196
|
event.initEvent('input', true, false);
|
|
196
197
|
element.dispatchEvent(event);
|
|
197
198
|
Object.defineProperty(element, 'value', descriptor);
|
|
@@ -204,25 +205,23 @@ var setText = function (eventData, done) {
|
|
|
204
205
|
try {
|
|
205
206
|
handleReactFormFocus(context.element);
|
|
206
207
|
if (eventConstructorSupported) {
|
|
207
|
-
context.element.dispatchEvent(new Event(
|
|
208
|
+
context.element.dispatchEvent(new Event('change'));
|
|
208
209
|
} else {
|
|
209
|
-
|
|
210
|
-
event.initEvent(
|
|
210
|
+
const event = document.createEvent('HTMLEvents');
|
|
211
|
+
event.initEvent('change', false, true);
|
|
211
212
|
context.element.dispatchEvent(event);
|
|
212
213
|
}
|
|
213
|
-
} catch (e) {
|
|
214
|
-
}
|
|
215
|
-
|
|
214
|
+
} catch (e) { /* ignored */ }
|
|
216
215
|
}
|
|
217
216
|
|
|
218
217
|
function nextAsyncEvent(context, currentEvent, nextEvent) {
|
|
219
218
|
if (nextEvent) {
|
|
220
|
-
setTimeout(
|
|
219
|
+
setTimeout(() => {
|
|
221
220
|
executeAsyncNext(context);
|
|
222
221
|
}, getTimeBetweenFiringEvents(context, currentEvent, nextEvent));
|
|
223
222
|
} else {
|
|
224
223
|
if (window.__unloadNavigator) {
|
|
225
|
-
window.removeEventListener(
|
|
224
|
+
window.removeEventListener('unload', window.__unloadNavigator);
|
|
226
225
|
}
|
|
227
226
|
handleChangeEventIfNeeded(context);
|
|
228
227
|
resolve();
|
|
@@ -230,29 +229,27 @@ var setText = function (eventData, done) {
|
|
|
230
229
|
}
|
|
231
230
|
|
|
232
231
|
function shouldDispatchOnParentElement(eventType, context) {
|
|
233
|
-
return (eventType ===
|
|
232
|
+
return (eventType === 'change' || eventType === 'blur') && context.element.tagName === 'OPTION';
|
|
234
233
|
}
|
|
235
234
|
|
|
236
235
|
function getElement(event, context, currentEvent) {
|
|
237
236
|
if (shouldDispatchOnParentElement(event.type, context)) {
|
|
238
237
|
return context.element.parentElement;
|
|
239
|
-
}
|
|
238
|
+
} if (currentEvent.locatedElement) {
|
|
240
239
|
return getLocatedElement(currentEvent.locatedElement);
|
|
241
|
-
} else {
|
|
242
|
-
return context.element;
|
|
243
240
|
}
|
|
241
|
+
return context.element;
|
|
244
242
|
}
|
|
245
243
|
|
|
246
244
|
function findTextNode(element, offsetData) {
|
|
247
|
-
|
|
248
|
-
|
|
245
|
+
let child = element.firstChild;
|
|
246
|
+
let innerChild;
|
|
249
247
|
while (child) {
|
|
250
248
|
if (child.nodeType === 3) {
|
|
251
249
|
if (offsetData.offset-- <= 0) {
|
|
252
250
|
return child;
|
|
253
251
|
}
|
|
254
|
-
}
|
|
255
|
-
else if (child.nodeType === 1) {
|
|
252
|
+
} else if (child.nodeType === 1) {
|
|
256
253
|
innerChild = findTextNode(child, offsetData);
|
|
257
254
|
if (innerChild) {
|
|
258
255
|
return innerChild;
|
|
@@ -267,46 +264,43 @@ var setText = function (eventData, done) {
|
|
|
267
264
|
if (!element || !selection) {
|
|
268
265
|
return;
|
|
269
266
|
}
|
|
267
|
+
// eslint-disable-next-line no-restricted-globals
|
|
270
268
|
if (!isNaN(selection.start)) {
|
|
271
269
|
element.selectionStart = selection.start;
|
|
272
270
|
element.selectionEnd = selection.end;
|
|
273
|
-
|
|
274
|
-
else if (!isNaN(selection.nodeOffset)) {
|
|
275
|
-
|
|
271
|
+
// eslint-disable-next-line no-restricted-globals
|
|
272
|
+
} else if (!isNaN(selection.nodeOffset)) {
|
|
273
|
+
let startNode;
|
|
276
274
|
if (element.firstChild) {
|
|
277
275
|
startNode = findTextNode(element, { offset: selection.nodeOffset });
|
|
278
|
-
}
|
|
279
|
-
else {
|
|
276
|
+
} else {
|
|
280
277
|
startNode = element;
|
|
281
278
|
}
|
|
282
279
|
if (startNode) {
|
|
283
|
-
|
|
284
|
-
|
|
280
|
+
const sel = window.getSelection();
|
|
281
|
+
const range = document.createRange();
|
|
285
282
|
|
|
286
283
|
try { // until we get our act together regarding contenteditable, this may throw when the numbers in the recorded data don't match the current text
|
|
287
284
|
sel.removeAllRanges();
|
|
288
285
|
range.setStart(startNode, selection.textOffset);
|
|
289
286
|
range.setEnd(startNode, selection.textOffset);
|
|
290
287
|
sel.addRange(range);
|
|
291
|
-
}
|
|
292
|
-
catch (ignore) {
|
|
293
|
-
}
|
|
288
|
+
} catch (ignore) { /* ignored */ }
|
|
294
289
|
}
|
|
295
290
|
}
|
|
296
291
|
}
|
|
297
292
|
|
|
298
293
|
function executeAsyncEvent(event, context, currentEvent) {
|
|
299
|
-
if (context.isFocusable && context.isSelectable(event) && event.type !==
|
|
294
|
+
if (context.isFocusable && context.isSelectable(event) && event.type !== 'submit') {
|
|
300
295
|
try {
|
|
301
296
|
setSelection(context.element, currentEvent.eventData.selection);
|
|
302
|
-
} catch (ignore) {
|
|
303
|
-
}
|
|
297
|
+
} catch (ignore) { /* ignored */ }
|
|
304
298
|
}
|
|
305
|
-
|
|
299
|
+
const element = getElement(event, context, currentEvent);
|
|
306
300
|
if (!element) {
|
|
307
301
|
throw new Error('could not find element');
|
|
308
302
|
}
|
|
309
|
-
if (event.type ===
|
|
303
|
+
if (event.type === 'submit' && element.action) {
|
|
310
304
|
element.submit();
|
|
311
305
|
} else {
|
|
312
306
|
element.dispatchEvent(event);
|
|
@@ -314,70 +308,70 @@ var setText = function (eventData, done) {
|
|
|
314
308
|
}
|
|
315
309
|
|
|
316
310
|
function executeAsyncNext(context) {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
311
|
+
let event;
|
|
312
|
+
const currentEvent = context.events[context.eventIndex];
|
|
313
|
+
const nextEvent = context.events[++context.eventIndex];
|
|
320
314
|
try {
|
|
321
315
|
event = getEvent(currentEvent);
|
|
322
316
|
} catch (err) {
|
|
323
|
-
return reject(
|
|
317
|
+
return reject(`exception in get event in text step:${err.message}`);
|
|
324
318
|
}
|
|
325
319
|
|
|
326
320
|
if (shouldSkipEvent(currentEvent, context)) {
|
|
327
321
|
return nextAsyncEvent(context, currentEvent, nextEvent);
|
|
328
|
-
}
|
|
322
|
+
} if (event) {
|
|
329
323
|
try {
|
|
330
324
|
executeAsyncEvent(event, context, currentEvent);
|
|
331
325
|
} catch (err) {
|
|
332
|
-
return reject(
|
|
326
|
+
return reject(`exception in executeEvent in text step:${err.message}`);
|
|
333
327
|
}
|
|
334
328
|
} else if (context.noEventExecuter) {
|
|
335
329
|
context.noEventExecuter(context, currentEvent);
|
|
336
330
|
} else {
|
|
337
|
-
return reject(
|
|
331
|
+
return reject(`cannot execute event ${currentEvent.event}`);
|
|
338
332
|
}
|
|
339
333
|
nextAsyncEvent(context, currentEvent, nextEvent);
|
|
334
|
+
return undefined;
|
|
340
335
|
}
|
|
341
336
|
|
|
342
337
|
function isFocusableInput(target) {
|
|
343
|
-
|
|
344
|
-
return (tagName ===
|
|
338
|
+
const tagName = target.tagName;
|
|
339
|
+
return (tagName === 'INPUT' || tagName === 'TEXTAREA');
|
|
345
340
|
}
|
|
346
341
|
|
|
347
342
|
function isContentEditable(target) {
|
|
348
343
|
return target.getAttribute ?
|
|
349
|
-
Boolean(target.getAttribute(
|
|
344
|
+
Boolean(target.getAttribute('contenteditable') === 'true') :
|
|
350
345
|
false;
|
|
351
346
|
}
|
|
352
347
|
|
|
353
348
|
function executeSetValue(context, userEvent) {
|
|
354
349
|
if (context.isInput) {
|
|
355
350
|
context.element.value = userEvent.eventData.text;
|
|
356
|
-
|
|
357
|
-
inputEvent.initEvent(
|
|
351
|
+
const inputEvent = document.createEvent('Event');
|
|
352
|
+
inputEvent.initEvent('input', true, false);
|
|
358
353
|
context.element.dispatchEvent(inputEvent);
|
|
359
|
-
}
|
|
360
|
-
else if (context.isContentEditable) {
|
|
354
|
+
} else if (context.isContentEditable) {
|
|
361
355
|
context.element.innerHTML = userEvent.eventData.text;
|
|
362
356
|
}
|
|
363
357
|
}
|
|
364
358
|
|
|
365
359
|
function findEffectiveActiveElement() {
|
|
366
|
-
|
|
367
|
-
while (activeElement.shadowRoot
|
|
360
|
+
let activeElement = document.activeElement;
|
|
361
|
+
while (activeElement.shadowRoot?.activeElement) {
|
|
368
362
|
activeElement = activeElement.shadowRoot.activeElement;
|
|
369
363
|
}
|
|
370
364
|
return activeElement;
|
|
371
365
|
}
|
|
372
366
|
|
|
373
367
|
function resolve(result) {
|
|
374
|
-
|
|
368
|
+
const status = {
|
|
375
369
|
status: 'done',
|
|
376
|
-
result
|
|
377
|
-
success: true
|
|
370
|
+
result,
|
|
371
|
+
success: true,
|
|
378
372
|
};
|
|
379
373
|
if (context.isNonTextableElemnet) {
|
|
380
|
-
status.reason =
|
|
374
|
+
status.reason = 'Set text on non input element';
|
|
381
375
|
}
|
|
382
376
|
|
|
383
377
|
done(status);
|
|
@@ -385,13 +379,13 @@ var setText = function (eventData, done) {
|
|
|
385
379
|
|
|
386
380
|
function reject(result) {
|
|
387
381
|
result = result || {};
|
|
388
|
-
|
|
382
|
+
const status = {
|
|
389
383
|
status: 'failed',
|
|
390
|
-
result
|
|
391
|
-
success: false
|
|
384
|
+
result,
|
|
385
|
+
success: false,
|
|
392
386
|
};
|
|
393
387
|
if (context.isNonTextableElemnet) {
|
|
394
|
-
status.reason =
|
|
388
|
+
status.reason = 'Set text on non input element';
|
|
395
389
|
}
|
|
396
390
|
|
|
397
391
|
done(status);
|
|
@@ -405,14 +399,15 @@ var setText = function (eventData, done) {
|
|
|
405
399
|
}
|
|
406
400
|
context.isFocusable = context.isInput || context.isContentEditable;
|
|
407
401
|
context.isSelectable = function (event) {
|
|
408
|
-
return event.type !==
|
|
402
|
+
return event.type !== 'keyup';
|
|
409
403
|
};
|
|
410
404
|
context.noEventExecuter = executeSetValue;
|
|
411
405
|
} catch (err) {
|
|
412
|
-
|
|
406
|
+
reject(`exception in set text step:${err.message}`);
|
|
407
|
+
return;
|
|
413
408
|
}
|
|
414
409
|
|
|
415
|
-
|
|
410
|
+
const oldActiveElement = findEffectiveActiveElement();
|
|
416
411
|
dispatchFocus(eventData.elementToFocusLocatedElement, oldActiveElement);
|
|
417
412
|
executeAsyncNext(context);
|
|
418
413
|
};
|
|
@@ -1,24 +1,25 @@
|
|
|
1
|
+
/* global getLocatedElement */
|
|
2
|
+
|
|
1
3
|
'use strict';
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
var MAX_WHEEL_EVENT_TIMEOUT = 200;
|
|
5
|
+
const wheel = function (eventData, done) {
|
|
6
|
+
const MAX_WHEEL_EVENT_TIMEOUT = 200;
|
|
6
7
|
|
|
7
8
|
function getEventPosition(userEvent, element) {
|
|
8
9
|
function isWithinBounds(start, end, point) {
|
|
9
10
|
return (point > start) && (point < end);
|
|
10
11
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
const pointerPosition = userEvent.pointerPosition || {};
|
|
13
|
+
const rect = element.getBoundingClientRect();
|
|
14
|
+
const clientX = pointerPosition.originX && isWithinBounds(rect.left, rect.left + rect.width, pointerPosition.originX) ? pointerPosition.originX : rect.left + (rect.width / 2);
|
|
15
|
+
const clientY = pointerPosition.originY && isWithinBounds(rect.top, rect.top + rect.height, pointerPosition.originY) ? pointerPosition.originY : rect.top + (rect.height / 2);
|
|
15
16
|
return { x: clientX, y: clientY };
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
function getWheelEvent(userEvent, eventData, element) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
const pos = getEventPosition(userEvent, element);
|
|
21
|
+
const modifiers = eventData?.modifiers || {};
|
|
22
|
+
const dict = {
|
|
22
23
|
deltaX: userEvent.deltaX,
|
|
23
24
|
deltaY: userEvent.deltaY,
|
|
24
25
|
deltaZ: userEvent.deltaZ,
|
|
@@ -37,22 +38,23 @@ var wheel = function (eventData, done) {
|
|
|
37
38
|
|
|
38
39
|
function executeEvents(events, element) {
|
|
39
40
|
if (events.length === 0) {
|
|
40
|
-
|
|
41
|
+
done({ state: 'success' });
|
|
42
|
+
return;
|
|
41
43
|
}
|
|
42
44
|
if (!element) {
|
|
43
45
|
throw new Error('element not found');
|
|
44
46
|
}
|
|
45
47
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
const event = events.shift();
|
|
49
|
+
const currentEvent = getWheelEvent(event, eventData.eventData, element);
|
|
50
|
+
const timeout = events[0] ? Math.min(events[0].timeStamp - event.timeStamp, MAX_WHEEL_EVENT_TIMEOUT) : MAX_WHEEL_EVENT_TIMEOUT;
|
|
49
51
|
element.dispatchEvent(currentEvent);
|
|
50
|
-
setTimeout(
|
|
52
|
+
setTimeout(() => {
|
|
51
53
|
executeEvents(events, element);
|
|
52
54
|
}, timeout);
|
|
53
55
|
}
|
|
54
56
|
|
|
55
|
-
|
|
57
|
+
const element = getLocatedElement(eventData.locatedElement);
|
|
56
58
|
executeEvents(eventData.events, element);
|
|
57
59
|
};
|
|
58
60
|
|
package/polyfills/index.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
require('./Array.prototype.at');
|
|
2
2
|
const xhr2 = require('../commons/xhr2');
|
|
3
|
+
const { performance } = require('perf_hooks');
|
|
3
4
|
|
|
4
5
|
global.xhr2 = xhr2;
|
|
5
6
|
global.XMLHttpRequest = xhr2;
|
|
7
|
+
|
|
8
|
+
// TODO [engine:node@>=16.6.0]: can be removed once we support 16+
|
|
9
|
+
global.performance = performance;
|
package/testRunStatus.js
CHANGED
|
@@ -202,20 +202,6 @@ class RunStatus {
|
|
|
202
202
|
try {
|
|
203
203
|
const params = await runHook(this.options.beforeTest, Object.assign({}, test, { exportsGlobal: globalParameters, globalParameters }), this.options.userData.loginData.token);
|
|
204
204
|
|
|
205
|
-
// Temporary Sapiens log (SUP-3192)
|
|
206
|
-
if (this.options.projectData && this.options.projectData.projectId === 'fZ63D61PRQQVvvtGY6Ue' && this.options.suites && this.options.suites.includes('Sanity')) {
|
|
207
|
-
logger.info('testRunStatus - testStartReport', {
|
|
208
|
-
'test.config.testData': test.config.testData,
|
|
209
|
-
'this.exportsGlobal': this.exportsGlobal,
|
|
210
|
-
'this.fileUserParamsData': this.fileUserParamsData,
|
|
211
|
-
'this.beforeSuiteParams': this.beforeSuiteParams,
|
|
212
|
-
params,
|
|
213
|
-
executionId,
|
|
214
|
-
'test.testId': test.testId,
|
|
215
|
-
'test.resultId': test.resultId,
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
|
|
219
205
|
test.config.testData = Object.assign({}, test.config.testData, this.exportsGlobal, this.fileUserParamsData, this.beforeSuiteParams, params);
|
|
220
206
|
this.options.runParams[test.resultId] = test.config.testData;
|
|
221
207
|
test.startTime = Date.now();
|
|
@@ -316,17 +302,7 @@ class RunStatus {
|
|
|
316
302
|
reporter.onTestFinished(test, wid, isRerun, isCodeMode);
|
|
317
303
|
|
|
318
304
|
const afterMerge = Object.assign({}, this.exportsGlobal, result.exportsGlobal);
|
|
319
|
-
|
|
320
|
-
if (this.options.projectData && this.options.projectData.projectId === 'fZ63D61PRQQVvvtGY6Ue' && this.options.suites && this.options.suites.includes('Sanity')) {
|
|
321
|
-
logger.info('testRunStatus - testEnd', {
|
|
322
|
-
'this.exportsGlobal': this.exportsGlobal,
|
|
323
|
-
'result.exportsGlobal': result.exportsGlobal,
|
|
324
|
-
afterMerge,
|
|
325
|
-
executionId,
|
|
326
|
-
'test.testId': test.testId,
|
|
327
|
-
'test.resultId': test.resultId,
|
|
328
|
-
});
|
|
329
|
-
}
|
|
305
|
+
|
|
330
306
|
this.exportsGlobal = afterMerge;
|
|
331
307
|
return test;
|
|
332
308
|
}
|
package/testimNpmDriver.js
CHANGED
|
@@ -14,7 +14,7 @@ const getNpmVersion = localRunnerCache.memoize(() => npmWrapper.getLatestPackage
|
|
|
14
14
|
|
|
15
15
|
function getPackageVersion() {
|
|
16
16
|
try {
|
|
17
|
-
logger.
|
|
17
|
+
logger.debug('Get package version');
|
|
18
18
|
const path = `${__dirname}/package.json`;
|
|
19
19
|
if (!fs.existsSync(path)) {
|
|
20
20
|
// This usually means that the program runs from a dev environment (in which __dirname
|