-
Notifications
You must be signed in to change notification settings - Fork 798
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
bug: v4.12.2 breaks E2E tests #5526
Comments
Thanks @nioe for reporting the issue. I will close this as duplicate of #5457 And asked to add this issue into our next sprint for us to take a look. In the meantime please pin the stencil dependency to |
Thanks @christian-bromann for the quick reply. I came across the other issue but figured that even if it's possibly the same root cause, it's a different problem which needs to be addressed. |
@nioe yes, I will make sure to run your reproduction case as well. |
Thanks a lot for your effort @christian-bromann. |
@nioe sorry for the delayed response. I was able to find the root cause of this issue while understanding the details of similar issues reported to Stencil. In your reproduction case you have a global script that is being invoked when the application is loaded. This means that the component rendering is also delayed for the time being until the global script has finished. You can fix this problem using one of the following two options:
diff --git a/src/components/my-component/my-component.e2e.ts b/src/components/my-component/my-component.e2e.ts
index d7ff311..fd3545b 100644
--- a/src/components/my-component/my-component.e2e.ts
+++ b/src/components/my-component/my-component.e2e.ts
@@ -5,6 +5,7 @@ describe('my-component', () => {
const page = await newE2EPage();
await page.setContent('<my-component></my-component>');
+ await new Promise(resolve => setTimeout(resolve, 1100));
const element = await page.find('my-component');
expect(element).toHaveClass('hydrated');
});
@@ -13,6 +14,7 @@ describe('my-component', () => {
const page = await newE2EPage();
await page.setContent('<my-component></my-component>');
+ await new Promise(resolve => setTimeout(resolve, 1100));
const component = await page.find('my-component');
const element = await page.find('my-component >>> div');
expect(element.textContent).toEqual(`Hello, World! I'm `);
diff --git a/src/global/global-script.ts b/src/global/global-script.ts
index 05d71d8..f156bf8 100644
--- a/src/global/global-script.ts
+++ b/src/global/global-script.ts
@@ -1,9 +1,13 @@
-const globalScript = async (): Promise<void> => {
- console.log('Global script started');
+const asyncGlobalScript = async (): Promise<void> => {
return new Promise<void>(resolve => setTimeout(() => {
- console.log('Global script ended');
+ console.log('Async Global script ended');
resolve();
}, 1000));
+}
+
+const globalScript = async (): Promise<void> => {
+ console.log('Global script started');
+ asyncGlobalScript();
};
-export default globalScript;
\ No newline at end of file
+export default globalScript; I will check in with the team to see how we can be more explicit in our docs about this behavior. |
Thank you for the detailed answer. Since the E2E Testing approach is baked into Stencil and an async global script is clearly mentioned as a valid case, I would assume that the testing framework handels this case automatically. That said, our components do not function correctly as long as the async part of the global script has finished and waiting for an arbitrary amount of time in our tests will slow down our builds... Both solutions are therefore not really practical for us. Is there no way the the E2EPage could wait for the async global script to finish? |
Unfortunately not, once the file with the component source code is loaded, everything comes to an halt. I would strongly advise to use any global scripts with async procedures as these will also delay the rendering of the components in your application. Therefor I suggested to run an |
Since the components add const waitForComponentToBeReady = (selector: string) => this.waitForSelector(`${selector}.hydrated`); Like this it would be a rather simple change within our tests. After setting the page content we could call the wait function: const page = await newE2EPage();
await page.setContent(`<my-component></my-component>`);
await page.waitForComponentToBeReady('my-component');
// test logic What do you think? |
@nioe that seems a viable idea to look into. I raised a PR but need to investigate why some end-to-end tests are failing. |
@nioe unfortunately this can't be build into Stencil because it is not guaranteed that the element is hydrated with a |
Thanks for your investigation and your answer. We extended the E2EPage object and added a new function called Like this, the changes in our tests are rather small and it seems to work for us in all scenarios. |
Prerequisites
Stencil Version
4.12.2
Current Behavior
We use an async global script, which worked totally fine for us until we updated from v4.12.1 to v4.12.2. After the update, nearly all our E2E Tests started to fail. After some digging I stumbled upon this PR #5158. Seems that there was a bug which caused the initialization of the components not to wait for an async global script. Since this was fixed, I assume that our E2E tests try to access the components too early now, which results in errors like
Node is either not clickable or not an Element
orshadow root does not exist for element
because the components are not actually loaded yet.Expected Behavior
First, even the PR was marked as breaking. So personally, I do not understand why it was published as a bug-fix release...
IMHO the
await newE2EPage()
call should wait for the async global script too.System Info
Steps to Reproduce
npm init stencil@latest
stencil.config.ts
npm run test
shadow root does not exist for element: my-component
since the component is not yet readyCode Reproduction URL
https://github.com/nioe/stencil-e2e-bug
Additional Information
No response
The text was updated successfully, but these errors were encountered: