From 990d02cd71a97129ea4c05d469d7297809482e49 Mon Sep 17 00:00:00 2001 From: Lukas Date: Tue, 13 Oct 2026 14:10:55 +0300 Subject: [PATCH 1/2] [docs-infra] Preserve normal body font weight --- .../core-docs/src/nextFonts/index.ts | 7 +++- test/e2e-website/docs-fonts.spec.ts | 35 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 test/e2e-website/docs-fonts.spec.ts diff --git a/packages-internal/core-docs/src/nextFonts/index.ts b/packages-internal/core-docs/src/nextFonts/index.ts index 1767a848aacfb8..49c8af2791750b 100644 --- a/packages-internal/core-docs/src/nextFonts/index.ts +++ b/packages-internal/core-docs/src/nextFonts/index.ts @@ -16,6 +16,7 @@ export const roboto = Roboto({ export const generalSans = localFont({ declarations: [{ prop: 'font-family', value: 'General Sans' }], + variable: '--font-general-sans', src: [{ path: './fonts/GeneralSans-Semibold.woff2', weight: '600', style: 'normal' }], }); @@ -61,4 +62,8 @@ export const fonts = [ roboto, ]; -export const fontClasses = fonts.map((font) => font.className).join(' '); +// The single-weight General Sans class sets font-weight: 600. Use its variable +// class to register and preload the font without changing the body font weight. +export const fontClasses = fonts + .map((font) => (font === generalSans ? generalSans.variable : font.className)) + .join(' '); diff --git a/test/e2e-website/docs-fonts.spec.ts b/test/e2e-website/docs-fonts.spec.ts new file mode 100644 index 00000000000000..a3f627b63562ed --- /dev/null +++ b/test/e2e-website/docs-fonts.spec.ts @@ -0,0 +1,35 @@ +import { test, expect } from '@playwright/test'; + +for (const javaScriptEnabled of [false, true]) { + test.describe(`Docs fonts (${javaScriptEnabled ? 'hydrated' : 'server-rendered'})`, () => { + test.use({ javaScriptEnabled }); + + test('keeps normal body text and semibold headings', async ({ page }) => { + await page.goto('/material-ui/getting-started/installation/'); + if (javaScriptEnabled) { + await expect(page.locator('body')).toHaveAttribute('dir', 'ltr'); + } + + await expect(page.locator('body')).toHaveCSS('font-weight', '400'); + + // Use plain elements to check inheritance without component typography styles. + const inheritedWeights = await page.evaluate(() => { + const container = document.createElement('div'); + container.innerHTML = + '

Paragraph

Legend
'; + document.body.appendChild(container); + const weights = Array.from( + container.querySelectorAll('p, label, legend'), + (element) => getComputedStyle(element).fontWeight, + ); + container.remove(); + return weights; + }); + expect(inheritedWeights).toEqual(['400', '400', '400']); + + const heading = page.getByRole('heading', { name: 'Installation', exact: true }); + await expect(heading).toHaveCSS('font-weight', '600'); + await expect(heading).toHaveCSS('font-family', /General Sans/); + }); + }); +} From 710c30a9fb8b600b9a90c0af7ea08c37006b3e4b Mon Sep 17 00:00:00 2001 From: Lukas Date: Tue, 13 Oct 2026 16:48:17 +0300 Subject: [PATCH 2/2] [docs-infra] Leave the General Sans class off body Next registers and preloads the font from its import, so the variable class is not necessary. Check that the General Sans 600 font face loads in the hydrated test, and use the shared test fixture. Co-Authored-By: Claude Opus 5.5 --- .../core-docs/src/nextFonts/index.ts | 8 +++---- test/e2e-website/docs-fonts.spec.ts | 22 ++++++++++++++++++- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/packages-internal/core-docs/src/nextFonts/index.ts b/packages-internal/core-docs/src/nextFonts/index.ts index 49c8af2791750b..d770b5a8fd6488 100644 --- a/packages-internal/core-docs/src/nextFonts/index.ts +++ b/packages-internal/core-docs/src/nextFonts/index.ts @@ -16,7 +16,6 @@ export const roboto = Roboto({ export const generalSans = localFont({ declarations: [{ prop: 'font-family', value: 'General Sans' }], - variable: '--font-general-sans', src: [{ path: './fonts/GeneralSans-Semibold.woff2', weight: '600', style: 'normal' }], }); @@ -62,8 +61,9 @@ export const fonts = [ roboto, ]; -// The single-weight General Sans class sets font-weight: 600. Use its variable -// class to register and preload the font without changing the body font weight. +// The single-weight General Sans class sets font-weight: 600 on body. The import +// still registers and preloads the font, so the class is not necessary. export const fontClasses = fonts - .map((font) => (font === generalSans ? generalSans.variable : font.className)) + .filter((font) => font !== generalSans) + .map((font) => font.className) .join(' '); diff --git a/test/e2e-website/docs-fonts.spec.ts b/test/e2e-website/docs-fonts.spec.ts index a3f627b63562ed..3afd5cb9cc335e 100644 --- a/test/e2e-website/docs-fonts.spec.ts +++ b/test/e2e-website/docs-fonts.spec.ts @@ -1,4 +1,7 @@ -import { test, expect } from '@playwright/test'; +import { test as base, expect } from '@playwright/test'; +import { TestFixture } from './playwright.config'; + +const test = base.extend({}); for (const javaScriptEnabled of [false, true]) { test.describe(`Docs fonts (${javaScriptEnabled ? 'hydrated' : 'server-rendered'})`, () => { @@ -30,6 +33,23 @@ for (const javaScriptEnabled of [false, true]) { const heading = page.getByRole('heading', { name: 'Installation', exact: true }); await expect(heading).toHaveCSS('font-weight', '600'); await expect(heading).toHaveCSS('font-family', /General Sans/); + + // The declared font-family does not prove that the font face loads. + // The dev server injects font CSS with JavaScript, so check only when hydrated. + if (javaScriptEnabled) { + await expect + .poll(() => + page.evaluate(() => + Array.from(document.fonts).some( + (font) => + font.family.replace(/"/g, '') === 'General Sans' && + font.weight === '600' && + font.status === 'loaded', + ), + ), + ) + .toBe(true); + } }); }); }