0

I want to test an input element on "keydown" event and wrote the below case.

it('should accept input', fakeAsync(() => {
    let inputSelector = fixture.debugElement.query(By.css('input')).nativeElement;
    expect(inputSelector.value).toBe('', 'value not empty at start');
    fixture.detectChanges();
    tick();

    const event = new KeyboardEvent("keydown", {
      key: "a",
      code: "KeyA"
    });
    inputSelector.dispatchEvent(event);
    tick();
    expect(inputSelector.value).toBe('a', 'value empty after some alphabet keypress');

    const eventNum = new KeyboardEvent("keydown", {
      key: "1",
      code: "Digit1"
    });
    inputSelector.dispatchEvent(eventNum);
    tick();
    expect(inputSelector.value).toBe('1', 'value empty after some number keypress');

  }));

But the value of inputSelector always remains empty. I am not sure what am I doing incorrect and what I should do instead.

Ayush Goyal
  • 57
  • 1
  • 10
  • According to [this](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent) - `manually firing a key event does not cause that letter to appear in a focused text input`, but your code triggers component handlers, for example, `(keydown)="doSomething($event)"` – Aleksandr Petrovskij Aug 21 '17 at 16:19
  • So how should I do the test instead? Is there a corresponding method I can call which would get triggered after KeyboardEvent and put the value in the input? – Ayush Goyal Aug 22 '17 at 06:02

1 Answers1

0

You should be able to do the same as in this answer: https://stackoverflow.com/a/54042368/6835260

describe('NumberComponent', () => {
    let component: NumberComponent;
    let fixture: ComponentFixture<NumberComponent>;

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            declarations: [NumberComponent, NumberOnlyDirective],
            imports: [FormsModule]
        })
            .compileComponents();
    }));

    beforeEach(async(() => {
        fixture = TestBed.createComponent(NumberComponent);
        component = fixture.componentInstance;

        fixture.detectChanges();
    }));

    it('should prohibit non-numeric input', () => {
        let numberDebug = fixture.debugElement.query(By.css('.number-input'));
        let numberInput = numberDebug.nativeElement as HTMLInputElement;

        fakeTyping('12abc34de', numberInput);

        expect(numberInput.value).toBe('1234');
    });

    function fakeTyping(value: string, inputEl: HTMLInputElement) {
        let result: string = '';
        for (let char of value) {
            let eventMock = createKeyDownEvent(char);
            inputEl.dispatchEvent(eventMock);
            if (eventMock.defaultPrevented) {
                // invalid char
            } else {
                result = result.concat(char);
            }
        }

        inputEl.value = result;
        inputEl.dispatchEvent(new Event('input'));
        fixture.detectChanges();
    }
});
Tucaen
  • 91
  • 1
  • 9