diff --git a/test/common/test-functions.js b/test/common/test-functions.js index a27faade8320..bf5cabf352a5 100644 --- a/test/common/test-functions.js +++ b/test/common/test-functions.js @@ -194,6 +194,33 @@ window.ph_mouse = function(sel, type, x, y, btn, ctrlKey, shiftKey, altKey, meta throw new Error(sel + " is disabled or somehow doesn't process events"); }; +window.ph_drag_event = function(sel, eventType, filename) { + const el = window.ph_find(sel); + + /* The element has to be visible, and not collapsed */ + if (el.offsetWidth <= 0 && el.offsetHeight <= 0 && el.tagName != 'svg') + throw new Error(sel + " is not visible"); + + let dataTransfer = null; + if (filename) { + const content = "Random file content: 4"; + const file = new File([content], filename, { type: "text/plain" }); + dataTransfer = new DataTransfer(); + dataTransfer.dropEffect = "move"; + + // The DataTransfer.files property is read-only as this object has a processing + // and security check that is handled by the browser during drag-and-drop events. + // Work around it and create a DataTransfer object with a single small textfile. + Object.defineProperty(dataTransfer, 'files', { + value: [file], + writable: false, + }); + } + + const ev = new DragEvent(eventType, { bubbles: true, dataTransfer }); + el.dispatchEvent(ev); +}; + window.ph_get_checked = function(sel) { const el = window.ph_find(sel); if (el.checked === undefined) diff --git a/test/common/testlib.py b/test/common/testlib.py index 3f9b2cf01aff..83de25923dfa 100644 --- a/test/common/testlib.py +++ b/test/common/testlib.py @@ -575,6 +575,19 @@ def click(self, selector: str) -> None: """ self.mouse(selector + ":not([disabled]):not([aria-disabled=true])", "click") + def drag(self, selector: str, dragType: str, filename: str | None = None) -> None: + """Simulate drag events + + When filename is specified a file is created to simulate an upload for drop event + + :param selector: target element + :param dragType: the drag event to simulate (dragenter, dragleave, dragover, drop, ...) + :param filename: name of file to be uploaded + """ + + self.wait_visible(selector) + return self.call_js_func('ph_drag_event', selector, dragType, filename) + def val(self, selector: str) -> Any: """Get the value attribute of a selector.