blob: 8c65ebb8ab11079841f80aff310a33dfc5060395 [file] [log] [blame]
const isDebug = false;
function logDebug(callback)
{
if (isDebug)
console.log(callback());
}
function dispatchMouseActions(actions)
{
if (!window.eventSender)
return Promise.reject(new Error("window.eventSender is undefined."));
return new Promise(resolve => {
setTimeout(() => {
for (let action of actions) {
switch (action.type) {
case "pointerMove":
let origin = { x: 0, y: 0 };
if (action.origin instanceof Element) {
const bounds = action.origin.getBoundingClientRect();
logDebug(() => `${action.origin.id} [${bounds.left}, ${bounds.top}, ${bounds.width}, ${bounds.height}]`);
origin.x = bounds.left + 1;
origin.y = bounds.top + 1;
}
logDebug(() => `eventSender.mouseMoveTo(${action.x + origin.x}, ${action.y + origin.y})`);
eventSender.mouseMoveTo(action.x + origin.x, action.y + origin.y);
break;
case "pointerDown":
// FIXME: what to do with "button"?
logDebug(() => `eventSender.mouseDown()`);
eventSender.mouseDown();
break;
case "pointerUp":
// FIXME: what to do with "button"?
logDebug(() => `eventSender.mouseUp()`);
eventSender.mouseUp();
break;
default:
return Promise.reject(new Error(`Unknown action type "${action.type}".`));
}
}
resolve();
});
});
}
function dispatchTouchActions(actions)
{
if (!window.testRunner || typeof window.testRunner.runUIScript !== "function")
return Promise.reject(new Error("window.testRunner.runUIScript() is undefined."));
let x = 0;
let y = 0;
let timeOffset = 0;
const events = actions.map(action => {
const touch = {
inputType : "finger",
id : 1,
x : action.x,
y : action.y,
pressure : 0
};
const command = {
inputType : "hand",
coordinateSpace : "content",
touches : [touch],
timeOffset
};
let timeOffsetIncrease = 0.05;
switch (action.type) {
case "pointerMove":
touch.phase = "moved";
if (action.origin instanceof Element) {
const bounds = action.origin.getBoundingClientRect();
touch.x += bounds.left + 1;
touch.y += bounds.top + 1;
}
break;
case "pointerDown":
touch.phase = "began";
break;
case "pointerUp":
touch.phase = "ended";
touch.x = x;
touch.y = y;
break;
case "pause":
timeOffsetIncrease = action.duration / 1000;
touch.phase = "stationary";
break;
default:
return Promise.reject(new Error(`Unknown action type "${action.type}".`));
}
x = touch.x;
y = touch.y;
timeOffset += timeOffsetIncrease;
return command;
});
const stream = JSON.stringify({ events });
logDebug(() => stream);
return new Promise(resolve => testRunner.runUIScript(`(function() {
(function() { uiController.sendEventStream('${stream}') })();
uiController.uiScriptComplete();
})();`, resolve));
}
if (window.test_driver_internal === undefined)
window.test_driver_internal = { };
window.test_driver_internal.action_sequence = function(sources)
{
// https://w3c.github.io/webdriver/#processing-actions
let noneSource;
let pointerSource;
for (let source of sources) {
switch (source.type) {
case "none":
noneSource = source;
break;
case "pointer":
pointerSource = source;
break;
default:
return Promise.reject(new Error(`Unknown source type "${action.type}".`));
}
}
if (!pointerSource)
return Promise.reject(new Error(`Unknown pointer type pointer type "${action.parameters.pointerType}".`));
const pointerType = pointerSource.parameters.pointerType;
if (pointerType !== "mouse" && pointerType !== "touch")
return Promise.reject(new Error(`Unknown pointer type "${pointerType}".`));
// If we have a "none" source, let's inject any pause with non-zero durations into the pointer source
// after the matching action in the pointer source.
if (noneSource) {
let injectedActions = 0;
noneSource.actions.forEach((action, index) => {
if (action.duration > 0) {
pointerSource.actions.splice(index + injectedActions + 1, 0, action);
injectedActions++;
}
});
}
logDebug(() => JSON.stringify(pointerSource));
if (pointerType === "mouse")
return dispatchMouseActions(pointerSource.actions);
if (pointerType === "touch")
return dispatchTouchActions(pointerSource.actions);
};