Skip to content
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

Unreliable font loading causes difference between test and reference #1564

Open
giorgiosironi opened this issue Apr 8, 2024 · 4 comments
Open

Comments

@giorgiosironi
Copy link

We are experiencing intermittent test failures due to font not loading for some scenarios.

Using BackstopJS 6.2.2, running in Docker with:

"dockerCommandTemplate": "docker run --rm -i --user $(id -u):$(id -g) --network sciety-test_default --mount type=bind,source=\"{cwd}\",target=/src backstopjs/backstopjs:{version} {backstopCommand} {args}",

Examples:
failed_diff_backstop_default_Sciety_feed_0_main_2_desktop
backstop_default_Sciety_feed_0_main_2_desktop_2
backstop_default_Sciety_feed_0_main_2_desktop

Researching previous issues lead us to code to wait for font loading:
#1298 (comment)
#1303 (comment)
but due to the age of these issues we don't know how to implement this in onReady with the Puppeteer API, can anyone advise?

@weseze
Copy link

weseze commented Apr 18, 2024

We are also experiencing this issue on 100+ websites with large testscanario's.
We are testing local websites vs production websites to find visual regressions between updates.

Anything from 50-95% of tests fail. The fails are random. Every time we run the tests, the result is different.

These tests used to run fine until we updated our entire npm stack. Mainly because the chromium we were using didn't support modern CSS (things like grid) and those tests failed.

Tried almost every suggestion I could find here in this issue and related issues. Nothing has worked so far.

1/
Tried reverting to older version of backstopJS (mainly 5.0/5.1): this didn't work because of a dependency hell on old libraries that I couldn't get resolved. I was able to install a 5.2 release, but that didn't help.

2/
Tried updating everything to latest versions, remaking our backstop configs from the latest versions examples: did not work

3/
Tried adding JS to check if fonts are fully loaded before creating the screenshots: did not work

4/
Added delays up to 10 seconds before taking the screenshots: did not work

5/
Limit the async capture limit to 1: did not work

6/
Tried al sort of CSS injections for font smoothing, kerning, aliasing: nothing worked. Fonts just started looking ugly, but still the same small differences

7/
Tried to use 2 testscenario's with only the testUrl, not the referenceUrl and comparing those: did not work

I have run out of things to try...
As of right now, backstopJS testing has become unusable for us and we are investigating other methods.
Any help to get it working again would be greatly appreciated, because switching our entire testsuite to a new system is a big project...

dgrebb added a commit to dgrebb/BackstopJS that referenced this issue Apr 30, 2024
@giorgiosironi
Copy link
Author

For reference, we tried (from dgrebb@bf413fb):

await page.waitForFunction(() => document.fonts.ready);

added to onReady. Still see intermittent failures of the same kind.

@dgrebb
Copy link
Contributor

dgrebb commented May 4, 2024

Thanks @giorgiosironi - this adds the same into the runner itself, and I've seen some very minimal improvements.

Out of curiosity, and it sounds like the answer is no, could this be a CSP issue? The fonts are there sometimes but not always, correct?

@randombitsUK
Copy link

I experienced font intermittent issues a few years ago. It was very frustrating at the time. I resolved it by having the font files locally.

In onBefore.js I added a call to await require('./interceptFonts')(page, scenario);

interceptFonts.js contains:

const fs = require('fs');
const path = require('path');

const FONT_URL_RE = /fonts\/.../i;

module.exports = async function (page, scenario) {
    page.route(FONT_URL_RE, route => {
        const fontURL = route.request().url();
        const fontReference = fontURL.replace('https://{FONT_URL_PATTERN}/', '');
        const fontPath = path.resolve(__dirname, `../../fonts/${fontReference}`);

        if (!fs.existsSync(fontPath)) {
            console.log(`Download: ${fontURL} to ${fontPath}`)
        }

        route.fulfill({
            body: fs.readFileSync(fontPath),
            headers: {
                "content-type": "font/woff2",
                "accept-ranges": "bytes",
                "access-control-allow-credentials": false,
                "access-control-allow-headers": "*",
                "access-control-allow-methods": "HEAD,GET",
                "access-control-allow-origin": "*",
                "access-control-max-age": 300,
                "cache-control": "public, max-age=31536000, immutable",
                "timing-allow-origin": "https://www.{AAA}.co.uk, https://www.{AAA}.com",
            },
            status: 200
        });
    });
};

So basically I look for font related URL requests and then highlight the fonts that need to be downloaded. I am manually downloading them but yo could automate this.

This resolved any font inconsistencies that I experienced.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants