Stencil version:
@stencil/[email protected]
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:
Functions passed via a property are not executed when running the E2E tests.
Expected behavior:
Functions should be executed when running the E2E tests.
Steps to reproduce:
See code below (or https://github.com/Coenego/e2etest/tree/master/src/callback-test)
Related code:
import { E2EElement, E2EPage, newE2EPage} from '@stencil/core/testing';
describe('the component should', () => {
let page: E2EPage;
let elm: E2EElement;
beforeEach(async () => {
page = await newE2EPage({ html: `<callback-test></callback-test>`});
elm = await page.find('callback-test');
});
it('execute the callback function', async () => {
// The callback function below will not be executed
await elm.setProperty('clickHandler', () => { console.log('CALLBACK'); });
await page.waitForChanges();
const HTMLButton = await page.find('callback-test >>> .button');
await HTMLButton.click();
});
});
import { Component, Prop } from '@stencil/core';
@Component({
tag: 'callback-test',
shadow: true
})
export class CallbackTest {
@Prop() clickHandler: Function = undefined;
private _clickHandler(): void {
console.log('do something interesting before invoking the callback');
// Invoke the callback function
if (this.clickHandler !== undefined) {
// Although passed in as a property, `this.clickHandler` will still be `undefined`
this.clickHandler();
}
}
render() {
return (
<button class="button" onClick={this._clickHandler}>Button</button>
);
}
}
Other information:
It does work in browser. Only fails when running the E2E tests.
@adamdbradley Cloning https://github.com/ionic-team/stencil/issues/1168 as adding await page.waitForChanges does not fix the issue.
Maybe you have to define the function within the browser context and pass the name of the function instead? Cause without JSX you can't just inline a function into a DOM element's attribute, afaik?
@simonhaenisch , you can not, and that's pitty, because you cannot check if property is handled correctly on initialisation. But still, setProperty method on E2EElement should accept function, as it is accepting objects, ie. an array. My components accept mainly callback functions and I am not using custom events. In my case those E2E tests are almost useless, while I can't perform the final action, which is item selection, recognised by callback invocation.
Guys, before use function in browsers context it should be exposed, working example:
it("click should return option", async () => {
const page = await newE2EPage();
const mockCallBack = jest.fn();
const optionToReturn = "ClickedOption";
await page.setContent(
`<list-option option='${optionToReturn}'></list-option>`
);
await page.exposeFunction("functionToInject", mockCallBack); // EXPOSE
const element = await page.find("list-option");
await page.$eval("list-option", (elm: any) => {
elm.onOptionSelected = this.functionToInject; // USE
});
await page.waitForChanges();
await element.click();
expect(mockCallBack.mock.calls.length).toEqual(1);
expect(mockCallBack.mock.calls[0][0]).toBe(optionToReturn);
});
class:
export class ListOption {
@Prop() option: string;
@Prop() onOptionSelected: (option: string) => void;
private onOptionSelectedHandler = (option: string) => {
if (this.onOptionSelected) {
this.onOptionSelected(option);
}
};
render() {
return (
<div
class="listOption"
onClick={() => this.onOptionSelectedHandler(this.option)}
>
<slot />
</div>
);
}
}
versions:
"@types/jest": "23.3.14",
"@types/puppeteer": "1.11.1",
"jest": "23.6.0",
"jest-cli": "23.6.0",
"puppeteer": "1.11.0",
Hi all.
First of all thanks to @KEMBL for the solution proposed.
In addition, @adamdbradley what do you think about adding this recipe to Stencil docs inside the testing section?
I know this is more like a Puppeteer recipe, but I think it would be useful nonetheless.
With version 1.4 you can now pass JSX for tests, afaik (haven鈥檛 tried using it yet).
Hello everyone!
Sorry for bothering an old thread but I am trying to find a solution on particular problem and this issue constantly pops up in google results.
I have TS issue with my version of line that is similar to one's from @KEMBL's example (https://github.com/ionic-team/stencil/issues/1174#issuecomment-471335279)
elm.onOptionSelected = this.functionToInject; // USE
tsc says _object is possibly undefined_ and points to this. Does anyone knows any good solution for this? (except ts-ignore)?
Most helpful comment
Guys, before use function in browsers context it should be exposed, working example:
class:
versions: