I'm working on getting some acceptance tests to work with Capybara. The main parts of the application leverage Polymer. There are some key parts of the application that require the test to wait for the Polymer library and the application code to load. Is there a Polymer centric way to wait for Polymer and the application to load. I currently am using sleep statements, but this is really bloating the test run times.
I think you should listen to the WebComponentsReady event, it's fired when all the Polymer elements are loaded.
https://github.com/webcomponents/webcomponentsjs#webcomponentsready
It appears that polymers FOUC prevention uses an 'unresolved' attribute on the body, that gets removed once polymer has finished initializing the elements. If you have put that attribute on the body then
expect(page).not_to have_selector('body[unresolved]')
would wait for polymer to finish loading
Another way would be to add a listener for the WebComponentsReady event to your code that sets a data-attribute on the body element when fired and then have Capybara find for the body with that attribute.
Related
I'm building a component that uses an <iframe> to display another component. This component connects to an NGXS state which needs to reflect changes made to the state. After a lot of failures and testing I discovered the component will always only load the default settings of the state. I created a <button> to toggle a boolean and added an *ngIf to the <iframe> so I can force it to reload manually after trying things like this.Frame.(contentDocument || contentWindow).location.reload(true); didn't make any difference.
I created a stablitz app to demonstrate this issue however I think stackblitz blocks the use of <iframe>s in their platform so you might need to copy it into a local project to tinker with it. It's a simple app that shows the state outside of the <iframe> as well as inside with a button that toggles the <iframe> on and off so you can see how only the default values load after you update the value I have available for demonstration purposes. I'm not getting any type of errors and the issue isn't a matter of something being wrong with the code so I don't know what more to show that isn't in the stackblitz.
Does anybody know why and how <iframe>s do this and if there's a way around it? The only thing I can think to try is make a NestJS app to see if putting the data outside the app and making an API request from the component inside the <iframe> will be allowed, however I don't know why this issue is occurring to in turn know if that too won't be rejected for that same reason. How this can be handled?
The document running in an iframe is isolated from its host. They do not share memory- Angular does not provide a way to synchronize state between a host and an iframe on the page out of the box. The example is actually booting two Angular apps (one inside the frame and one outside). If you are using an iframe for security and isolation purposes, you'll need to devise a way to pass state between the host and the child via postMessage (and be aware that you are running two copies of your application). If this isn't for security/isolation, simply do not use an iframe to contain the child component.
My WordPress site got some violations.
[Violation] Added non-passive event listener to a scroll-blocking 'touchstart' event. Consider marking event handler as 'passive' to make the page more responsive.
[Violation] 'DOMContentLoaded' handler took 55ms
[Violation] Forced reflow while executing JavaScript took 52ms
Theme Ari version 1.2
If you can access or modify your code, just use highly flexible and configurable passive-events-support package to debug and make event listeners passive without touching 3rd party source code.
See this answer on similar issue:
https://stackoverflow.com/a/70811715/2333299
For me, this package fixed all the warnings cause by materialize and jquery. Hope it helps you too.
I have a SPA say https://www.example.com. And one of the sub-pages https://www.example.com/foo can be added as a PWA. On navigating to /foo from the homepage, the manifest and service-worker get installed and registered correctly and the PWA can be installed from the A2HS native buttons too, but the event beforeinstallprompt isn't called on chrome. If the page /foo is refreshed then the event is called. It's only when the navigation happens to it from another page that isn't in the scope of the PWA. The lighthouse audit passes all tests on /foo as well.
Has anyone tried creating multiple PWAs on a SPA, or encountered a similar issue?
I don't think this is a good solution, but this is how I got around it on my Gatsby.js site:
On every page (even those where I don't have the "Add to Homepage" custom trigger), I listen for the beforeinstallprompt event.
I set up a listener for a custom event on the <html> element on the pages that have my "Add to Homepage" custom trigger.
When beforeinstallprompt fires, I stash a reference to the event on the <html> tag (this does not get swapped out in between pages for my SPA) using jQuery's $.data() - I couldn't get vanilla JavaScript dataset to work but I may have been using it wrong, and I had jQuery loaded in anyway.
In the beforeinstallprompt handler, after setting the data, I fire the custom event on the <html> element.
The page that has the "Add to Homepage" custom trigger catches this custom event, grabs the reference to the beforeinstallprompt event from the $( 'html ').data( 'event' ) and carries on with it as normal.
Hopefully that helps; it feels pretty hacky but I'm pretty new to PWAs / SPAs / React!
Consider this Plunker minimal example code.
<dom-module id="my-element">
...
<button onclick="dialog.open()">What is Confucianism ?</button>
<paper-dialog id="dialog" modal>
<h2>Confucianism</h2>
<p>...</p>
</paper-dialog>
...
</dom-module>
won't work.
I am using Polymer v2.0. When I click on the button dialog.open() fails and says dialog is undefined.
In previous version of Polymer, this code worked but now that I have upgraded my code, I have to clear this issue everywhere I'm using paper-dialog elements. My current solution is to add a on-click attribute on all the buttons in my code and manually write a tied function and execute this.$.<dialogID>.open(); but I don't understand why I have to do that, and it appears to be like an issue to me because I write more tedious code, and this afterward compatibility seems more like a disadvantage to the new version.
Am I really doing something wrong ?
this approach is really bad. You should always call a function that will open dialog. Plus, you should use polymer event handlers. on-tap for example.
And why is your code no longer works? well it depends on if you are using shadow dom. Because in shadow DOM, there are shadowRoots which are, let's say closed, so window object no longer have elements with IDs saved as properties.
Normally, it works because whenever you define element with some ID, this element is saved inside window object and that's why you can do <someID>.<someFunction>.
You should definitely rewrite your app so it's using polymer event handler functions.
EDIT:
Consider this Feature Request #4647 for a future reliable solution.
I could probably go benchmark this myself but I'm not 100% sure how to go about it so I'm asking here to see if anyone knows the answer to the problem already.
I have some webpage, it has a load of content on it and say, an ad in its own iframe. The ad has some html which then includes some more resources. The html for the ad and all resources it requires are served from a separate domain to the parent page.
What parts of the iframe will delay the onload event of the parent page firing? Also, if different, what parts of the iframe need to load for tracking like Google Analytics to decide the parent page has finished loading?
The onload event isn't guarenteed to fire after all of the DOM has been loaded.
Quite often you'll find the onload event firing way before the DOM has fully loaded, as many a Javascript developer can tell you.
I'd summise from this that your iframe will have little, if any, effect on the onload event firing.