🐛 Flatten nested properties in screenshot upload payload#221
🐛 Flatten nested properties in screenshot upload payload#221
Conversation
When callers pass { properties: { url, viewport } } as options,
the payload was sent as properties: { properties: { url } } — double
nesting. The server read properties.url (top-level) and got undefined.
Spread options.properties into the top level so url, viewport, etc.
are accessible directly as properties.url on the server side.
This comment has been minimized.
This comment has been minimized.
Code ReviewI've reviewed PR #221 and the fix looks good overall. Here's my analysis: SummaryThe fix correctly addresses the double-nesting issue where Positive Aspects
Issues & Concerns1. Missing Test for Nested Properties CaseThe current test at line 377 only tests flat options ( Recommendation: Add a test case like: it('flattens nested properties object', async () => {
await vizzlyScreenshot('test', Buffer.from('data'), {
properties: {
url: 'https://example.com',
viewport: '1920x1080'
},
browser: 'chrome'
});
assert.strictEqual(requests.length, 1);
assert.strictEqual(requests[0].body.properties.url, 'https://example.com');
assert.strictEqual(requests[0].body.properties.viewport, '1920x1080');
assert.strictEqual(requests[0].body.properties.browser, 'chrome');
// Verify no double-nesting
assert.strictEqual(requests[0].body.properties.properties, undefined);
});2. Potential Property CollisionThe spread order { url: 'A', properties: { url: 'B' } }The nested Question: Should we warn/error if there are conflicting properties, or is this override behavior intended? 3. Documentation GapThe JSDoc at line 316 documents vizzlyScreenshot('test', img, { url: 'foo' }) // Direct
vizzlyScreenshot('test', img, { properties: { url: 'foo' } }) // NestedRecommendation: Update the JSDoc to clarify this behavior. 4. Static Site Client ImpactThe static-site client at
Test Plan CompletenessThe PR description mentions:
Recommendation: Complete the remaining test plan items before merging. Security ConsiderationsNo security concerns. The PerformanceNo performance impact. The spread operation is negligible. Code Quality
Verdict✅ Approve with recommendations: The core fix is correct, but please add the test case for nested properties and verify the static-site integration works as expected. |
buildScreenshotCheckObject was only sending sha256, name, browser, and viewport — no url or metadata. When the server reused screenshots by SHA match, it copied the old null URL instead of using the new one.
Vizzly - Visual Test ResultsCLI Reporter - 1 change needs review
|
|
Closing in favor of a proper fix that addresses the root cause in the client SDK. Instead of patching the server to handle double-nested properties, the client now properly separates SDK options ( |
## Summary
- The client SDK was sending the entire `options` object as
`properties`, causing double-nesting when SDKs passed `{ properties: {
url } }` — the server received `properties: { properties: { url } }`
making `url` unreachable
- Now destructures SDK-internal options (`fullPage`, `threshold`) out
and flattens `options.properties` into the top-level properties object
- Adds tests verifying properties flattening and that SDK options don't
leak into properties
- Closes #221 — this fixes the root cause instead of patching around it
server-side
## Context
After the URL capture change (#220), Storybook and Static Site SDKs
passed `{ properties: { url: page.url() } }` to `vizzlyScreenshot()`.
The client blindly forwarded the whole options object as `properties`,
double-nesting the data. A server-side fallback
(`properties.properties?.url`) was deployed as a stopgap — this fix
makes that fallback unnecessary.
## Test plan
- [x] `npm test` — 1894 pass, 0 fail
- [x] `npm run lint` — clean
- [x] New test: verifies `{ properties: { url } }` flattens to `{ url }`
in the payload
- [x] New test: verifies `fullPage` and `threshold` are excluded from
properties
- [x] Existing integration tests still pass (no breaking changes)

Summary
{ properties: { url, viewport } }as options tovizzlyScreenshot(), the client sentproperties: { properties: { url } }— double-nesting the dataproperties.url(top-level) and gotundefined, soscreenshots.urlwas never populated for static site uploadscanLinkToPreview()needs a valid URL fromcomparison.current_urloptions.propertiesinto the top level sourl,viewport, etc. are directly accessibleContext
Server-side fallback already deployed (
properties.properties?.url) but this fixes the source of the nesting bug.Test plan
screenshots.urlis populated