Giter VIP home page Giter VIP logo

Comments (11)

christian-bromann avatar christian-bromann commented on September 26, 2024 1

@nioe yes, I will make sure to run your reproduction case as well.

from stencil.

nioe avatar nioe commented on September 26, 2024 1

Hi @christian-bromann

Thanks for your investigation and your answer.
As we did not customize the behaviour we came up with a solution that works for us:

We extended the E2EPage object and added a new function called findComponent. It's similar to the original find function but it waits for the given selector to have the hydrated class.

Like this, the changes in our tests are rather small and it seems to work for us in all scenarios.

from stencil.

christian-bromann avatar christian-bromann commented on September 26, 2024

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 v4.12.1. At the time where I worked on the PR I didn't recognised this would cause an issue like this.

from stencil.

nioe avatar nioe commented on September 26, 2024

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.
It's ok for me to close my issue, as long as both problems get solved eventually.

from stencil.

nioe avatar nioe commented on September 26, 2024

Thanks a lot for your effort @christian-bromann.

from stencil.

christian-bromann avatar christian-bromann commented on September 26, 2024

@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:

  1. delay test execution after you set the content until the global script is done, e.g.
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 `);
  1. keep your global script synchronous and run the asynchronous part in an extra function:
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.

from stencil.

nioe avatar nioe commented on September 26, 2024

Hi @christian-bromann

Thank you for the detailed answer.
Both solutions seem kind of hacky to me.

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?

from stencil.

christian-bromann avatar christian-bromann commented on September 26, 2024

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 asyncGlobalScript function without awaiting it.

from stencil.

nioe avatar nioe commented on September 26, 2024

Hi @christian-bromann

Since the components add hydrated to its class list once they are completely loaded, you could at least provide a helper method on the E2EPage:

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?

from stencil.

christian-bromann avatar christian-bromann commented on September 26, 2024

@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.

from stencil.

christian-bromann avatar christian-bromann commented on September 26, 2024

@nioe unfortunately this can't be build into Stencil because it is not guaranteed that the element is hydrated with a .hydrated class as the user can customize this behavior. I will raise a PR in the docs to better document this.

from stencil.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.