Reputation: 3671
I have a StencilJS component with an Event defined as:
@Event({eventName: 'focusEvent'}) focusEvent: EventEmitter<any>;
And the component looks like this:
<input type='text'
...
onFocus={ (evt) => this.focusEvent.emit(evt)}>
</input>
My test is as follows:
const mockEvent = jest.fn();
const page = await newE2EPage();
await page.setContent(`<my-textbox focusEvent=${mockEvent}></my-textbox>`);
await page.waitForSelector('input');
const el = await page.find('input');
expect(el).not.toBeNull(); // <-- this passes
const spy = el.spyOnEvent("focusEvent");
await el.focus();
expect(spy).toHaveBeenCalled(); // <-- this fails
The error is:
Matcher error: received value must be a mock or spy function
Received has type: object
Received has value: {}
If I put the component in a test application and run it, I can see that the focus event fires when I click into the text box, but I can't figure out how to reproduce that in a test.
Upvotes: 2
Views: 3744
Reputation: 1914
Try the following:
const page = await newE2EPage();
await page.setContent(`<my-textbox></my-textbox>`); // removed the focusEvent={...}
const input = await page.find('input') // removed the waitForSelector + find, just find works
expect(input).not.toBeNull(); // <-- this passes
const focusEventSpy = await page.spyOnEvent('focusEvent');
await input.focus();
await page.waitForChanges(); // introduced the wait for changes
expect(focusEventSpy).toHaveReceivedEvent(); // <-- this now passes
Key points:
waitForChanges
, from stenciljs docs:Both Stencil and Puppeteer have an asynchronous architecture, which is a good thing for performance. Since all calls are async, it's required that await page.waitForChanges() is called when changes are made to components.
Upvotes: 3