I've a service that detects if a CTRL/CMD key is pressed. It is used in various components to check (among other things) if links should open in a new tab or not.
Service:
keyDownListenerCTRL = fromEvent<KeyboardEvent>(window, 'keydown').pipe(
tap((event: KeyboardEvent) => {
if (
event.metaKey ||
event.ctrlKey ||
event.key === 'Meta' ||
event.key === 'Ctrl'
) {
this.isControlButtonHeld = true;
}
})
);
constructor() {
this.keyDownListenerCTRL.subscribe();
}
I don't know how to test this. There is no HTML element that I could simulate a click on, so using a dispatchEvent (like suggested here) does not work.
CodePudding user response:
It should be the same thing as the answer you linked to, but on the window object.
const evt = new KeyboardEvent("keydown", {
key: 'Control',
code: 'ControlLeft',
ctrlKey: true
});
window.dispatchEvent(evt);
A few things...
- You might be better off using renderer.listen to attach to the event. This way you don't have to reference an non-injected global object like window, and the technique above will still work.
- If you can, consider using HostListener instead of fromEvent as now testing is a simple as calling a method.
// injecting document and using renderer.
constructor (private renderer: Renderer2) {
this.renderer.listen('window', 'keydown', event => { /* do stuff */ });
}
// Using HostListner to listen to control and escape
@HostListener('window:keydown.control')
@HostListener('window:keydown.escape')
onKeyDown(evt: KeyboardEvent) {
this.isControlButtonHeld = true;
}