diff --git a/inc/functions.php b/inc/functions.php index 608aad0..6f910ac 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -85,21 +85,6 @@ function accelerate_scripts_styles_method() { 'file' => '/all', 'version' => '6.7.2', ), - array( - 'handle' => 'font-awesome-solid', - 'file' => '/solid', - 'version' => '6.7.2', - ), - array( - 'handle' => 'font-awesome-regular', - 'file' => '/regular', - 'version' => '6.7.2', - ), - array( - 'handle' => 'font-awesome-brands', - 'file' => '/brands', - 'version' => '6.7.2', - ), ); foreach ( $font_awesome_styles as $style ) { diff --git a/tests/e2e/specs/performance/font-awesome-single-bundle.spec.ts b/tests/e2e/specs/performance/font-awesome-single-bundle.spec.ts index adb1590..1cbf066 100644 --- a/tests/e2e/specs/performance/font-awesome-single-bundle.spec.ts +++ b/tests/e2e/specs/performance/font-awesome-single-bundle.spec.ts @@ -3,30 +3,54 @@ import { test, expect } from "@playwright/test"; /** * @area assets * @tier fresh - * @source accelerate-free-pro-senior-dev-audit.html#ACCELERATE-004 - * @why inc/functions.php:76-113 enqueues 5 overlapping Font Awesome - * stylesheets (v4-shims, all, solid, regular, brands) unconditionally - * on every page, even though `all.css` already contains solid+regular+ - * brands. Lighthouse measured this + Google Fonts as ~two-thirds of the - * homepage's byte weight. Only one `/fontawesome/css/*.css` request - * should be needed. + * @guards themegrill/accelerate-pro#83 ACCELERATE-004 + * @source accelerate-free-pro-senior-dev-audit.html#ACCELERATE-004; themegrill/flash#120 (same fix) + * @why inc/functions.php enqueued v4-shims, all, solid, regular and brands on + * every page, and `all` already contains every rule and @font-face of the + * other three. v4-shims stays: the theme's markup uses v4 class names + * (`fa fa-*`) that only the shim maps, so the target is two, not one. + * Asserts each of `all` and the shim is requested exactly once (minified + * or, with SCRIPT_DEBUG, not), and that a v4 solid, regular and brand icon + * still resolve to a loaded Font Awesome face. The probe icons are added to + * the page, so this does not depend on what content the site has. */ -// Quarantined: ACCELERATE-004 is not fixed yet. Drop `.fixme` in the PR that fixes it. -test.fixme("only one Font Awesome stylesheet loads per page @assets @performance @fresh", async ({ +test("Font Awesome loads only the full bundle and the v4 shim, and icons still render @assets @performance @fresh", async ({ page, }) => { - const fontAwesomeRequests: string[] = []; + const requested: string[] = []; page.on("request", (req) => { - if (/\/fontawesome\/css\//.test(req.url())) { - fontAwesomeRequests.push(req.url()); - } + const m = req.url().match(/\/fontawesome\/css\/([a-z0-9-]+?)(?:\.min)?\.css/); + if (m) requested.push(m[1]); }); await page.goto("/"); await page.waitForLoadState("networkidle"); + // An array, not a Set: the same file requested twice must fail too. + expect(requested.sort(), "Font Awesome stylesheets requested").toEqual(["all", "v4-shims"]); - expect( - fontAwesomeRequests.length, - `expected exactly 1 Font Awesome stylesheet request, got ${fontAwesomeRequests.length}: ${fontAwesomeRequests.join(", ")} (ACCELERATE-004)`, - ).toBe(1); + // One v4 class name per style the removed stylesheets used to cover. + const probes = { "fa-user": "Font Awesome 6 Free", "fa-calendar-o": "Font Awesome 6 Free", "fa-facebook": "Font Awesome 6 Brands" }; + for (const [icon, family] of Object.entries(probes)) { + const rendered = await page.evaluate(async (cls) => { + const el = document.createElement("i"); + el.className = `fa ${cls}`; + document.body.append(el); + const cs = getComputedStyle(el, "::before"); + const glyph = cs.content.replace(/^["']|["']$/g, ""); + // Read now: the computed style is live and empties once the element is removed. + const family = cs.fontFamily; + const font = `${cs.fontWeight} 16px ${family}`; + let faces: string[] = []; + try { + if (glyph && glyph !== "none") faces = (await document.fonts.load(font, glyph)).map((f) => f.family); + } catch { + faces = []; + } + el.remove(); + return { glyph, family, faces }; + }, icon); + expect(rendered.glyph, `${icon} has no glyph`).not.toMatch(/^(none)?$/); + expect(rendered.family, `${icon} font family`).toContain(family); + expect(rendered.faces.length, `${icon} glyph has no loaded font face`).toBeGreaterThan(0); + } });