Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change event is never fired when faking a file drop on custom input #627

Open
ThomasFerro opened this issue Aug 22, 2023 · 0 comments
Open

Comments

@ThomasFerro
Copy link

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:

  1. When dropping a file in the custom component, we have both the inner input's drop and the wrapper's change events are triggered:
    image
  2. When selecting a file via the file chooser, the wrapper's change event is also triggered:
    image

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant