feat: PER-7348 add waitForReady() call before serialize()#134
Merged
Conversation
Adds the readiness gate from percy/cli#2184. A new _wait_for_ready() helper uses page.evaluate (sync Playwright auto-awaits Promises) with a typeof guard so older CLI versions that lack waitForReady are no-ops. The return value is attached to dom_snapshot['readiness_diagnostics'] so the CLI can log timing and pass/fail. serialize itself is unchanged. Config precedence: kwargs['readiness'] > healthcheck-cached percy.config.snapshot.readiness > {} (CLI applies balanced default). Disabled preset skips the evaluate call. Graceful on exception. Tests cover happy path (call order), config pass-through, disabled preset, and readiness raising. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
This PR is stale because it has been open for more than 14 days with no activity. Remove stale label or comment or this will be closed in 14 days. |
- Replaced exclusive precedence (`if None: fallback`) with shallow-merge
in a new `_resolve_readiness_config` helper. Per-snapshot kwargs['readiness']
wins, global percy_config.snapshot.readiness keys inherited — a partial
per-snapshot override no longer silently drops a global preset:disabled.
Defensive against None/wrong-type values in the CLI healthcheck payload.
- Removed the redundant `_is_percy_enabled()` re-call inside _wait_for_ready;
percy_snapshot already has the config in scope and now plumbs it through
explicitly. Avoids surprise dependency on the lru_cache for direct callers.
- Responsive capture: readiness now runs ONCE before the per-width loop
(via skip_readiness + passed-through diagnostics in get_serialized_dom)
instead of N times. With 3 widths and a 10s timeoutMs, previous behavior
could cost up to 30s of sequential waits per snapshot.
- Strip `readiness` from forwarded PercyDOM.serialize args (consumed by
_wait_for_ready upstream) AND from the POST body (CLI already has it
via healthcheck; round-tripping risks future CLI-side validators).
- Diagnostics-attach now uses `is not None` instead of truthy check —
preserves legitimate falsy returns like `{}` ("gate ran, no notable
diagnostics").
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Wrap long readiness eval string at the && to fit within 100 chars - Suppress too-many-locals on get_serialized_dom (now takes percy_config, skip_readiness, readiness_diagnostics kwargs in addition to existing cookies, percy_dom_script -- 16 locals) - Suppress too-many-locals on capture_responsive_dom (now tracks responsive_readiness_diagnostics in addition to existing 15 locals) `pylint percy/screenshot.py` rates 10/10.
CLI 1.31.15-beta.0 ships PercyDOM.waitForReady (the readiness gate). The SDK changes in this PR call waitForReady end-to-end in tests; old CLI pins (1.30.9, 1.31.10) don't have it, causing the typeof guard's done() callback path to never quite settle in geckodriver's async-script handling. Bump so tests run against a CLI that actually has the feature.
Race PercyDOM.waitForReady against a setTimeout-based Promise so a never-resolving waitForReady doesn't block the test suite. Bounds the readiness call to readiness.timeoutMs + 2s.
Mirrors percy-selenium-python: default-skip readiness in the absence
of explicit readiness config to avoid CI hangs. Users opt in via
readiness={...} kwarg or .percy.yml.
- Same opt-in fix as percy-selenium-python: detect explicit `readiness` kwarg
rather than relying on dict truthiness (empty {} should still opt in).
- Update test to expect the [readiness, deadline_ms] tuple shape that
page.evaluate now receives.
Same fix as percy-selenium-python: bypass real driver calls in the readiness tests so we don't depend on the in-page observers quiescing in CI.
Four readiness tests are skipped in CI: orchestration verified in sdk-utils tests, and the opt-in check protects every non-readiness production code path. Tracking under PER-7348; revisit when Playwright hang in GHA is reproducible locally.
Readiness tests are skipped under PER-7348 (CI hang). Coverage threshold is 100, so the readiness code paths drop the total below threshold even though they are intentionally untested in this SDK. Mark them no-cover with a pointer back to the JIRA so future cleanup is greppable.
rishigupta1599
approved these changes
May 25, 2026
….04) Same fix as percy-selenium-python: the auto-generated Dependency Submission workflow can no longer resolve the exact 3.10.3 patch from the ubuntu-24.04 toolcache. Pinning to 3.10 lets setup-python pick the latest available patch.
The old tests used the real Playwright page with side_effect patches and hung in CI under unknown conditions. New tests construct MagicMock(spec=Page) directly and exercise _wait_for_ready / _resolve_readiness_config / get_serialized_dom in isolation - no CDP traffic, no observer plumbing, no hang risk. Also removed every # pragma: no cover annotation in screenshot.py since all readiness paths are now covered.
2 tasks
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.
Summary
Adopts the readiness gate from percy/cli#2184 (PER-7348). New
_wait_for_ready(page, kwargs)helper runsPercyDOM.waitForReady(config)viapage.evaluate(sync Playwright auto-awaits Promises). Its return value is attached todom_snapshot['readiness_diagnostics']. ThePercyDOM.serializecall is unchanged.Contract
kwargs['readiness']→ healthcheck-cachedpercy.config.snapshot.readiness→{}(CLI appliesbalanceddefault).typeof PercyDOM.waitForReady === 'function'guard.Tests
4 new tests in
TestPercySnapshot: happy path (call order), config pass-through, disabled preset, readiness raising.Test results
python -c ast.parse)make test)Related