`change` event is never fired when faking a file drop on custom input
ThomasFerro opened this issue · comments
Is this a regression?
No
Description
Hello!
We are working on a custom file input component, which mostly rely on native elements with a more refined UI. Unfortunately, we are unable to test the "drag and drop" feature of this component using spectator
the way we imagined it.
We managed to reproduce the issue in the following minimalist implementation:
<!-- my-file-input template -->
<input type="file" multiple (drop)="onFilesDrop($event)">
// my-file-input component
import { Component } from '@angular/core';
@Component({
selector: 'app-my-file-input',
templateUrl: './my-file-input.component.html',
styleUrls: ['./my-file-input.component.css'],
standalone: true
})
export class MyFileInputComponent {
onFilesDrop(e: Event) {
console.log('onFilesDrop', e)
}
}
<!-- app template -->
<app-my-file-input (change)="onFileChanged($event)"></app-my-file-input>
// app component
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
onFileChanged(e: Event) {
console.log('onFileChanged', e)
}
}
In a browser, it all seems to work just fine:
- When dropping a file in the custom component, we have both the inner input's
drop
and the wrapper'schange
events are triggered:
- When selecting a file via the file chooser, the wrapper's
change
event is also triggered:
However, in the test context, when faking a file drop, only the inner input's drop
event is trigger, not the wrapper's change
event:
LOG: 'onFilesDrop', Object{dataTransfer: Object{files: Object{length: ..., item: ...}}}
Here is how we fake the file drop (complete reproduction repo is also linked):
it('should emit files when the user drops files', fakeAsync(() => {
const emittedFiles: FileList = {
length: 1,
item(): File | null {
return new File([], 'newFile.pdf');
},
};
let changeEventEmitted = false;
spectator.element.addEventListener('change', (event) => {
const element = event.target as HTMLInputElement;
expect(element.files!.length).toEqual(1);
expect(element.files!.item(0)).toEqual(emittedFiles[0]);
changeEventEmitted = true;
});
const dragEvent: DragEvent = {
// @ts-ignore
dataTransfer: {
files: emittedFiles,
},
};
spectator.triggerEventHandler('input', 'drop', dragEvent);
tick(50);
expect(changeEventEmitted).toBeTruthy();
}));
Is it related to the way we implemented the test? A limitation in the library?
Thanks for the whole project and in advance for this specific issue, have a nice day :D
Please provide a link to a minimal reproduction of the bug
https://gitlab.com/thomas.ferro/spectator-fake-file-drop-event
Please provide the exception or error you saw
We expect the test to succeed, but the `change` event is never fired, thus making the assertion fail.
Please provide the environment you discovered this bug in
Local.
Anything else?
I will be glad to help resolving this issue if indeed it is due to a bug in the library :)
Do you want to create a pull request?
Yes