From 6ada6876f84db5cf332be99132f902538a673936 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Wed, 21 Oct 2026 04:52:38 -0500 Subject: [PATCH 1/2] Serve the email templates' fonts and logo locally in matrix tests The Synapse email and validation-page templates load three Google Fonts stylesheets, a fonts.cdnfonts.com stylesheet and the Boxel logo from the internet. The stylesheets block rendering. When one is slow, the mail client shows the email as a blank pane and the screenshot assertion fails. In one failure the Poppins 700 stylesheet had no response when the screenshot was taken. The shared test fixture now routes those URLs, for every page in the context, to the bytes the browser received from them. A request to those hosts that is not stored gets a quick 404 and a warning, so a template change cannot bring the network dependency back without notice. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01WdM45xnz3vvTmA7HN8nGmK --- .prettierignore | 5 + packages/matrix/helpers/email-assets.ts | 74 ++++++++++++++ .../support/email-assets/Poppins-OFL.txt | 93 ++++++++++++++++++ .../matrix/support/email-assets/arial-2.css | 8 ++ .../support/email-assets/boxel-icon.png | Bin 0 -> 539 bytes .../matrix/support/email-assets/open-sans.css | 90 +++++++++++++++++ .../support/email-assets/poppins-400.css | 24 +++++ .../support/email-assets/poppins-700.css | 24 +++++ .../pxiByp8kv8JHgFVrLCz7Z1xlFQ.woff2 | Bin 0 -> 7816 bytes .../email-assets/pxiEyp8kv8JHgFVrJJfecg.woff2 | Bin 0 -> 7884 bytes packages/matrix/tests/fixtures.ts | 5 + 11 files changed, 323 insertions(+) create mode 100644 packages/matrix/helpers/email-assets.ts create mode 100644 packages/matrix/support/email-assets/Poppins-OFL.txt create mode 100644 packages/matrix/support/email-assets/arial-2.css create mode 100644 packages/matrix/support/email-assets/boxel-icon.png create mode 100644 packages/matrix/support/email-assets/open-sans.css create mode 100644 packages/matrix/support/email-assets/poppins-400.css create mode 100644 packages/matrix/support/email-assets/poppins-700.css create mode 100644 packages/matrix/support/email-assets/pxiByp8kv8JHgFVrLCz7Z1xlFQ.woff2 create mode 100644 packages/matrix/support/email-assets/pxiEyp8kv8JHgFVrJJfecg.woff2 diff --git a/.prettierignore b/.prettierignore index 87cc33e7d22..f1f16777ad9 100644 --- a/.prettierignore +++ b/.prettierignore @@ -21,6 +21,11 @@ packages/boxel-cli/plugin/skills/ # breaks its recorded SHA-256 and drifts it from its documented provenance. packages/experiments-realm/filedef-fixtures/samples/ +# Fonts, font stylesheets and an image that the matrix tests serve in place of +# the internet copies the Synapse email templates load. They are the bytes the +# browser received from those hosts; reformatting drifts them from that. +packages/matrix/support/email-assets/ + # Vendored third-party bundles and data in Pret UI. Each directory's README.md # records the upstream version and build; reformatting drifts the bytes from it. packages/pretui/color/index.js diff --git a/packages/matrix/helpers/email-assets.ts b/packages/matrix/helpers/email-assets.ts new file mode 100644 index 00000000000..f5aed319671 --- /dev/null +++ b/packages/matrix/helpers/email-assets.ts @@ -0,0 +1,74 @@ +import { readFileSync } from 'fs'; +import { join } from 'path'; +import type { BrowserContext } from '@playwright/test'; + +// The Synapse email and validation-page templates +// (support/synapse/templates/_base.html) load web fonts and the Boxel logo +// from the internet. Those stylesheets block rendering, so when one of them is +// slow the email shows as a blank pane in the mail client and the screenshot +// assertions fail. These are the bytes the browser received for each URL, +// served locally so the screenshots no longer depend on those hosts. +const assetsDir = join(import.meta.dirname, '..', 'support', 'email-assets'); + +const EXTERNAL_HOSTS = [ + 'fonts.googleapis.com', + 'fonts.gstatic.com', + 'fonts.cdnfonts.com', + 'd12nxmpmo97fii.cloudfront.net', +]; + +const ASSETS: Record = { + 'https://fonts.googleapis.com/css2?family=Poppins:wght@400': { + file: 'poppins-400.css', + contentType: 'text/css; charset=utf-8', + }, + 'https://fonts.googleapis.com/css2?family=Poppins:wght@700': { + file: 'poppins-700.css', + contentType: 'text/css; charset=utf-8', + }, + 'https://fonts.googleapis.com/css?family=Open%20Sans': { + file: 'open-sans.css', + contentType: 'text/css; charset=utf-8', + }, + 'https://fonts.cdnfonts.com/css/arial-2': { + file: 'arial-2.css', + contentType: 'text/css; charset=utf-8', + }, + 'https://fonts.gstatic.com/s/poppins/v24/pxiEyp8kv8JHgFVrJJfecg.woff2': { + file: 'pxiEyp8kv8JHgFVrJJfecg.woff2', + contentType: 'font/woff2', + }, + 'https://fonts.gstatic.com/s/poppins/v24/pxiByp8kv8JHgFVrLCz7Z1xlFQ.woff2': { + file: 'pxiByp8kv8JHgFVrLCz7Z1xlFQ.woff2', + contentType: 'font/woff2', + }, + 'https://d12nxmpmo97fii.cloudfront.net/boxel-icon.png': { + file: 'boxel-icon.png', + contentType: 'image/png', + }, +}; + +export async function routeEmailAssets(context: BrowserContext) { + await context.route( + (url) => EXTERNAL_HOSTS.includes(url.hostname), + async (route) => { + let url = route.request().url(); + let asset = ASSETS[url]; + if (!asset) { + // A template now asks for something not stored here. Answer quickly + // so nothing waits on the network, and say so in the test output. + console.warn( + `email asset not stored locally, answering 404: ${url} (add it to helpers/email-assets.ts)`, + ); + await route.fulfill({ status: 404, body: '' }); + return; + } + await route.fulfill({ + status: 200, + contentType: asset.contentType, + headers: { 'access-control-allow-origin': '*' }, + body: readFileSync(join(assetsDir, asset.file)), + }); + }, + ); +} diff --git a/packages/matrix/support/email-assets/Poppins-OFL.txt b/packages/matrix/support/email-assets/Poppins-OFL.txt new file mode 100644 index 00000000000..76df3b56567 --- /dev/null +++ b/packages/matrix/support/email-assets/Poppins-OFL.txt @@ -0,0 +1,93 @@ +Copyright 2020 The Poppins Project Authors (https://github.com/itfoundry/Poppins) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/packages/matrix/support/email-assets/arial-2.css b/packages/matrix/support/email-assets/arial-2.css new file mode 100644 index 00000000000..68ed020d03a --- /dev/null +++ b/packages/matrix/support/email-assets/arial-2.css @@ -0,0 +1,8 @@ +@font-face { + font-family: 'Arial'; + font-style: normal; + font-weight: 900; + src: local('Arial'), url('https://fonts.cdnfonts.com/s/59002/Lalithabai.woff') format('woff'); +} + + diff --git a/packages/matrix/support/email-assets/boxel-icon.png b/packages/matrix/support/email-assets/boxel-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..d8b9ad05bb500042d864cd53b12cc2b92fe48909 GIT binary patch literal 539 zcmeAS@N?(olHy`uVBq!ia0vp^Vj#@H3?x5i&EW)6+XH+;T!A#h|NjjC8yL=-v z!F=QZ^O1ebNB1!whBBCr?gODC`e|nI6sQJ-KnfsI zAQECGgn`Tkn!o@5|No+<<;Q_8w=N0t3ua(sV&&lF6BUz`QdBZBGqaAUHrwgoOT`J zS#{!S{;7ijCWk~M?@ayr^N@*Q@Uw$U`qrjA(R{7$_rLk)#>*=x32l?ssJAvL}@O1TaS?83{1OQf}_0a$T literal 0 HcmV?d00001 diff --git a/packages/matrix/support/email-assets/open-sans.css b/packages/matrix/support/email-assets/open-sans.css new file mode 100644 index 00000000000..55ea444ff20 --- /dev/null +++ b/packages/matrix/support/email-assets/open-sans.css @@ -0,0 +1,90 @@ +/* cyrillic-ext */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 400; + font-stretch: 100%; + src: url(https://fonts.gstatic.com/s/opensans/v44/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4taVIGxA.woff2) format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 400; + font-stretch: 100%; + src: url(https://fonts.gstatic.com/s/opensans/v44/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4kaVIGxA.woff2) format('woff2'); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek-ext */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 400; + font-stretch: 100%; + src: url(https://fonts.gstatic.com/s/opensans/v44/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4saVIGxA.woff2) format('woff2'); + unicode-range: U+1F00-1FFF; +} +/* greek */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 400; + font-stretch: 100%; + src: url(https://fonts.gstatic.com/s/opensans/v44/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4jaVIGxA.woff2) format('woff2'); + unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF; +} +/* hebrew */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 400; + font-stretch: 100%; + src: url(https://fonts.gstatic.com/s/opensans/v44/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4iaVIGxA.woff2) format('woff2'); + unicode-range: U+0307-0308, U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F; +} +/* math */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 400; + font-stretch: 100%; + src: url(https://fonts.gstatic.com/s/opensans/v44/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B5caVIGxA.woff2) format('woff2'); + unicode-range: U+0302-0303, U+0305, U+0307-0308, U+0310, U+0312, U+0315, U+031A, U+0326-0327, U+032C, U+032F-0330, U+0332-0333, U+0338, U+033A, U+0346, U+034D, U+0391-03A1, U+03A3-03A9, U+03B1-03C9, U+03D1, U+03D5-03D6, U+03F0-03F1, U+03F4-03F5, U+2016-2017, U+2034-2038, U+203C, U+2040, U+2043, U+2047, U+2050, U+2057, U+205F, U+2070-2071, U+2074-209F, U+20D0-20DC, U+20E1, U+20E5-20EF, U+2100-2112, U+2114-2115, U+2117-2121, U+2123-214F, U+2190, U+2192, U+2194-21AE, U+21B0-21E5, U+21F1-21F2, U+21F4-2211, U+2213-2214, U+2216-22FF, U+2308-230B, U+2310, U+2319, U+231C-2321, U+2336-237A, U+237C, U+2395, U+239B-23B7, U+23D0, U+23DC-23E1, U+2474-2475, U+25AF, U+25B3, U+25B7, U+25BD, U+25C1, U+25CA, U+25CC, U+25FB, U+266D-266F, U+27C0-27FF, U+2900-2AFF, U+2B0E-2B11, U+2B30-2B4C, U+2BFE, U+3030, U+FF5B, U+FF5D, U+1D400-1D7FF, U+1EE00-1EEFF; +} +/* symbols */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 400; + font-stretch: 100%; + src: url(https://fonts.gstatic.com/s/opensans/v44/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B5OaVIGxA.woff2) format('woff2'); + unicode-range: U+0001-000C, U+000E-001F, U+007F-009F, U+20DD-20E0, U+20E2-20E4, U+2150-218F, U+2190, U+2192, U+2194-2199, U+21AF, U+21E6-21F0, U+21F3, U+2218-2219, U+2299, U+22C4-22C6, U+2300-243F, U+2440-244A, U+2460-24FF, U+25A0-27BF, U+2800-28FF, U+2921-2922, U+2981, U+29BF, U+29EB, U+2B00-2BFF, U+4DC0-4DFF, U+FFF9-FFFB, U+10140-1018E, U+10190-1019C, U+101A0, U+101D0-101FD, U+102E0-102FB, U+10E60-10E7E, U+1D2C0-1D2D3, U+1D2E0-1D37F, U+1F000-1F0FF, U+1F100-1F1AE, U+1F1E6-1F1FF, U+1F30D-1F30F, U+1F315, U+1F31C, U+1F31E, U+1F320-1F32C, U+1F336, U+1F378, U+1F37D, U+1F382, U+1F393-1F39F, U+1F3A7-1F3A8, U+1F3AC-1F3AF, U+1F3C2, U+1F3C4-1F3C6, U+1F3CA-1F3CE, U+1F3D4-1F3E0, U+1F3ED, U+1F3F1-1F3F3, U+1F3F5-1F3F7, U+1F408, U+1F415, U+1F41F, U+1F426, U+1F43F, U+1F441-1F442, U+1F444, U+1F446-1F449, U+1F44C-1F44E, U+1F453, U+1F46A, U+1F47D, U+1F4A3, U+1F4B0, U+1F4B3, U+1F4B9, U+1F4BB, U+1F4BF, U+1F4C8-1F4CB, U+1F4D6, U+1F4DA, U+1F4DF, U+1F4E3-1F4E6, U+1F4EA-1F4ED, U+1F4F7, U+1F4F9-1F4FB, U+1F4FD-1F4FE, U+1F503, U+1F507-1F50B, U+1F50D, U+1F512-1F513, U+1F53E-1F54A, U+1F54F-1F5FA, U+1F610, U+1F650-1F67F, U+1F687, U+1F68D, U+1F691, U+1F694, U+1F698, U+1F6AD, U+1F6B2, U+1F6B9-1F6BA, U+1F6BC, U+1F6C6-1F6CF, U+1F6D3-1F6D7, U+1F6E0-1F6EA, U+1F6F0-1F6F3, U+1F6F7-1F6FC, U+1F700-1F80B, U+1F810-1F847, U+1F850-1F859, U+1F860-1F887, U+1F890-1F8AD, U+1F8B0-1F8BB, U+1F8C0-1F8C1, U+1F8D0-1F8D8, U+1F900-1F90B, U+1F93B, U+1F946, U+1F984, U+1F996, U+1F9E9, U+1FA00-1FA6F, U+1FA70-1FA7C, U+1FA80-1FAC6, U+1FAC8, U+1FACC-1FADD, U+1FADF-1FAEB, U+1FAEF-1FAFA, U+1FB00-1FBFF; +} +/* vietnamese */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 400; + font-stretch: 100%; + src: url(https://fonts.gstatic.com/s/opensans/v44/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4vaVIGxA.woff2) format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 400; + font-stretch: 100%; + src: url(https://fonts.gstatic.com/s/opensans/v44/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4uaVIGxA.woff2) format('woff2'); + unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 400; + font-stretch: 100%; + src: url(https://fonts.gstatic.com/s/opensans/v44/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4gaVI.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} diff --git a/packages/matrix/support/email-assets/poppins-400.css b/packages/matrix/support/email-assets/poppins-400.css new file mode 100644 index 00000000000..a8bba6c13cb --- /dev/null +++ b/packages/matrix/support/email-assets/poppins-400.css @@ -0,0 +1,24 @@ +/* devanagari */ +@font-face { + font-family: 'Poppins'; + font-style: normal; + font-weight: 400; + src: url(https://fonts.gstatic.com/s/poppins/v24/pxiEyp8kv8JHgFVrJJbecmNE.woff2) format('woff2'); + unicode-range: U+0900-097F, U+1CD0-1CF4, U+1CF7-1CF9, U+200C-200D, U+20A8, U+20B9, U+20F0, U+25CC, U+A830-A839, U+A8E0-A8FF, U+11B00-11B0A; +} +/* latin-ext */ +@font-face { + font-family: 'Poppins'; + font-style: normal; + font-weight: 400; + src: url(https://fonts.gstatic.com/s/poppins/v24/pxiEyp8kv8JHgFVrJJnecmNE.woff2) format('woff2'); + unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Poppins'; + font-style: normal; + font-weight: 400; + src: url(https://fonts.gstatic.com/s/poppins/v24/pxiEyp8kv8JHgFVrJJfecg.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} diff --git a/packages/matrix/support/email-assets/poppins-700.css b/packages/matrix/support/email-assets/poppins-700.css new file mode 100644 index 00000000000..e9632e64cf9 --- /dev/null +++ b/packages/matrix/support/email-assets/poppins-700.css @@ -0,0 +1,24 @@ +/* devanagari */ +@font-face { + font-family: 'Poppins'; + font-style: normal; + font-weight: 700; + src: url(https://fonts.gstatic.com/s/poppins/v24/pxiByp8kv8JHgFVrLCz7Z11lFc-K.woff2) format('woff2'); + unicode-range: U+0900-097F, U+1CD0-1CF4, U+1CF7-1CF9, U+200C-200D, U+20A8, U+20B9, U+20F0, U+25CC, U+A830-A839, U+A8E0-A8FF, U+11B00-11B0A; +} +/* latin-ext */ +@font-face { + font-family: 'Poppins'; + font-style: normal; + font-weight: 700; + src: url(https://fonts.gstatic.com/s/poppins/v24/pxiByp8kv8JHgFVrLCz7Z1JlFc-K.woff2) format('woff2'); + unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Poppins'; + font-style: normal; + font-weight: 700; + src: url(https://fonts.gstatic.com/s/poppins/v24/pxiByp8kv8JHgFVrLCz7Z1xlFQ.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} diff --git a/packages/matrix/support/email-assets/pxiByp8kv8JHgFVrLCz7Z1xlFQ.woff2 b/packages/matrix/support/email-assets/pxiByp8kv8JHgFVrLCz7Z1xlFQ.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..bf022fc77e764ee16a6d45fae8ed5016110ca2fc GIT binary patch literal 7816 zcmV;39(Un)Pew8T0RR9103L_{3;+NC06tIv03I{|0RR9100000000000000000000 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 a#rF!vrZP-gD&O<}^};ukMx!zS00029z2{T_ literal 0 HcmV?d00001 diff --git a/packages/matrix/support/email-assets/pxiEyp8kv8JHgFVrJJfecg.woff2 b/packages/matrix/support/email-assets/pxiEyp8kv8JHgFVrJJfecg.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..b69e0091c26c46151996a7feec95515567f95ac2 GIT binary patch literal 7884 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 literal 0 HcmV?d00001 diff --git a/packages/matrix/tests/fixtures.ts b/packages/matrix/tests/fixtures.ts index 792c2daffce..ee8d9e45d39 100644 --- a/packages/matrix/tests/fixtures.ts +++ b/packages/matrix/tests/fixtures.ts @@ -1,7 +1,12 @@ import { test as base, expect } from '@playwright/test'; import { setRealmRedirects } from '../helpers/index.ts'; +import { routeEmailAssets } from '../helpers/email-assets.ts'; export const test = base.extend({ + context: async ({ context }, use) => { + await routeEmailAssets(context); + await use(context); + }, page: async ({ page }, use) => { await setRealmRedirects(page); await use(page); From 9a011d6486f08e1ace3cc66d2f68efcd8290a5d8 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Wed, 21 Oct 2026 04:55:29 -0500 Subject: [PATCH 2/2] DO NOT MERGE: run the email screenshot tests with a stalled font stylesheet Holds the Poppins 700 stylesheet the email templates load for 8 seconds and runs only the three email screenshot tests on each matrix shard, repeated, one worker, no retries. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01WdM45xnz3vvTmA7HN8nGmK --- packages/matrix/scripts/test.sh | 10 ++++++++-- packages/matrix/tests/fixtures.ts | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/packages/matrix/scripts/test.sh b/packages/matrix/scripts/test.sh index df4e29fb9b2..e0ca78709d5 100755 --- a/packages/matrix/scripts/test.sh +++ b/packages/matrix/scripts/test.sh @@ -5,7 +5,13 @@ echo "running tests: ${1}" # this and narrows `testMatch` to the spec files bin-packed onto this shard; # Playwright's own `--shard` is not used because it balances test count rather # than test cost. See packages/matrix/support/shard-spec-files.ts. -MATRIX_TEST_SHARD="${1:-}" +# THROWAWAY VERIFICATION: every shard runs only the email screenshot tests, +# repeated, one worker, no retries. The template job has nothing to run. +if [ -n "${MATRIX_SYNAPSE_TEMPLATE:-}" ]; then + echo "verification run: skipping template job" + exit 0 +fi +MATRIX_TEST_SHARD="" export MATRIX_TEST_SHARD BASE_REALM="https-get://localhost:4201/base/" @@ -20,4 +26,4 @@ BASE_REALM_READY="$BASE_REALM$READY_PATH" WAIT_ON_TIMEOUT=600000 START_SERVER_AND_TEST_INSECURE=1 start-server-and-test \ 'pnpm run wait' \ "$BASE_REALM_READY" \ - 'pnpm playwright test' + 'pnpm playwright test tests/profile.spec.ts:90 tests/forgot-password.spec.ts:27 tests/registration-with-token.spec.ts:51 --repeat-each=5 --retries=0 --workers=1' diff --git a/packages/matrix/tests/fixtures.ts b/packages/matrix/tests/fixtures.ts index ee8d9e45d39..069a067ea7c 100644 --- a/packages/matrix/tests/fixtures.ts +++ b/packages/matrix/tests/fixtures.ts @@ -1,9 +1,24 @@ import { test as base, expect } from '@playwright/test'; +import type { BrowserContext } from '@playwright/test'; import { setRealmRedirects } from '../helpers/index.ts'; import { routeEmailAssets } from '../helpers/email-assets.ts'; +// THROWAWAY VERIFICATION: hold the Poppins 700 stylesheet the email templates +// load, as in the CI failure where it had no response at screenshot time. +async function stallEmailFontStylesheet(context: BrowserContext) { + await context.route( + 'https://fonts.googleapis.com/css2?family=Poppins:wght@700', + async (route) => { + console.log('stalling Poppins 700 stylesheet for 8000ms'); + await new Promise((r) => setTimeout(r, 8000)); + await route.continue(); + }, + ); +} + export const test = base.extend({ context: async ({ context }, use) => { + await stallEmailFontStylesheet(context); await routeEmailAssets(context); await use(context); },