Skip to content

Commit

Permalink
[DOM-61912] Fix JS_DROP_FILE snippet to work for input fields when th…
Browse files Browse the repository at this point in the history
…e directory option is enabled (#537)

* Fix drag and drop js snippet

* Update src/cucu/steps/file_input_steps.py

CR fixes

Co-authored-by: Kevin Garton <71028750+ddl-kgarton@users.noreply.github.com>

* resolve build issue

---------

Co-authored-by: DDL-Cedric <95940265+ddl-cedricyoung@users.noreply.github.com>
Co-authored-by: Kevin Garton <71028750+ddl-kgarton@users.noreply.github.com>
  • Loading branch information
3 people authored Nov 26, 2024
1 parent b007655 commit 9c3aa90
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 25 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project closely adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 1.0.5
- Fix - Resolved issues with the drag-and-drop feature to ensure compatibility with all input options.

## 1.0.4
- Change - for retry steps, also log before and after call messages

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "cucu"
version = "1.0.4"
version = "1.0.5"
description = "Easy BDD web testing"
readme = "README.md"
license = { text = "The Clear BSD License" }
Expand Down
141 changes: 118 additions & 23 deletions src/cucu/steps/file_input_steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,30 +41,125 @@ def upload_file_to_input(ctx, filepath, name):


JS_DROP_FILE = """
var target = arguments[0],
offsetX = arguments[1],
offsetY = arguments[2],
document = target.ownerDocument || document,
window = document.defaultView || window;
var input = document.createElement('INPUT');
input.type = 'file';
input.onchange = function () {
var rect = target.getBoundingClientRect(),
x = rect.left + (offsetX || (rect.width >> 1)),
y = rect.top + (offsetY || (rect.height >> 1)),
dataTransfer = { files: this.files };
['dragenter', 'dragover', 'drop'].forEach(function (name) {
var evt = document.createEvent('MouseEvent');
evt.initMouseEvent(name, !0, !0, window, 0, 0, 0, x, y, !1, !1, !1, !1, 0, null);
evt.dataTransfer = dataTransfer;
target.dispatchEvent(evt);
});
setTimeout(function () { document.body.removeChild(input); }, 25);
var args = arguments,
element = args[0],
offsetX = args[1],
offsetY = args[2],
doc = element.ownerDocument || document;
var box = element.getBoundingClientRect(),
clientX = box.left + (offsetX || box.width / 2),
clientY = box.top + (offsetY || box.height / 2),
target = doc.elementFromPoint(clientX, clientY);
if (!(target && element.contains(target))) {
element.scrollIntoView({
behavior: "instant",
block: "center",
inline: "center",
});
var box = element.getBoundingClientRect(),
clientX = box.left + (offsetX || box.width / 2),
clientY = box.top + (offsetY || box.height / 2),
target = doc.elementFromPoint(clientX, clientY);
if (!(target && element.contains(target))) {
// Scrolling didn't do the trick, so give up
var ex = new Error("Element not interactable");
ex.code = 15;
throw ex;
}
}
var input = doc.createElement("INPUT");
input.setAttribute("type", "file");
input.setAttribute("multiple", "");
input.setAttribute("style", "position:fixed;z-index:2147483647;left:0;top:0;");
input.onchange = function (ev) {
input.parentElement.removeChild(input);
ev.stopPropagation();
var dataTransfer = {
constructor: DataTransfer,
effectAllowed: "all",
dropEffect: "none",
types: ["Files"],
files: input.files,
setData: function setData() {},
getData: function getData() {},
clearData: function clearData() {},
setDragImage: function setDragImage() {},
};
document.body.appendChild(input);
if (window.DataTransferItemList) {
dataTransfer.items = Object.setPrototypeOf(
Array.prototype.map.call(input.files, function (f) {
return {
constructor: DataTransferItem,
kind: "file",
type: f.type,
getAsFile: function getAsFile() {
return f;
},
getAsString: function getAsString(callback) {
var reader = new FileReader();
reader.onload = function (ev) {
callback(ev.target.result);
};
reader.readAsText(f);
},
webkitGetAsEntry: function webkitGetAsEntry() {
return {
constructor: window.FileSystemEntry || window.Entry,
name: f.name,
fullPath: "/" + f.name,
isFile: true,
isDirectory: false,
file: function file(callback) {
callback(f);
},
};
},
};
}),
{
constructor: DataTransferItemList,
add: function add() {},
clear: function clear() {},
remove: function remove() {},
}
);
}
["dragenter", "dragover", "drop"].forEach(function (type) {
var event = doc.createEvent("DragEvent");
event.initMouseEvent(
type,
true,
true,
doc.defaultView,
0,
0,
0,
clientX,
clientY,
false,
false,
false,
false,
0,
null
);
Object.setPrototypeOf(event, null);
event.dataTransfer = dataTransfer;
Object.setPrototypeOf(event, DragEvent.prototype);
target.dispatchEvent(event);
});
};
doc.documentElement.appendChild(input);
input.getBoundingClientRect(); /* force reflow for Firefox */
return input;
"""

Expand Down
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 9c3aa90

Please sign in to comment.