Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions lib/capybara/cuprite/browser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,18 @@ def drag_by(node, dx, dy, steps, delay = nil, scroll = true)
mouse.up
end

def drop(node, *args)
if args[0].is_a?(String)
execute("_cuprite.attachDropInput()")
input = find(:css, "#_cuprite_drop_file").first
select_file(input, args)
evaluate_on(node: node, expression: "_cuprite.dropFile(this)")
else
strings = args.flat_map { |arg| arg.map { |type, data| { "type" => type, "data" => data } } }
evaluate_on(node: node, expression: "_cuprite.dropString(#{strings.to_json}, this)")
end
end

def select_file(node, value)
node.select_file(value)
end
Expand Down
41 changes: 41 additions & 0 deletions lib/capybara/cuprite/javascripts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,47 @@ class Cuprite {
return true;
}

// Ported from Capybara's Selenium html5_drag.rb (DROP_STRING).
dropString(strings, target) {
let dt = new DataTransfer();
let opts = { cancelable: true, bubbles: true, dataTransfer: dt };
for (let i = 0; i < strings.length; i++) {
if (dt.items) {
dt.items.add(strings[i]["data"], strings[i]["type"]);
} else {
dt.setData(strings[i]["type"], strings[i]["data"]);
}
}
target.dispatchEvent(new DragEvent("drop", opts));
}

// Ported from Capybara's Selenium html5_drag.rb (ATTACH_FILE).
attachDropInput() {
document.getElementById("_cuprite_drop_file")?.remove();
let input = document.createElement("INPUT");
input.type = "file";
input.id = "_cuprite_drop_file";
input.multiple = true;
document.body.appendChild(input);
}

// Ported from Capybara's Selenium html5_drag.rb (DROP_FILE).
dropFile(target) {
let input = document.getElementById("_cuprite_drop_file");
let files = input.files;
let dt = new DataTransfer();
let opts = { cancelable: true, bubbles: true, dataTransfer: dt };
input.parentElement.removeChild(input);
if (dt.items) {
for (let i = 0; i < files.length; i++) {
dt.items.add(files[i]);
}
} else {
Object.defineProperty(dt, "files", { value: files, writable: false });
}
target.dispatchEvent(new DragEvent("drop", opts));
}

// This command is purely for testing error handling
browserError() {
throw new Error("zomg");
Expand Down
2 changes: 2 additions & 0 deletions lib/capybara/cuprite/node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ def drag_by(x, y, **options)
command(:drag_by, x, y, options[:steps], options[:delay], options[:scroll])
end

def drop(...) = command(:drop, ...)

def trigger(event)
command(:trigger, event)
end
Expand Down
5 changes: 0 additions & 5 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,6 @@ module TestSessions
RSpec.configure do |config|
config.define_derived_metadata do |metadata|
regexes = <<~REGEXP.split("\n").map { |s| Regexp.quote(s.strip) }.join("|")
node Element#drop can drop a file
node Element#drop can drop multiple files
node Element#drop can drop strings
node Element#drop can drop multiple strings
node Element#drop can drop a pathname
node #set should submit single text input forms if ended with
#has_field with valid should be false if field is invalid
#has_element? should be true if the given element is on the page
Expand Down
Loading