`fireEvent.drop` API behaves not as expected about preventDefault in Browser and js env
- @testing-library/dom 9.3.4 version:
- Testing Framework and version: null
- DOM Environment: 20.0.3
Reproduction:
import { fireEvent, render,act } from '@testing-library/react'
import type { FC } from 'react'
function tick(): Promise<void> {
return new Promise((resolve) => {
setTimeout(resolve, 0)
})
}
async function fireDragDrop(source: Element) {
await act(async () => {
fireEvent.dragStart(source)
fireEvent.dragEnter(source)
fireEvent.dragOver(source)
fireEvent.drop(source)
await tick()
})
}
const Container: FC = (function Container() {
return (
<>
<div draggable="true"
data-testid={'Other1'}
onDragStart={(e)=>{
e.preventDefault()
console.log("ondragstart")
}}
onDragOver={()=>{
console.log("onDragOver")
}}>
other1
</div>
</>
)
})
describe('drag', () => {
it('prevent', async () => {
const rendered = render(<Container />)
const box1 = (await rendered.findAllByTestId('Other1'))[0]
await fireDragDrop(box1)
})
})
What you did:
run it in brower and testing env
Problem description:
when I run this component in the browser, onDragOver isn't executed due to e.preventDefault() in the onDragStart test case,
but onDragOver is executed in testing env after onDragStart
Expect
ii should prevent onDragOver fn in test env
Hi @electroluxcode, thanks for taking the time to open this.
fireEvent is a very low level API, all it does is dispatch the event based on the configuration.
I think you should be trying your use case with user-event instead.
To top that, I'm not sure I understand the reasoning behind calling e.preventDefault() in onDragStart (afaik, usually calling e.preventDefault in drag scenarios only has meaning in onDragOver or onDragEnter to mark that an item can be dropped somewhere).
I'm also not sure the browser's behavior is following the spec and I couldn't find any mention about that. Are you familiar with any spec that defines this behavior?
Hi @electroluxcode, thanks for taking the time to open this.
fireEventis a very low level API, all it does is dispatch the event based on the configuration. I think you should be trying your use case withuser-eventinstead. To top that, I'm not sure I understand the reasoning behind callinge.preventDefault()inonDragStart(afaik, usually callinge.preventDefaultin drag scenarios only has meaning inonDragOveroronDragEnterto mark that an item can be dropped somewhere). I'm also not sure the browser's behavior is following the spec and I couldn't find any mention about that. Are you familiar with any spec that defines this behavior?
@MatanBobi Thank you very much for your reply. The reason I call e.preventDefault() in onDragStart is to avoid dragging some page elements that shouldn't be draggable. You can refer to
https://github.com/react-dnd/react-dnd/blob/7c88c37489a53b5ac98699c46a506a8e085f1c03/packages/backend-html5/src/HTML5BackendImpl.ts#L551-L553
This is a snippet of react-dnd code where this logic is encapsulated within the onDragStart method.
I wanted to write test cases for this code snippet, but found that the onDragStart event behaves unexpectedly during testing.
and after reading your reply, I looked into user-event, but it seems there are no methods related to dragStart or dragOver.
and regarding the browser's behavior you mentioned, you can refer to https://html.spec.whatwg.org/multipage/dnd.html#dndevents.