In my Karma-Jasmine tests I have to test my onPaste
method.
onPaste
method:
onPaste(event: any): void {
const pastedText = event.clipboardData.getData('text/plain');
// some stuff
}
My unit test:
it('should do something', () => {
const queryField = fixture.debugElement.query(By.css('input[type="search"]')).nativeElement;
queryField.dispatchEvent(new ClipboardEvent('paste', {
dataType: 'text/plain',
data: '325435956\r325435956',
}));
// some stuff
})
And I use Chrome to run the tests but new ClipboardEvent()
in Chrome creates ClipboardEvent
object where clipboardData
is null
and event.clipboardData.getData('text/plain')
throws an error:
Uncaught TypeError: Cannot read property 'getData' of null
It doesn't happen in Firefox, so if I use karma-firefox-launcher
it works fine, but I have to use Chrome. So, I had some ideas how to solve it.
The first idea was to create ClipboardEvent
object and override clipboardData property:
const pasteEvent = new ClipboardEvent('paste', {
dataType: 'text/plain',
data: '325435956\r325435956',
});
pasteEvent.clipboardData = {
getData() {
return this.data;
}
};
But I can't do it because clipboardData
is a read-only property.
The second idea was to create fake ClipboardEvent
object:
function FakePasteEvent(options) {
this.clipboardData = {
dataType: options.dataType,
data: options.data,
getData() {
return this.data;
}
};
}
const pasteEvent = new FakePasteEvent({
dataType: 'text/plain',
data: '325435956\r325435956',
});
console.log(pasteEvent.clipboardData.getData()) // returns what I need
But I can't pass it to dispatchEvent
because the type of pasteEvent
is not Event. Then I thought I can specify prototype object for my FakePasteEvent
:
Object.setPrototypeOf(pasteEvent, ClipboardEvent);
But anyway I've got an error:
TypeError: Failed to execute 'dispatchEvent' on 'EventTarget': parameter 1 is not of type 'Event'
Can you help me to solve this problem? ;)
Code example here http://jsbin.com/puqilivalo/1/edit?html,js,console,output
clipboardData property holds a DataTransfer object, which can be used: to specify what data should be put into the clipboard from the cut and copy event handlers, typically with a setData(format, data) call; to obtain the data to be pasted from the paste event handler, typically with a getData(format) call.
The ClipboardEvent interface represents events providing information related to modification of the clipboard, that is cut , copy , and paste events.
In Internet Explorer, use the getData method to retrieve and the clearData method to clear the contents of the clipboard. In Firefox, Opera, Google Chrome and Safari, use the execCommand method with the 'Paste' command to retrieve and with the 'Copy' command to set the text content of the clipboard.
Browser support: Retrieves the specified formatted data from the clipboard. In Internet Explorer, use the setData method to set and the clearData method to clear the contents of the clipboard.
Quite interestingly, I am currently struggling on who is right between chrome and Firefox on this, I still can't figure out what the specs tell when they say
dictionary ClipboardEventInit : EventInit { DataTransfer? clipboardData = null; };
and
[Constructor (DOMString type, optional ClipboardEventInit eventInitDict), Exposed=Window] interface ClipboardEvent : Event { readonly attribute DataTransfer? clipboardData; };
I would tend to say that Chrome is right when it returns null for the clipboardData
property, but then the very next example makes FF behavior correct:
Example 3
var pasteEvent = new ClipboardEvent('paste');
pasteEvent.clipboardData.items.add('My string', 'text/plain'); document.dispatchEvent(pasteEvent);
But anyway, Chrome does support (partially) the DataTransfer contructor, whereas FF still doesn't. And you can then construct your event with this DataTransfer object in chrome too:
var dT = null;
try{ dT = new DataTransfer();} catch(e){}
var evt = new ClipboardEvent('paste', {clipboardData: dT});
console.log('clipboardData available: ', !!evt.clipboardData);
evt.clipboardData.setData('text/plain', 'Hello world');
document.onpaste = function(e){
console.log('onpaste: ', e.clipboardData.getData('text/plain'));
};
document.dispatchEvent(evt);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With