Skip to content

chore: enable Alttester visual tests - #8628

Merged
pravusjif merged 34 commits into
devfrom
chore/visual-test-app-args
May 21, 2026
Merged

chore: enable Alttester visual tests#8628
pravusjif merged 34 commits into
devfrom
chore/visual-test-app-args

Conversation

@pravusjif

@pravusjif pravusjif commented May 5, 2026

Copy link
Copy Markdown
Member

A series of small changes and additions to enable the external Alttester automation tests the maximum determinism for VISUAL TESTS (automation tests like at https://github.com/decentraland/explorer-automation)

  • --disable-hud app arg flag needed for visual tests determinism (Explorer HUD , NOT scenes SDK UI).
  • --graphics app arg flag needed for visual tests determinism.
  • --skip-minimum-specs-screen app arg flag needed for visual tests determinism.
  • Fixed missing skybox timers skipping the --skybox-time-enabled flag
  • Added Scene Readiness Probe for AltTester Visual Tests

Reminder: the ALTTESTER compiler definition is only enabled when the --alttester app arg is used, Metaforge already takes care of that when opening a build to run the Alttester tests.


Added Scene Readiness Probe for AltTester Visual Tests

What

Adds a tiny, AltTester-queryable surface that reports whether the player's current scene has finished loading. Replaces the heuristic "wait for a pixel-stable frame" used by the visual test fixtures, which silently passed on stale frames during hot-reload.

How it works

  • SceneFacade.SetIsCurrent(true) registers the facade on the probe; SetIsCurrent(false) / Dispose / DisposeAsync clear it.
  • IsCurrentSceneReady() returns currentFacade?.IsSceneReady() — the same SceneLoadingConcluded check already used by UnloadSceneLODSystem, ReloadSceneChatCommand, etc.
  • Test side (explorer-automation) calls AltDriver.CallStaticMethod<bool>("SceneRunner.Scene.AlttesterSceneReadinessProbe", "IsCurrentSceneReady", "SceneRunner.Scene", …) and polls until ready.

Why static

AltTester's CallStaticMethod is the only reflection path that doesn't require first locating a MonoBehaviour on a GameObject. A non-static alternative would mean (a) a sink interface injected into every SceneFacade instance through the DI chain (SceneFactory and its parents), (b) a no-op implementation for non-AltTester contexts, and (c) updating every test that builds a facade by hand. That's a meaningful refactor for a hook that exists purely to serve AltTester. Static + compile-time gating delivers the same effective footprint with a tenth of the surface area.

Gating

Everything is wrapped in #if ALTTESTER:

  • The entire AlttesterSceneReadinessProbe.cs body.
  • All three call sites in SceneFacade.cs.

The ALTTESTER define is set in ProjectSettings.asset under Standalone defines for Editor and local builds, and stripped by CloudBuild.cs when IS_RELEASE_BUILD=true. Release builds shipped to end-users contain no probe class, no fields, no call sites — zero footprint.


TEST INSTRUCTIONS (MacOS ONLY)

Clone the automation tests repo: https://github.com/decentraland/explorer-automation and step at the root of that folder, the following commands have to be ran in there -> Run the visual tests locally and confirm both the regression tests pass:

  1. make install
  2. metaforge account create
  3. metaforge account login (select one of the existent accounts)
  4. metaforge explorer server start
  5. metaforge explorer test chore/visual-test-app-args --filter "Category=Visual" [REPORT SHOULD BE GREEN, ALL TESTS PASS]
  6. metaforge explorer server stop

@pravusjif pravusjif self-assigned this May 5, 2026
@pravusjif pravusjif added the shape-up It has been shaped and is awaiting the cycle. label May 5, 2026
@github-actions

github-actions Bot commented May 5, 2026

Copy link
Copy Markdown
Contributor

@pravusjif pravusjif moved this from Todo to In Progress in Explorer Alpha May 6, 2026
@pravusjif pravusjif changed the title chore: visual tests app args chore: enable Alttester visual tests May 13, 2026
@pravusjif pravusjif added the force-build Used to trigger a build on draft PR label May 15, 2026
@pravusjif pravusjif added force-build Used to trigger a build on draft PR and removed force-build Used to trigger a build on draft PR labels May 15, 2026
@pravusjif
pravusjif removed the request for review from Ludmilafantaniella May 19, 2026 12:38
@pravusjif pravusjif moved this from In Progress to With QA / Awaiting Review in Explorer Alpha May 19, 2026
popuz and others added 3 commits May 19, 2026 17:10
…vided

  FullScreenWindow is a borderless window sized to the OS desktop, so the
  Unity --resolution override is silently clamped to the desktop size. On
  headless Windows CI (1024x768 default) the framebuffer never reaches the
  requested WxH, breaking visual-regression captures.

  Switch to ExclusiveFullScreen whenever the caller explicitly passes a
  resolution override in fullscreen mode — this triggers a real DXGI/display
  mode-switch and the captured framebuffer matches the requested size.
  Behavior without --resolution is unchanged.
@github-actions github-actions Bot deleted a comment from claude Bot May 19, 2026
@github-actions github-actions Bot deleted a comment from claude Bot May 19, 2026
@github-actions github-actions Bot deleted a comment from claude Bot May 19, 2026
@claude

This comment has been minimized.

@github-actions github-actions Bot deleted a comment from claude Bot May 20, 2026
@github-actions github-actions Bot deleted a comment from claude Bot May 20, 2026
@claude

This comment has been minimized.

@claude

This comment has been minimized.

@claude

This comment has been minimized.

@claude

This comment has been minimized.

@claude

This comment has been minimized.

@claude

claude Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor

Claude finished @pravusjif's task in 2m 11s —— View job


PR Review (sync — latest HEAD 2d2d8410)

  • Read CLAUDE.md and docs/README.md
  • Check new commit 2d2d8410 (review feedback fixes)
  • Review full PR diff against origin/dev
  • Post final verdict

Root-cause summary

This PR solves two problems: (a) AltTester visual test non-determinism because HUD visibility, skybox time, and graphics quality weren't pinned at build launch; (b) AltTester had no reliable signal for scene-load completion. The diff fixes both root causes directly — new app args pin the variables, a skybox timer bypass fixes the --skybox-time-enabled regression, and AlttesterSceneReadinessProbe gives tests a deterministic readiness gate. No symptom-masking detected.


Latest commit 2d2d8410 — review feedback applied

Both items from the previous review were addressed:

Item Before After
BootstraperShould.cs:16async void Setup() async void with UniTask.WaitUntil workaround in each test async Task Setup() — workarounds removed
AlttesterSceneReadinessProbe.cs:57 — string concat allocation parcel.x + "," + parcel.y StringBuilder(16).Append(parcel.x).Append(',').Append(parcel.y)

Both fixes are correct and clean.


No blocking issues found

All changed files reviewed:

  • AlttesterSceneReadinessProbe.csvolatile field correct for single-writer/multi-reader pattern. internal Set/Clear, public query methods. Hand-rolled JSON builder is appropriate here (no serializer dep). All gated by #if ALTTESTER.
  • SceneFacade.csClearIfCurrent called in both Dispose (before DisposeInternal) and DisposeAsync (before the main-thread switch). SetIsCurrent correctly branches on isCurrent. All three sites properly #if ALTTESTER-gated.
  • SkyboxPlugin.csSetInitialTime local function now called unconditionally, pins to noon when !timeEnabled so skybox is deterministic regardless of host clock. SkyboxTimeUpdateSystem injection still gated by skyboxTimeEnabled. Correct.
  • SavedQualitySettingsApplier.cs / QualitySettingsController.cs--graphics override applied without persisting (persist: false). Custom rejected with LogWarning. Clean.
  • NativeWindowManager.cs — Three-way fullscreen decision logic is correct: --windowed-mode → forced false; saved pref exists → from pref; else → inherit Unity's mode. ResolveFullScreenMode helper and ExclusiveFullScreen/Windows branch are clean.
  • MainSceneLoader.cs--skip-minimum-specs-screen correctly yields to --force (&& !forceShow). No issue.
  • BootstraperShould.csasync Task Setup() with remaining UniTask.Yield() is correct; ensures substitutes are ready before tests run.
  • AppArgsFlags.cs — Three new string constants (SKIP_MINIMUM_SPECS_SCREEN, GRAPHICS, DISABLE_HUD). No issues.

Non-blocking warning (carried from prior review)

W.7a — visual-regression.yml:162: reusable workflow pinned to @main with secrets: inherit
uses: decentraland/explorer-automation/.github/workflows/run-visual-suite.yml@main with secrets: inherit. SHA-pin recommended before this workflow is used as a template. (Cannot be modified in this context — GitHub App lacks .github/workflows/ write permission.)


REVIEW_RESULT: PASS ✅
COMPLEXITY: COMPLEX
COMPLEXITY_REASON: Touches scene runtime (SceneFacade lifecycle with volatile cross-thread state), skybox plugin, quality settings controller, native window management, async patterns (UniTask), and a new CI/CD workflow.
QA_REQUIRED: YES
· branch chore/visual-test-app-args

@claude

claude Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor

Claude finished @pravusjif's task in 1m 4s —— View job


Claude PR Security Re-Review — sync

  • Identify what changed since prior security review (HEAD 38c7590cf)
  • Re-evaluate workflow/dependency findings
  • Re-scan PR-side changes in current HEAD (2d2d8410d)
  • Post verdict

What changed since the prior security review

One new commit on top of 38c7590cf:

Commit Files Type
2d2d8410d BootstraperShould.cs (+1/-4), AlttesterSceneReadinessProbe.cs (+3/-1) C# style — addresses two non-blocking review comments

The two changes:

  • [SetUp] public async void Setup()public async Task Setup() and removed the per-test await UniTask.WaitUntil(() => mvcManager != null) workarounds.
  • parcel.x + "," + parcel.yStringBuilder (the using System.Text; import was already present from the existing GetCurrentSceneStatusJson usage).

Verified:

  • No new dependenciesgit diff 38c7590cf..HEAD -- Explorer/Packages/manifest.json Explorer/Packages/packages-lock.json is empty.
  • No workflow changesgit log 38c7590cf..HEAD -- .github/workflows/ is empty; visual-regression.yml is identical to the file reviewed previously.
  • No new binaries / native plugins / .asmdef changes.
  • No new prompt files.
  • No new attack surface — both changes are local C# inside #if ALTTESTER / test code paths.

Prior findings — current status

ID File Status
W.7arun-visual-suite.yml@main pinned to mutable ref with secrets: inherit .github/workflows/visual-regression.yml:162 Still present — SHA-pin recommended before merge
W.3 — TOCTOU between /visual-tests comment and workflow run .github/workflows/visual-regression.yml:99-101 Still present
W.6author_association as sole authorization gate .github/workflows/visual-regression.yml:63-77 Still present (informational — availability, not bypass)

None of these are reachable from the new commit; they are properties of the workflow file, which is unchanged in this sync.

Verdict

The new PR-side commit only addresses two non-blocking C# style comments from the previous review — no security-relevant changes. The prior verdict carries over unchanged: W.7a is the one finding worth resolving before merge (SHA-pin the run-visual-suite.yml reusable workflow invoked with secrets: inherit); W.3 and W.6 remain smaller follow-ups.

DEPENDENCY_REVIEW: NEEDS_ATTENTION (carried over from the prior six reviews — no new findings on this sync)
· branch chore/visual-test-app-args

@m3taphysics

Copy link
Copy Markdown
Contributor

PR #8628, run #26196359619

Builds: Windows change, Windows baseline, macOS change, macOS baseline

Framework 13 i7

Metric Change Baseline Delta Improvement
Samples 2700 2700
CPU average 33.3 ms 33.3 ms -0.0 ms 0.0%
CPU 1% worst 33.6 ms 33.6 ms 0.0 ms -0.0%
CPU 0.1% worst 35.5 ms 35.8 ms -0.4 ms 1.0%
GPU average 7.8 ms 7.9 ms -0.1 ms 1.0%
GPU 1% worst 18.7 ms 19.3 ms -0.6 ms 3.0% 🟢
GPU 0.1% worst 25.9 ms 26.6 ms -0.7 ms 2.5%

@decentraland decentraland deleted a comment from m3taphysics May 21, 2026
@pravusjif
pravusjif merged commit 050db6d into dev May 21, 2026
26 of 27 checks passed
@pravusjif
pravusjif deleted the chore/visual-test-app-args branch May 21, 2026 10:57
@github-project-automation github-project-automation Bot moved this from With QA / Awaiting Review to Done in Explorer Alpha May 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

new-dependency shape-up It has been shaped and is awaiting the cycle.

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

4 participants