Skip to content

test(demo): add bisect seed history - #99

Draft
rameziophobia wants to merge 18 commits into
mainfrom
ramez/bisect-demo-history
Draft

test(demo): add bisect seed history#99
rameziophobia wants to merge 18 commits into
mainfrom
ramez/bisect-demo-history

Conversation

@rameziophobia

@rameziophobia rameziophobia commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

PR 5 of 12; side branch from PR 4.

Summary

  • add an intentionally bisectable demo commit history
  • seed visual, performance, and accessibility regressions
  • document expected first-bad commits and configure acceptance fixtures

Why

Provide deterministic demo history for validating category-specific bisect behavior without coupling fixture changes to the product stack.

Checks

  • yarn workspace shaka-perf typecheck
  • seed-history Jest suite, 2 tests

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: aeec6835-e372-469c-84ef-2438d359eb0b

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ramez/bisect-demo-history

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

browser: 'chromium',
args: ['--no-sandbox'],
},
viewports: ['phone'],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This scopes visreg down to viewports: ['phone'] (dropping desktop/tablet), and below perf drops to phone-only too, plus numberOfMeasurements goes 10→8. These are global config changes that apply to every AB run for this demo, not just bisect runs — worth confirming that's intentional. If it's purely to keep bisect (which rebuilds per-commit) fast, consider scoping it to the bisect category only if the config surface supports per-category viewport overrides, so regular (non-bisect) visreg/perf runs keep full desktop/tablet coverage and full measurement count. Otherwise this is a real, unstated reduction in demo test coverage/statistical power.

Comment on lines +144 to +149
const configPath = path.resolve(
__dirname,
'../../../../../../demo-ecommerce/abtests.config.ts',
);

expect(fs.readFileSync(configPath, 'utf8')).toContain(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test does a raw substring match against abtests.config.ts's source text (via a path.resolve with six ../ segments). It's brittle in two ways: (1) any harmless reformatting of that line (quote style, whitespace, splitting the && command) breaks the test without an actual behavior regression; (2) the deep relative path silently breaks if this test file or the config ever move. Consider importing/parsing the resolved config (or at least matching a looser regex on the meaningful parts: rm -rf public/packs tmp/cache and assets:precompile) instead of an exact literal match.

status: 'running',
goodSha: seedCommits[0],
badSha: seedCommits.at(-1)!,
originalExperiment: { sha: seedCommits.at(-1)!, branch: 'codex/git-bisect-demo-history' },

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: branch: 'codex/git-bisect-demo-history' doesn't match this PR's actual branch (ramez/bisect-demo-history). Looks like leftover copy-paste from an earlier draft branch name — harmless since the assertions don't depend on it, but worth cleaning up so it doesn't confuse someone tracing this fixture back to a real branch later.

checksum += Math.sqrt(checksum + 1);
}

if (checksum === Number.POSITIVE_INFINITY) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

checksum === Number.POSITIVE_INFINITY is effectively unreachable (a ~450ms sum of sqrt increments can't overflow to Infinity), so this is dead code kept only to dodge dead-code elimination of the busy-loop. That's fine as a fixture technique, but as written it reads like a real conditional. A one-line comment explaining "kept to prevent the loop from being optimized away" would save the next reader from treating this as a real check. Same pattern in ProductDetailPage.tsx.

@claude

claude Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review

Overview

This side PR seeds a deterministic, bisectable commit history on the demo-ecommerce app: four category-specific regression fixtures (visreg on the homepage hero, perf CPU-warmup on homepage + product detail, a11y offscreen unnamed button), plus a bisect.rebuildCommands config block, a scoping change to visreg/perf viewports, and a Jest suite (seed-history.test.ts) that replays the documented commit map through the real search.ts bisect algorithm (nextCandidate/applyCachedObservations/applyObservations) and asserts it converges on the documented first-bad SHAs.

What's solid

  • The fixture pattern (runMerchandisingWarmup/runRecommendationScoring busy-loops, BisectAccessibilityProbe) mirrors the existing ExperimentA11yRegressions convention already in this demo app — deterministic client-side CPU work instead of network delays, as the new docs correctly call out.
  • docs/git-bisect-seed-history.md is thorough: it documents the seed base, a per-commit category map, and explicit "expected affected/unaffected AB tests," which is genuinely useful for future maintainers validating bisect behavior.
  • The test's simulated binary search against search.ts is a real correctness check of the production algorithm (not just a data fixture), and the math checks out against the documented commit indices (fixtures at indices 3, 6, 10, 14 of an 18-commit chain, each persisting monotonically afterward).
  • bisect.rebuildCommands matches the existing SetupCommandSchema/BisectConfigSchema shape in config.ts, so this isn't introducing an unrecognized config key.

Issues raised inline

  • Config scope: viewports: ['phone'] was added to both visreg and perf (dropping desktop/tablet coverage), and perf.numberOfMeasurements dropped 10→8. These are global changes to the demo's regular (non-bisect) AB runs, not scoped to bisect — worth confirming that's intended given the PR is framed as "seed demo history," not "reduce test coverage/statistical power."
  • Brittle test: seed-history.test.ts's first test does an exact substring match against abtests.config.ts source text via a 6-level-deep relative path — fragile to harmless reformatting and to future file moves.
  • Minor cleanup: leftover branch: 'codex/git-bisect-demo-history' in the test fixture doesn't match the actual PR branch name; and the checksum === Number.POSITIVE_INFINITY dead-code guard in both busy-loop helpers would benefit from a one-line comment explaining it's there to defeat dead-code elimination, not a real check.

Not verified

I wasn't able to run yarn workspace shaka-perf typecheck or the Jest suite in this environment (command execution was restricted), so I couldn't confirm the PR's own stated checks pass — worth making sure CI is green before merge. I also didn't independently verify that the 16 documented commit SHAs' actual diffs match their doc descriptions (the test validates the algorithm against the documented map, not that the map matches real git show output for each SHA).

Security

No concerns — all changes are demo-app fixture code and a fixed (non-user-controlled) shell command string in the rebuild config; no injection surface.

@rameziophobia
rameziophobia marked this pull request as ready for review July 15, 2026 18:25
@greptile-apps

greptile-apps Bot commented Jul 15, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds deterministic demo history for category-specific bisect testing. The main changes are:

  • Phone-focused visual and performance settings with candidate rebuild commands.
  • Seeded visual, performance, and accessibility regressions on measured pages.
  • Documentation and tests for expected first-bad commits.

Confidence Score: 4/5

The phone-only visual configuration drops existing coverage and should be corrected before merging.

  • Non-phone visual tests resolve to no work under the new global setting.
  • The history test can remain green after the real seed history drifts.
  • The page probes otherwise match the documented fixture goals.

demo-ecommerce/abtests.config.ts; packages/shaka-perf/src/compare/bisect/tests/seed-history.test.ts

Important Files Changed

Filename Overview
demo-ecommerce/abtests.config.ts Adds phone-only category settings and bisect rebuild commands, but the visual override drops existing non-phone tests.
demo-ecommerce/app/javascript/components/pages/HomePage.tsx Adds the intended homepage visual, performance, and accessibility probes.
demo-ecommerce/app/javascript/components/pages/ProductDetailPage.tsx Adds the intended product-detail visual and performance probes.
demo-ecommerce/docs/git-bisect-seed-history.md Documents the seeded commits, expected first-bad points, and affected test coverage.
packages/shaka-perf/src/compare/bisect/tests/seed-history.test.ts Tests synthetic bisect search results but does not validate the modeled commits against the real Git history.

Reviews (1): Last reviewed commit: "test(demo): configure bisect acceptance ..." | Re-trigger Greptile

browser: 'chromium',
args: ['--no-sandbox'],
},
viewports: ['phone'],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Desktop Visual Tests Are Skipped

The viewport planner intersects this global list with each test's viewport list. With only phone enabled, desktop-only Admin tests and the tablet/desktop Product Detail Actions test produce no visual work, so regressions in those tests disappear instead of remaining unaffected.

Comment on lines +164 to +170
const candidateIndex = seedCommits.indexOf(work.sha);
const regressionsPresent = new Set(
seedCommits
.slice(0, candidateIndex + 1)
.flatMap(
(sha) => seedRegressionsByCommit[sha as keyof typeof seedRegressionsByCommit] ?? [],
),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Synthetic History Hides Commit Drift

Regression presence is generated from the same hard-coded commit list and map used to define the expected answers. If a seed commit is removed, reordered, or no longer contains its documented page change, this test still passes while a real Git bisect reports a different first-bad commit.

@claude

claude Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review

This PR adds a deterministic, bisectable demo commit history to demo-ecommerce (hero-color visreg regression, CPU-warmup perf regressions, an offscreen unnamed-button a11y regression) plus a bisect.rebuildCommands config block and a Jest suite that replays the seeded commit list through the real search.ts binary-search logic to confirm each target's documented first-bad commit.

Overall: the regression fixtures are well-isolated (contained to Home/ProductDetail, deterministic CPU busy-loops instead of network delays, no data/API changes) and the seed-history doc is a nice touch for future maintainers. The unit test exercises the actual applyCachedObservations / nextCandidate / applyObservations bisect algorithm rather than re-implementing it, which is the right way to validate this.

A few things worth a look (left as inline comments):

  • The test's seedCommits array has an 18th, undocumented commit (f7b872f...) that doesn't appear in docs/git-bisect-seed-history.md's "Category map" — worth reconciling so the doc stays an accurate map of the branch.
  • originalExperiment.branch in the test fixture is hardcoded to codex/git-bisect-demo-history, which doesn't match this PR's actual head branch (ramez/bisect-demo-history) — looks like a leftover from a different context.
  • The "clears persistent build output" test asserts an exact-string match against the raw abtests.config.ts source (including quote style/whitespace), which will break on a harmless reformat even though behavior didn't change.
  • The while (true) search loop in the second test has no iteration cap, so a regression in the bisect algorithm that fails to converge would hang the test until Jest's default timeout rather than failing with a clear assertion.

Also noting for awareness (not blockers): numberOfMeasurements drops from 10 → 8 and viewports is pinned to ['phone'] for both visreg and perf in the shared demo config — reasonable if this is scoped to speed up the bisect demo, but worth confirming it doesn't quietly narrow coverage for other tests riding on this same config.

🤖 Generated with Claude Code

Comment on lines +21 to +38
'38dae6871b8b443dd1880269dacde951700e77cc',
'623a1ae6f39cb6cbddd550ecd33d83c670877d14',
'fe8900e2568f11d05e41d43ad62e0aa863017264',
'58cc828b7272cd69408fa4dc5cd36206dcd8846a',
'a55e7f44dea86afa94775cf448dc3e696c71ed33',
'754fcd9b72b5623118a9bc1fb84b87ec98e002e1',
'9c7cfff6c0ca9bd561f5bb9905a1b09ee3132d1e',
'744fe902ab6b087f761f2df7e1f52bcc2e88d1c1',
'ac38e5320e6c33b67474f445c15e3012e22fb491',
'463c4296e003fafe5dc4e23f5f43e805e555938d',
'fcb0e2b107a99c6e4edab01da114d4d83b3d7a94',
'c1e2a62486870b02354c0c5b8727f8944e4913a3',
'ce1f6015bfd01e05228d94affb788fe5f0d896a0',
'3846371172486d851b836883c54520cc1b844199',
'5345dffb62b761b9cb0e1516a6bbd4389a6cf642',
'088afb9342d8c4337361df177e3731550b096fc9',
'4406a7800cfec9af52e9f7e731a1ad59915ac227',
'f7b872f2a6d5817be15261b4d9f21a4f6814126f',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This array has 18 commits (the base + 17), but docs/git-bisect-seed-history.md's "Category map" only documents 16 commits after the base (623a1ae4406a78). The last entry here, f7b872f2a6d5817be15261b4d9f21a4f6814126f, doesn't appear in the doc at all.

It's used as badSha/the end of orderedCommits, so it doesn't affect the test's assertions today, but it means the doc is no longer a complete map of the fixture branch — worth adding a line for it (or dropping it if it's stray) so the two stay in sync for whoever bisects this branch by hand later.

status: 'running',
goodSha: seedCommits[0],
badSha: seedCommits.at(-1)!,
originalExperiment: { sha: seedCommits.at(-1)!, branch: 'codex/git-bisect-demo-history' },

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

branch: 'codex/git-bisect-demo-history' doesn't match this PR's actual head branch (ramez/bisect-demo-history). It's inert test data (nothing asserts on it), but it reads like a leftover from a different branch/tooling context and could mislead someone debugging this fixture later.

Comment on lines +143 to +153
it('clears persistent build output before precompiling each candidate', () => {
const configPath = path.resolve(
__dirname,
'../../../../../../demo-ecommerce/abtests.config.ts',
);

expect(fs.readFileSync(configPath, 'utf8')).toContain(
"command: 'rm -rf public/packs tmp/cache && SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile'",
);
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test asserts an exact substring of the raw abtests.config.ts source, including quote style and whitespace ("command: 'rm -rf public/packs tmp/cache && ..."). A harmless reformat (prettier, switching quote style, wrapping the line) would fail this test with no behavior change.

Consider asserting against the loaded/parsed config value (e.g. import the resolved bisect.rebuildCommands array and check an entry's command) instead of grepping file text — same coverage, but resilient to formatting.

it('finds the documented first bad commit for every seeded regression target', () => {
let session = seedSession();

while (true) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while (true) with no iteration cap: if a future change to search.ts introduces a bug where nextCandidate never returns null for this fixture (e.g. an off-by-one that keeps splitting forever), this test hangs until Jest's default timeout instead of failing with a clear assertion. A for (let i = 0; i < seedCommits.length * 4; i++) guard (or similar) with a fail('did not converge') after would make that failure mode diagnosable.

@rameziophobia
rameziophobia changed the base branch from ramez/bisect-run-controls to main July 15, 2026 18:35
@rameziophobia
rameziophobia marked this pull request as draft August 6, 2026 11:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant