Search code examples
puppeteere2e-testingalpine-linuxgoogle-chrome-headlessstenciljs

Stencil's Puppeteer sometimes does not renders text or fonts


I'm trying to use Stencil e2e screenshot tests which have Puppeteer v10 under the hood.

I'm facing the problem with texts and fonts. Sometimes they are hidden and sometimes they appear as they should.

Screenshot diff

I'm using the following code for my tests:

const componentStatesTemplate = `
  <div style="display: flex; flex-direction: column;">
    <nl-button>Button</nl-button>
    <nl-button is-disabled>Button</nl-button>
    <nl-button is-full-width>button</nl-button>
    <nl-button><nl-icon-heart></nl-icon-heart></nl-button>
    <nl-button><nl-icon-heart></nl-icon-heart>Button</nl-button>
    <nl-button variant="secondary">Button</nl-button>
    <nl-button variant="secondary"><nl-icon-heart></nl-icon-heart></nl-button>
    <nl-button variant="secondary"><nl-icon-heart></nl-icon-heart>Button</nl-button>
  </div>
`;

describe("button component", () => {
  it("is rendered", async () => {
   const page = await newE2EPage();
   await page.setContent(html);

   await page.addStyleTag({
    content: `
      @font-face {
        font-family: "Source Sans 3";
        src: url("${getAssetPath("../assets/fonts/SourceSans3-VariableFont_wght.ttf")}");
        font-weight: 100 900;
      }

      body {
        -webkit-font-smoothing: antialiased;
      }
    `,
  });
    const results = await page.compareScreenshot();

    expect(results).toMatchScreenshot({allowableMismatchedPixels: E2EConstants.DEFAULT_allowableMismatchedPixels});
    expect(results).toMatchScreenshot({allowableMismatchedRatio: E2EConstants.DEFAULT_allowableMismatchedRatio});
  });
});

Environment:

  • I'm running tests in docker, using alpine linux with Chromium installed as described in Puppeteer docs.
  • I'm also applying --font-render-hinting=none flag as described in many articles on the subject.
  • Using waitForOptions.waitUntil set to networkidle0 or domcontentloaded did not help as well.

However, the text in my components is not shown stable. Sometimes tests run as supposed and sometimes the components are rendered as if text was hidden. How do I make them stable?


Solution

  • Adding await page.evaluateHandle("document.fonts.ready"); helped, now fonts load properly.

    Example:

    const page = await newE2EPage();
       await page.setContent(html);
    
       await page.addStyleTag({
        content: `
          @font-face {
            font-family: "Source Sans 3";
            src: url("${getAssetPath("../assets/fonts/SourceSans3-VariableFont_wght.ttf")}");
            font-weight: 100 900;
          }
    
          body {
            -webkit-font-smoothing: antialiased;
          }
        `,
      });
    
        // Inserting the wait before comparing elements
        await page.evaluateHandle("document.fonts.ready");
    
        const results = await page.compareScreenshot();