Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

spyOnEvent has wrong event.detail data if a custom event emits a Map or a dom element. #1841

Open
pr3tori4n opened this issue Aug 29, 2019 · 6 comments
Labels
Resolution: Needs Investigation This PR or Issue should be investigated from the Stencil team

Comments

@pr3tori4n
Copy link

Stencil version:

@stencil/core@1.3.2

I'm submitting a:

[x] bug report
[ ] feature request
[ ] support request => Please do not submit support requests here, use one of these channels: https://stencil-worldwide.herokuapp.com/ or https://forum.ionicframework.com/

Current behavior:
when using page.spyOnEvent() to spy on a custom stencil emitted event, if data was passed from the event, the spy's event.detail is incorrect.

Expected behavior:
When validating the event.detail from the spys event object, the data should match what the component passes.

Steps to reproduce:

  1. Create a component that emits a custom event when something is clicked on. Have that custom event either pass a reference to a dom element, or a javascript Map.
  2. Setup an e2e test that triggers a click on that element, and spys on that event using e2eElement.spyOnEvent()
  3. try and run an expect on that event's details, such as expect(spy.lastEvent.detail).toBe or toHaveReceivedEventDetail.
  4. Notice that the event detail data is incorrect if it's not a primitive data type.

Related code:

// component
const bar = document.querySelector('foo-element');
const selectedValues = new Map('foo', bar);
this.fooEvent.emit(selectedValues);
// e2e test
const toggleSpy = await picker.spyOnEvent("fooEvent");
await something.click();
expect(toggleSpy.lastEvent.detail.has('foo').toBe(true);

Other information:

spyOnEvent(eventName: string, selector?: 'window' | 'document'): Promise<d.EventSpy>;

@ionitron-bot ionitron-bot bot added the triage label Aug 29, 2019
@manucorporat
Copy link
Contributor

it's not trivial to move complex objects from browser to node, notice that the tests ar running in node, but your app is running in the browser using puppeteer.

@pr3tori4n
Copy link
Author

@manucorporat That's fair. I've been able to achieve some goals relying on page.waitForEvent() and page.evaluate(). It might be worth documenting this limitation and pointing folks to possible solutions.

@pr3tori4n
Copy link
Author

Maybe spyOnEvent could be amended to accept a callback function that uses page.evaluate under the hood? That way a user can perform operations on an object in the page scope, then pass that back to node for assertion.

@TRMW
Copy link

TRMW commented Feb 19, 2021

I am also encountering this issue. I agree that it would be nice to at least document this behavior.

FWIW, I am seeing the value "s-p": Array [] for all DOM node and array values contained in an event detail.

@rdlabo
Copy link

rdlabo commented Mar 10, 2021

me too. I use evaluateHandle instead of spyOnEvent . But can't get event.detail data.

const result = page.evaluateHandle( () => {
  return new Promise(resolve => {
    const inputfield = document.querySelector('blf-inputfield');
    inputfield.addEventListener('blfInput', (event) => {
      resolve(event)
    });
  })
});await page.waitForChanges();
result.then(d => d.jsonValue().then(s => console.log(s)));

@pr3tori4n Can I get sample code if you have a solution?

@Trendy
Copy link

Trendy commented May 27, 2021

This bug seems to be affecting me as well, but in a different way.

I have a component that emits a custom event, let's call it tabAcitivated.
That event has an element in the event details.

this.tabAcitived.emit({ index, tab});

My test is like so:

//...
const tabs = await page.find('tab-bar');
const activatedEvent = await tabs.spyOnEvent('tabActivated');

await tabs.callMethod('activateTab', 0);
await page.waitForChanges();

expect(activatedEvent).toHaveReceivedEventTimes(1);

My test will fail, saying the event was never received. Removing the DOM element from the event details allows the tests to pass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: Needs Investigation This PR or Issue should be investigated from the Stencil team
Projects
None yet
Development

No branches or pull requests

7 participants