'use strict';
// The mouse bot will always be precise. Humans can click anywhere in the boxes.
const epsilon = (window.eventSender) ? 0 : 50;
const elementCenter = (element) => {
const clientRect = element.getBoundingClientRect();
const centerX = (clientRect.left + clientRect.right) / 2;
const centerY = (clientRect.top + clientRect.bottom) / 2;
return { x: centerX, y: centerY };
};
const mouseMoveToCenter = (element, frameOffset) => {
const center = elementCenter(element);
eventSender.mouseMoveTo(center.x + frameOffset.x, center.y + frameOffset.y);
};
const mouseEventCoordinates = (event) => {
return {
client: { x: event.clientX, y: event.clientY },
offset: { x: event.offsetX, y: event.offsetY },
page: { x: event.pageX, y: event.pageY },
screen: { x: event.screenX, y: event.screenY },
};
};
// Recursively loads content into a series of nested iframes.
// Returns a promise that resolves with the HTMLDocument of the innermost frame.
const loadNestedFrames = (domRoot) => {
const frame = domRoot.querySelector('iframe');
if (!frame)
return Promise.resolve(domRoot);
return new Promise((resolve, reject) => {
const htmlSourceId = frame.getAttribute('data-source');
const html = document.getElementById(htmlSourceId).textContent;
frame.onload = () => {
const frameDocument = frame.contentDocument;
resolve(loadNestedFrames(frameDocument));
};
frame.setAttribute('srcdoc', html);
});
};
const runDragTest = (t, params) => {
const domRoot = params.domRoot;
const dragged = domRoot.querySelector('.dragged');
let dragStartCoordinates = null;
dragged.ondragstart = (event) => {
dragStartCoordinates = mouseEventCoordinates(event);
event.dataTransfer.setData('text/plain', 'Needed to work in Firefox');
};
const dropZone = domRoot.querySelector('.dropzone');
dropZone.ondragover = (event) => { event.preventDefault(); }
let dropCoordinates = null;
dropZone.ondrop = (event) => {
// Needed to avoid navigation in Firefox.
event.preventDefault();
dropCoordinates = mouseEventCoordinates(event);
}
let dragEndCoordinates = null;
return new Promise((resolve, reject) => {
dragged.ondragend = (event) => {
dragEndCoordinates = mouseEventCoordinates(event);
resolve(true);
}
if (window.eventSender) {
mouseMoveToCenter(dragged, params.frameOffset);
eventSender.mouseDown();
setTimeout(() => {
mouseMoveToCenter(dropZone, params.frameOffset);
eventSender.mouseUp();
}, 100);
}
}).then(() => t.step(() => {
assert_approx_equals(dragStartCoordinates.client.x, params.start.client.x,
epsilon, 'clientX on the dragstart event should be in the drag me box');
assert_approx_equals(dragStartCoordinates.client.y, params.start.client.y,
epsilon, 'clientY on the dragstart event should be in the drag me box');
assert_approx_equals(dragStartCoordinates.page.x, params.start.page.x,
epsilon, 'pageX on the dragstart event should be in the drag me box');
assert_approx_equals(dragStartCoordinates.page.y, params.start.page.y,
epsilon, 'pageY on the dragstart event should be in the drag me box');
assert_approx_equals(dropCoordinates.client.x, params.end.client.x, epsilon,
'clientX on the drop event should be in the drop here box');
assert_approx_equals(dropCoordinates.client.y, params.end.client.y, epsilon,
'clientX on the drop event should be in the drop here box');
assert_approx_equals(dropCoordinates.page.x, params.end.page.x, epsilon,
'pageX on the drop event should be in the drop here box');
assert_approx_equals(dropCoordinates.page.y, params.end.page.y, epsilon,
'pageY on the drop event should be in the drop here box');
assert_approx_equals(dragEndCoordinates.client.x, params.end.client.x,
epsilon, 'clientX on the dragend event should be in the drop here box');
assert_approx_equals(dragEndCoordinates.client.y, params.end.client.y,
epsilon, 'clientY on the dragend event should be in the drop here box');
assert_approx_equals(dragEndCoordinates.page.x, params.end.page.x, epsilon,
'pageX on the dragend event should be in the drop here box');
assert_approx_equals(dragEndCoordinates.page.y, params.end.page.y, epsilon,
'pageY on the dragend event should be in the drop here box');
}));
};