Karma test paste event
Asked Answered
E

3

9

I have a simple component that handle paste event into a form input.

The form:

this.searchForm = this.formBuilder.group({
  query: [ null, [Validators.required] ]
});

onPaste(event) {
    event.preventDefault();
    const formattedQuery = event.clipboardData.getData('text/plain')
      .split(/,?[\r\n\t]+\s?/)
      .join(', ')
      .replace(/,\s?$/g, '');

    this.searchForm.get('query').setValue(formattedQuery);
  }

Now I am trying to test that and it looks like this:

it('should reformat pasted data', () => {
    const queryField = fixture.debugElement.query(By.css('input[type="search"]'));
    queryField.nativeElement.dispatchEvent(new ClipboardEvent('paste', {
      dataType: 'text/plain', 
      data: '123\r123'
    }));
    fixture.detectChanges();
    expect(queryField.nativeElement.value).toBe('123, 123');
    // also tried expect(component.searchForm.get('query').value).toBe('123, 123');
  });

But as a result i've got

Expected '' to be '123, 123'

If i do console.log(queryField.nativeElement) it shows the input, but why it doesn't handle new ClipboardEvent('paste') event?

<input class="ng-untouched ng-pristine ng-invalid" formcontrolname="query" type="search" ng-reflect-name="query">

Full component you can find here https://stackblitz.com/edit/angular-cp9yhx?file=app%2Fhello.component.ts

What's wrong with my unit test?

Eldoria answered 8/12, 2017 at 13:46 Comment(6)
Did you try it without fixture.detectChanges() ?Lycurgus
i did. same result (Eldoria
Where does value 325435956, 325435956 come from? Did you set it somewhere before the test? Like, in beforeEach?Lycurgus
oops, i am sorry, i tried different numbers. let's assume it's '123, 123'Eldoria
try calling onPaste directly. So instead of dispatching the event on the element queryField.nativeElement.dispatchEvent.... try calling onPaste( new ClipboardEvent(.... and see if it helps.Lycurgus
TypeError: queryField.nativeElement.onPaste is not a function and TypeError: queryField.onPaste is not a functionEldoria
L
3

Try this:

it('should reformat pasted data', () => {
  component.onPaste(new ClipboardEvent('paste', {
    dataType: 'text/plain', 
    data: '123\r123'
  }));
  expect(queryField.nativeElement.value).toBe('123, 123');
});

Or even

it('should reformat pasted data', () => {
  component.onPaste(new ClipboardEvent('paste', {
    dataType: 'text/plain', 
    data: '123\r123'
  }));
  expect(component.searchForm.get('query').value).toBe('123, 123');
});
Lycurgus answered 8/12, 2017 at 14:22 Comment(1)
i am sorry, but i've got the same result Expected '' to be '123, 123'. i've copy pasted your both examples without any changesEldoria
S
3

This worked for me:

it('should trim pasted data', () => {
  const initialValue = 'test ';
  fixture.detectChanges();

  // Setting initial value
  const el = inputElement.nativeElement;
  el.value = initialValue;

  // Setting up event data
  const pasteData = new DataTransfer();
  pasteData.setData('text', initialValue);

  // Creating event
  const pasteEvent = new ClipboardEvent('paste', {
    clipboardData: 'new value'  <- CHANGED
  } as any);


  // Dispatching event    
  el.dispatchEvent(pasteEvent);

  expect(el.value).toEqual('new value'); <- CHANGED
});
Sacred answered 22/8, 2019 at 9:3 Comment(3)
no, it just looks like it works because of el.value = initialValue;Operator
Thank you @ed4becky. How stupid of me. I updated the answer.Sacred
what's the use of pasteData?Satinwood
L
0

This is the easiest solution I found to mock a paste event and test how the component handles it:

// Creating a mock of the paste event with the data I need returned
const pasteEvent = { clipboardData: { getData: () => "541236"}};
// Select the component from the template
const comp = fixture.debugElement.query(By.directive(MyComponent));
// Call triggerEventHandler on the component
comp.triggerEventHandler('paste', pasteEvent);
// Detect changes to ensure everything is in the right state 
// before running assertions
fixture.detectChanges();
Leviathan answered 11/9, 2024 at 22:24 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.