Closed chalmagean closed 2 years ago
What library are you using for your drag and drop behavior implementation? Capybara attempts to automatically detect whether your app is using proprietary drag/drop or standard HTML5 based drag/drop behaviors and uses different methods based on what it detects. You can however force it to use one mode of the other. Try
note2.drag_to(note1, html5: true)
or
note2.drag_to(note1, html5: false)
to see if that makes any difference. It's also possible Capybara just isn't compatible with the method your application is using. ie. If you're repeatedly adding/removing elements to the page then Capybara may not be able to emulate the drag/drop
I'm using Stimulus JS and doing the drag and drop manually. Like this.
import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
static targets = ["note"];
dragStart(event) {
event.target.style.opacity = "0.4";
this.dragSrcEl = event.target;
event.dataTransfer.effectAllowed = "move";
event.dataTransfer.setData("text/html", event.target.innerHTML);
}
dragEnter(event) {
event.target.classList.add("over");
if (event.preventDefault) {
event.preventDefault();
}
return false;
}
dragOver(event) {
if (event.preventDefault) {
event.preventDefault();
}
return false;
}
dragLeave(event) {
event.target.classList.remove("over");
this.resetOpacity();
}
drop(event) {
event.stopPropagation();
event.target.classList.remove("over");
this.resetOpacity();
fetch("/note_links", {
method: "POST",
credentials: "same-origin",
headers: {
Accept: "text/vnd.turbo-stream.html",
"Content-Type": "application/json",
"X-CSRF-Token": document.head.querySelector("[name='csrf-token']")
.content,
},
body: JSON.stringify({
source_id: this.dragSrcEl.dataset.id,
target_id: event.target.dataset.id,
}),
})
.then((response) => response.text())
.then(Turbo.renderStreamMessage);
}
dragEnd() {
this.resetOpacity();
}
resetOpacity() {
this.noteTargets.forEach((el) => {
el.style.opacity = "1";
});
}
}
<div class="md:w-1/3 note" draggable="true" data-notes-target="note" data-action="dragstart->notes#dragStart dragend->notes#dragEnd drop->notes#drop dragenter->notes#dragEnter dragleave->notes#dragLeave dragover->notes#dragOver" data-id="<%= insight.id %>">
<div class="note-body flex flex-col mt-4 h-48 bg-white text-gray-600 body-font text-sm border-2 border-gray-200 rounded-md border-opacity-60 overflow-hidden mx-4 shadow-md">
<div class="flex-none mx-3 my-0 mt-0 py-1 font-bold note-header border-b">
<div class="note-id">Id: <%= insight.id %></div>
</div>
<div class="grow p-0 py-2 mx-3">
<p class="leading-relaxed mb-3"><%= insight.text %></p>
</div>
<div id="insight-note-<%= insight.id %>" class="flex-none py-1 mx-3 text-right">
<% if insight.insights.present? %>
<div class="note-links">
<%= insight.insights.map(&:id).join(", ") %>
</div>
<% end %>
</div>
</div>
</div>
I've also tried https://github.com/Shopify/draggable with the same effect.
In both cases changing the html5
option had no effect.
This was totally my fault. I had a JS error (thank god I thought about opening the console) because of calling .content
on null.
I would help to see any JS errors when running the tests.
I'm currently using master, but I've tried the latest version(s) as well.
Expected Behavior
I expect the test to be able to drag notes over one another just like I can do it manually in Chrome (see screenshot).
Actual Behavior
Steps to reproduce
This is my test, not sure how relevant it is.