Categories
angular automated-tests java javascript selenium

Cannot input text with selenium into field with angular 2 directive

I have worked with Selenium for about 4 years. This is first time happened to me that I cannot find a proper way to send text to input field.
Our application is using angular 2 and I am sure it has something to do with it.
We have required field with angular 2 directive that checks if it’s a number and later formats it(just adding commas).
When I am using regular selenium sendKeys() method, text does not appear in input field with no exception.
I have tried to use Jquery:

 $("#test_borrowValue").val(770) 

from selenium and google chrome console.
Text appears inside an input, but angular doesn’t see it and because it is a required field it is impossible to go forward with a test.

I have tried all kind of things with selenium and js like:

action.keyDown(Keys.CONTROL).sendKeys("770").keyUp(Keys.CONTROL).perform();
$("#test_borrowValue").val(45).trigger("keydown", {which: 103});

The only thing that does work is java Robot framework or Windows api. But of course it doesn’t work reliably.
Since during test nothing else could be opened, window has to be on top.
Anybody who will click anywhere on the screen in wrong moment could break the test. And in Jenkins it fails all the time.

Here is how html input looks like:

`<input  id="test_borrowValue" inputNumber class="form-control require-input" formControlName="borrowValue"
[ngClass]="{requireInputError : !form.controls.borrowValue.valid && form.controls.borrowValue.touched}"/>`

And here angular 2 directive:

import { Directive, ElementRef, HostListener ,OnInit} from '@angular/core';
@Directive({
selector: '[inputNumber]'
})
export class InputNumberDtv implements OnInit {
private el:HTMLElement;
constructor(el:ElementRef) {
this.el = el.nativeElement;
}
ngOnInit():any {
this.onBlur();
}
@HostListener('keydown', ['$event']) onKeyDown(event:KeyboardEvent) {
var isNumberRegex = /^\d$/;
if (!isNumberRegex.test(event.key) && !this.permittedKeyCodes(event)) {
event.preventDefault();
}
}
@HostListener('focus') onFocus() {
$(this.el).val($(this.el).val().replace(/,/g, ""));
}
@HostListener('blur') onBlur() {
$(this.el).val($(this.el).val().replace(/\B(?=(\d{3})+(?!\d))/g, ","));
}
private permittedKeyCodes(event:KeyboardEvent) {
return event.keyCode === 46 /* Delete */
|| event.keyCode === 8 /* Backspace */
|| event.keyCode === 37 /* Arrow Left */
|| event.keyCode === 38 /* Arrow Up */
|| event.keyCode === 39 /* Arrow Right */
|| event.keyCode === 40 /* Arrow Down */
|| event.keyCode === 9 /* Tab */
|| event.keyCode === 18; /* Alt */
}
}

If I comment @HostListener block, sendKeys() method starting to work as it should. But of course we need that validation and formatting.

Looking for suggestions from selenium, js(test side) and angular 2 (development side) solutions.