Testing SSR in SPA projects #143
Replies: 5 comments 1 reply
-
Thanks for starting this discussion! I also had the same idea of taking a DOM snapshot. I suspect that slotted components may not be complete, or there may be other differences we can use. |
Beta Was this translation helpful? Give feedback.
-
I wonder if there's a way of making Playwright to load the page and not run any JS, so the DOM snapshot is faithful to what we expect. Maybe we might not even need Playwright for that. |
Beta Was this translation helpful? Give feedback.
-
@xander-marjoram @fernandofranca thanks both, I agree! For interest, here is an example page source fragment both when SSR has failed and succeeded in NextJS: Failing: <pie-input class="form-field" id="username" data-test-id="username"></pie-input> Successful: <pie-input class="form-field" id="username" data-test-id="username" defer-hydration="" type="text">
<template shadowroot="open" shadowrootmode="open" shadowrootdelegatesfocus="">
<style>*,*:after,*:before{box-sizing:inherit}.c-input{--input-padding-block: var(--dt-spacing-c);--input-padding-inline: var(--dt-spacing-d);--input-gap: var(--dt-spacing-d);--input-text-color: var(--dt-color-content-default);--input-text-color-leading-trailing-content: var(--dt-color-content-default);--input-text-color-placeholder: var(--dt-color-content-subdued);--input-border-color: var(--dt-color-interactive-form);--input-container-color: var(--dt-color-container-default);--input-radius: var(--dt-radius-rounded-c);--input-font-size: var(--dt-font-body-l-size);--input-height: 48px;--input-cursor: text;--icon-display-override: block;--icon-size-override: 24px;height:var(--input-height);border:1px solid var(--input-border-color);border-radius:var(--input-radius);padding-inline-start:var(--input-padding-inline);padding-inline-end:var(--input-padding-inline);padding-block-start:var(--input-padding-block);padding-block-end:var(--input-padding-block);line-height:24px;font-size:var(--input-font-size);display:flex;flex-wrap:nowrap;align-items:center;background-color:var(--input-container-color);color:var(--input-text-color-leading-trailing-content);cursor:var(--input-cursor)}.c-input[data-pie-size=large]{--input-padding-block: var(--dt-spacing-d);--input-height: 56px}.c-input[data-pie-size=small]{--input-padding-block: var(--dt-spacing-b);--input-height: 40px}.c-input[data-pie-status=error]{--input-border-color: var(--dt-color-support-error)}.c-input ::slotted([slot=leading]){margin-inline-end:var(--input-gap)}.c-input ::slotted([slot=trailing]){margin-inline-start:var(--input-gap)}@supports (gap: var(--input-gap)){.c-input{gap:var(--input-gap)}.c-input ::slotted([slot=leading]){margin-inline-end:0}.c-input ::slotted([slot=trailing]){margin-inline-start:0}}@media (hover: hover){.c-input:hover{--input-container-color: hsl(var(--dt-color-container-default-h), var(--dt-color-container-default-s), calc(var(--dt-color-container-default-l) + calc(-1 * var(--dt-color-hover-01))))}}.c-input[data-pie-readonly]{--input-container-color: var(--dt-color-disabled-01);--input-border-color: var(--dt-color-border-inverse)}.c-input[data-pie-disabled][data-pie-readonly],.c-input[data-pie-disabled]{--input-container-color: var(--dt-color-disabled-01);--input-border-color: var(--dt-color-disabled-01);--input-text-color: var(--dt-color-content-disabled);--input-text-color-placeholder: var(--dt-color-content-disabled);--input-text-color-leading-trailing-content: var(--dt-color-content-disabled);--input-cursor: auto}.c-input:focus-within{box-shadow:0 0 0 2px var(--dt-color-focus-inner),0 0 0 4px var(--dt-color-focus-outer);outline:none}input{border:0;outline:0;height:24px;padding:0;color:var(--input-text-color);width:100%;font-size:var(--input-font-size);font-family:inherit;background:none;cursor:inherit;-webkit-appearance:none;-moz-appearance:none;appearance:none}input::placeholder{color:var(--input-text-color-placeholder)}input:disabled{-webkit-text-fill-color:var(--input-text-color);color:var(--input-text-color);-webkit-opacity:1;opacity:1}input[type=number]:not([step])::-webkit-inner-spin-button,input[type=number]:not([step])::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}input[type=number]:not([step]){-moz-appearance:textfield}
</style><!--lit-part P+mWmIP730w=-->
<!--lit-node 0-->
<div
class="c-input"
data-test-id="pie-input-shell"
data-pie-size="medium">
<slot name="leading"></slot>
<!--lit-node 2--><input
type="text"
value=""
name="username"
data-test-id="pie-input">
<slot name="trailing"></slot>
</div>
<!--lit-part--><!--/lit-part--><?><!--/lit-part-->
</template>
</pie-input> |
Beta Was this translation helpful? Give feedback.
-
Just to add my 2 cents, I feel that snapshot testing would be best for this scenario as it would provide a much faster feedback loop for if the dom is/isn't hydrated. It would potentially take way too long to get a percy snapshot fed back to you before running everything else so my personal preference would be a DOM snapshot test. |
Beta Was this translation helpful? Give feedback.
-
Just doing a quick search – would passing an option like this to Playwright work, so that we're testing how the page renders with JS disabled? (Not sure if doing this mitigates your concerns @JoshuaNg2332 or not though) |
Beta Was this translation helpful? Give feedback.
-
Currently, we do not have a way of verifying that our components are working with SSR. At the time of writing this, SSR in the NextJS does not work, however it does in Nuxt.
We already to visual regression tests, however these occur after the client hydrates.
I would like to use this discussion for us to propose ideas on how to automate SSR testing rather than relying on manual checks.
For example, could it be possible to perform a dom snapshot or visual test before the page hydrates?
All ideas welcome, thanks in advance! 🎉
Beta Was this translation helpful? Give feedback.
All reactions