Ссылаясь на документацию на веб-сайте Mozilla, события обычно инициируются «внешними» источниками, такими как кнопки, их также можно запускать программно, например, путем вызова метода HTMLElement.click () элемента. или определив событие, а затем отправив его указанной цели с помощью EventTarget.dispatchEvent ().
Я полагаю, что click
- это простое событие, которое может запускаться программно, но change
Событие для <input type=file..>
более сложное, так как требует выбора файла, преобразования в блог, обновления свойства files
и т. Д. Итак, вероятно, по этой причине я не могу просто позвонить imageElementNE.change()
.
Итак, я подумал об использовании dispatchEvent
, и, похоже, он работает
1) Я явно создал Событие. Я предполагаю, что конструктор Event
принимает 2 аргумента, 2-й является необязательным.
С https://developer.mozilla.org/en-US/docs/Web/API/Event/Event
event = new Event(typeArg, eventInit);
Из документации typeArg
- это строка DOMString, представляющая имя события. Другими словами, 1-й аргумент представляется type
события. Поскольку я хочу отправить change
событие, мне нужно назвать его change
.
Для части eventInit
я посмотрел определение события change
в https://developer.mozilla.org/en-US/docs/Web/Events/change и выбрал значения bubbles
и cancelable
оттуда
let fileSelectEvent = new Event("change",{bubbles:true,
cancelable: false});
Это создает Event
, который выглядит следующим образом (я должен признаться, я не очень понимаю)
Event {isTrusted: false, type: "change", target: input#question-file-upload.custom-file-input.ng-untouched.ng-pristine.ng-valid, currentTarget: input#question-file-upload.custom-file-input.ng-untouched.ng-pristine.ng-valid, eventPhase: 2, …}bubbles: truecancelBubble: falsecancelable: falsecomposed: falsecurrentTarget: nulldefaultPrevented: falseeventPhase: 0isTrusted: falsepath: (10) [input#question-file-upload.custom-file-input.ng-untouched.ng-pristine.ng-valid, div#file-upload.custom-file, div.form-group, form#new-question-form.practice-question-form.ng-untouched.ng-pristine.ng-invalid, div#form-div.body__div--background, div#root0, body, html, document, Window]returnValue: truesrcElement: input#question-file-upload.custom-file-input.ng-untouched.ng-pristine.ng-validtarget: input#question-file-upload.custom-file-input.ng-untouched.ng-pristine.ng-validtimeStamp: 3759.4000000026426type: "change"__proto__: Event
2) После создания Event
я вызвал метод dispatchEvent
для imageInputNE
. По сравнению с EventTarget.dispatchEvent()
, я думаю, это означает, что EventTarget
вызывает событие (в моем случае imageInputNE
запускает fileSelectEvent
.
imageInputNE.dispatchEvent(fileSelectEvent);
Вся пройденная спецификация
fit('should keep track of image counter when an image is loaded', () => {
let newPracticeQuestionComponent = component;
expect(newPracticeQuestionComponent.currentImageAttachmentCount).toBe(0);
let imageInputDE = fixture.debugElement.query(By.css("#question-file-upload"));
expect(imageInputDE).toBeTruthy();
spyOn(newPracticeQuestionComponent,'handleFileSelect');/*.and.callThrough();/*.and.callFake((event)=>{
console.log("fake handleFileSelect called with event",event);
});*/
/*
nativeElemenet hasn'nt got any type. As this program will run in a browser, we can
typecast it to HTMLElement so that we can access prperties and methods of the
corresponding nativeElement
The HTMLElement interface represents any HTML element. Some elements directly
implement this interface, while others implement it via an interface that inherits it.
*/
let imageInputNE = imageInputDE.nativeElement ;
console.log("input element is ",imageInputNE);
console.log("debug element is ",imageInputDE);
//imageInputNE.click();
let fileSelectEvent = new Event("change",{bubbles:true,
cancelable: false});
console.log("created event ",fileSelectEvent);
imageInputNE.dispatchEvent(fileSelectEvent);
expect(newPracticeQuestionComponent.handleFileSelect).toHaveBeenCalled();
});
Вышеприведенное может быть не лучшим решением, так как я не могу манипулировать files
в поле input
, но это лучшее, что я могу придумать!