Repository navigation
[3.0] Adds template snapshot tests that freeze what each page renders - #9712
Open
albertlast wants to merge 8 commits into
Open
albertlast wants to merge 8 commits into
albertlast wants to merge 8 commits into
Conversation
Collaborator
Author
|
@Sesquipedalian here you test env for plate migration |
This was referenced Sep 29, 2026
live627
reviewed
Sep 30, 2026
This was referenced Sep 30, 2026
Open
albertlast
force-pushed
the
3.0/template-snapshots
branch
from
October 1, 2026 17:56
ea5ae21 to
7a08b1e
Compare
Records what about 230 pages render today, as a guest, a member and an administrator, so that moving the templates to Plates can be checked page by page. A page that renders differently fails, and the diff says how. Pages are compared as DomSnapshot describes them rather than as HTML: whitespace, comments and attribute order are dropped, and the forum's own data - ids, counts, dates, names, sessions, list lengths - is masked. Pages that list content look at fixtures built once per forum, and lists of the whole forum are narrowed to them, so the snapshots do not change when somebody posts, registers or adds a board. The errors a page logs are part of its snapshot. perturb-forum.php fills a throwaway forum with unrelated members, boards and posts. Recorded on a fresh MySQL forum, the snapshots pass there and on a fresh PostgreSQL forum, and on both again after two rounds of it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: albertlast <mathiaspapealbert@hotmail.com>
…d-in forum showed HttpTestCase slept for three seconds and retried whenever flood control turned a login or a post away. As suggested in review, submitForm() now deletes the rows in log_floodcontrol first, so there is nothing to wait out and no test depends on how quickly it runs. The retry logic goes. Running the snapshots against a forum that had been used, rather than a new one, found content they still depended on: - the forum administrator's own profile, since the fixtures posted as them; a fixture administrator posts instead, and the fixtures carry a version so that forums holding the old ones rebuild them - the hash in a minified file's name, which \b never matched after "_" - ;boardseen, decimals and thousands in numbers, email addresses, the encoded parameters of a search, and fixture ids in the selectors - the errors a member had logged, on their tracking page The recording itself had two faults: a Settings_bak.php the forum could not write, which put a warning on every settings page, and the password prompt in front of a member's account settings, which was recorded in place of the page. The suite now gets past the prompt for members as it already did for the administrator. Snapshot tests also reuse their signed in browser rather than making a new one per test, which cost a request each and a third of the run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: albertlast <mathiaspapealbert@hotmail.com>
docker compose exec starts a fresh environment, so test.sh only hands over the variables it names. SMF_UPDATE_SNAPSHOTS was not one of them, and under the docker runner the documented way to re-record the snapshots compared against them instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: albertlast <mathiaspapealbert@hotmail.com>
The search results snapshots open search2 from a link, and SMF turns away a search made within a few seconds of the last one. With each request taking about a second, as it does over a Windows bind mount, the two search pages were never close enough together to notice. On a Linux filesystem the suite runs about twenty times faster, and the second search came back as a 403. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: albertlast <mathiaspapealbert@hotmail.com>
profile_track_ip pinned a fatal that SimpleMachines#9718 has fixed, so it now records the page. features_basic and profile_theme show the time zone select grouped by country. themes_copy lists the new TimeZoneSelect template and no longer logs an array to string conversion, which SimpleMachines#9720 fixed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: albertlast <mathiaspapealbert@hotmail.com>
Adds the license header to any test file this adds, and writes the docblock of each new test method in the agreed shape: Expected:, Guards: for a regression, and @link lines for the commit that introduced the bug and for this pull request. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: albertlast <mathiaspapealbert@hotmail.com>
HttpTestCase now shares one guest browser between tests, and signInAsAdmin() signs in a browser of its own. The snapshot classes need a browser per audience, so their first browser is a new one rather than the shared guest, which the member audience would otherwise sign in for every test after it. The admin audience signs in a fresh browser rather than the shared one, since passing the admin security check changes its session, and the audience's browser is kept once signing in is done. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: albertlast <mathiaspapealbert@hotmail.com>
The time zone pickers on the basic features page and the theme profile page name and order each zone by whether daylight saving is in effect that day, so both snapshots failed when Australia moved its clocks on 4 October, with no template involved. Both cases now ignore the select, which the snapshot still records as being there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: albertlast <mathiaspapealbert@hotmail.com>
albertlast
force-pushed
the
3.0/template-snapshots
branch
from
October 5, 2026 04:49
94734c7 to
ff6e3fd
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
The templates are going to move from SMF's own template layer to Plates. That touches almost every page, and almost none of those pages is covered by a test, so there is no way today to tell whether a converted page still renders what it used to.
This adds a snapshot suite that records what 234 pages render now, and fails when one renders differently:
.dev/test.sh --engine mysql --testsuite snapshot SMF_UPDATE_SNAPSHOTS=1 .dev/test.sh --engine mysql --testsuite snapshot # re-recordA run takes about five and a half minutes in the Docker environment on Windows, so it has a testsuite of its own and
--testsuite httpstays as quick as it was. Nearly all of that is the bind mount: every request stats a few hundred source files across it, at about 2 ms a file against 4 µs on the container's own disk, so any page costs a second or so. It should be much quicker on Linux, though I have not measured that.What is compared
Not the HTML.
tests/Support/DomSnapshot.phpreduces each page to its elements, attributes and text, one node per line, so a diff reads like a tree:{date}, lengths of time{duration}, ids and counts#(decimals and thousands included), and the word after a count is written the same in the singular and the plural (# reply(s)){member},{board}or{subject}, wherever else that text appears on the page tooWhat is left is the structure, the attributes and the text the templates and language files put there. The unit test for it pins both halves: the variations it has to ignore, and the changes it must still catch (a class dropped, an attribute dropped, a string changed or missing, escaping lost, an element moved, a column lost from every row).
Each snapshot also records the page's HTTP status and the errors the page logged. A converted template that renders the same page while logging an undefined index still shows up as a diff, and a page that fatals today is pinned as doing so.
Stable when the forum changes
The snapshots must not change when somebody posts, registers or adds a board. Two things make that hold:
fixture-forum.phpbuilds the content the pages are pointed at, once per forum, through SMF's own API: a category with boards and child boards, topics (one sticky, locked and with a poll), replies from members, an administrator and a guest, three members, a personal message and two calendar events. Every date is pinned to January 2020, there are at least two of everything a template loops over, and everything is marked read. Nothing is posted by the forum's own administrator, whose profile is not ours to rely on; a fixture administrator does it. The fixtures carry a version, and a forum holding an older one has them removed and rebuilt.perturb-forum.phptests exactly this. It registers members with awkward names, creates categories, boards and child boards (including one under an existing board), posts topics and replies from the administrator, the new members and a guest, some sticky, some locked, sends PMs to the administrator, and gives the administrator a signature, personal text and website. It is for a forum you are going to throw away.Configuration is not masked. The admin pages show the forum's settings, so the snapshots are recorded on, and meant to be compared against, a freshly installed forum, as CI installs. Against a dev forum that had been used for weeks, the only differences left are the three pages that show
securityDisable, which that forum has switched on.Validation
On a freshly installed forum in an isolated compose project, for each engine:
One set of snapshots serves both engines. Flood control is cleared through
log_floodcontrolbefore each login or form post rather than waited out, as suggested in review. Earlier rounds of this failed, and each failure was fixed at the cause rather than re-recorded. They are listed because they are the reasons behind rules that could look arbitrary:<strong>Today</strong> at 10:00instead of a date once somebody had signed in that dayIntegrationTestCaserestores$modSettingsin memory after each test andupdateModSettings()then saw nothing to change�never matched afterminified_), averages like2.5,;boardseen, and fixture ids in the selectorsSettings_bak.phpthe forum could not write, which put a warning on every settings page, and the password prompt in front of a member's account settings, recorded in place of the pageWhat is deliberately not covered
Not in CI yet
--testsuite integrationin.github/workflows/phpunit.ymlexcludestests/Integration/Http, so neither the existing HTTP tests nor these run in CI. CI serves the forum from PHP's built-in server with a different set of extensions from the Docker image, and some pages (the attachment settings with the php.ini upload limits, for one) may well render differently there. Wiring that up is a follow-up worth doing on its own, once it has been run against CI's environment.Found along the way
None of these is fixed here; each has its own pull request. The snapshots work around them and are recorded as the pages behave today.
?action=recent;boards=1,2returns a 500:explode(): Argument #2 ($string) must be of type string, array given. The recent posts snapshot uses;c=instead. Fixed in [3.0] Lets recent posts be narrowed to a list of boards again #9713.Memberlist::search()wraps the columns inLOWER()but no longer folds the search term; [3.0][Testing] Case insensitive comparisons (part 2 of 2) — guard the convention in the unit suite #9597 folds it with{string_ci:search}, but was written against the code before the email search changes and needs rebasing onto it. The member list snapshot searches in lower case. Fixed in [3.0] Finds members on PostgreSQL whatever case the search is typed in #9716.TopicSplithas noORDER BYat all unless the member views newest first, so on PostgreSQL the split page lists the posts in whatever order the table gives them. Fixed in [3.0] Lists the posts to split off a topic in a defined order #9714.PermissionProfileloads the profiles with noORDER BY, so they come out in a different order on each engine. Fixed in [3.0] Loads the permission profiles in the order they were made again #9715.webmaster_emailat the defaultnoreply@myserver.comand a fresh PostgreSQL one at the address the installer was given. Not looked into; email addresses are masked, so it does not reach the snapshots.Issues References (Fixes|Related|Closes)
Related: the planned conversion of the templates to Plates (no issue yet), #9713, #9714, #9715, #9716.
🤖 Generated with Claude Code