Skip to content

Commit 85dcf80

Browse files
committed
fix(ios): preserve snapshot error context
1 parent 0fd991f commit 85dcf80

3 files changed

Lines changed: 38 additions & 17 deletions

File tree

packages/capture-kit/src/ios-snapshot-engine/errors.test.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,23 @@ import { test } from 'vitest';
33
import { toIosSnapshotEngineErrorDetails } from './errors.ts';
44
import { IosSnapshotEngineError } from './types.ts';
55

6-
test('engine error details expose only the public reason and field', () => {
6+
test('engine error details preserve typed public context', () => {
77
const error = new IosSnapshotEngineError('invalid-viewport', 'invalid viewport', {
88
field: 'viewport',
99
index: 4,
10+
parentIndex: 2,
1011
frame: { x: 0, y: 0, width: 10, height: 10 },
12+
clip: { x: 1, y: 2, width: 3, height: 4 },
13+
projection: 'regular',
1114
});
1215

1316
assert.deepEqual(toIosSnapshotEngineErrorDetails(error), {
1417
reason: 'invalid-viewport',
1518
field: 'viewport',
19+
index: 4,
20+
parentIndex: 2,
21+
frame: { x: 0, y: 0, width: 10, height: 10 },
22+
clip: { x: 1, y: 2, width: 3, height: 4 },
23+
projection: 'regular',
1624
});
1725
});
Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
1-
import type { IosSnapshotEngineError, IosSnapshotEngineFailureReason } from './types.ts';
1+
import type {
2+
IosSnapshotEngineError,
3+
IosSnapshotEngineFailureDetails,
4+
IosSnapshotEngineFailureReason,
5+
} from './types.ts';
26

3-
export type IosSnapshotEnginePublicErrorDetails = Readonly<{
4-
reason: IosSnapshotEngineFailureReason;
5-
field?: string;
6-
}>;
7+
export type IosSnapshotEnginePublicErrorDetails = Readonly<
8+
IosSnapshotEngineFailureDetails & { reason: IosSnapshotEngineFailureReason }
9+
>;
710

811
export function toIosSnapshotEngineErrorDetails(
912
error: IosSnapshotEngineError,
1013
): IosSnapshotEnginePublicErrorDetails {
1114
return {
1215
reason: error.reason,
13-
...(error.details.field ? { field: error.details.field } : {}),
16+
...(error.details.index !== undefined ? { index: error.details.index } : {}),
17+
...(error.details.parentIndex !== undefined ? { parentIndex: error.details.parentIndex } : {}),
18+
...(error.details.frame !== undefined ? { frame: error.details.frame } : {}),
19+
...(error.details.clip !== undefined ? { clip: error.details.clip } : {}),
20+
...(error.details.projection !== undefined ? { projection: error.details.projection } : {}),
21+
...(error.details.field !== undefined ? { field: error.details.field } : {}),
1422
};
1523
}

packages/provider-webdriver/src/webdriver-ios-snapshot.test.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,17 @@ test('Appium iOS snapshots acquire facts and publish regular output through the
4949
});
5050

5151
test('Appium iOS options become an engine plan and engine-owned projection', () => {
52-
const acquired = acquireWebDriverIosSnapshot(SOURCE, {
53-
raw: true,
54-
interactiveOnly: true,
55-
depth: 1,
56-
scope: 'Continue',
57-
customActions: true,
58-
});
52+
const acquired = acquireWebDriverIosSnapshot(
53+
SOURCE,
54+
{
55+
raw: true,
56+
interactiveOnly: true,
57+
depth: 1,
58+
scope: 'Continue',
59+
customActions: true,
60+
},
61+
'ios-2',
62+
);
5963

6064
assert.equal(acquired.input.stage, 'acquired');
6165
assert.deepEqual(acquired.plan.narrowing, {
@@ -71,7 +75,7 @@ test('Appium iOS options become an engine plan and engine-owned projection', ()
7175
customActions: true,
7276
acquisitionIntent: 'full',
7377
});
74-
assert.deepEqual(acquired.input.acquisition.lineage, {});
78+
assert.deepEqual(acquired.input.acquisition.lineage, { targetId: 'ios-2' });
7579
assert.deepEqual(acquired.input.acquisition.viewport, {
7680
kind: 'reported',
7781
rect: { x: 0, y: 0, width: 390, height: 844 },
@@ -82,7 +86,7 @@ test('Appium iOS options become an engine plan and engine-owned projection', ()
8286
published.result.nodes?.map((node) => [node.type, node.label, node.depth, node.parentIndex]),
8387
[['XCUIElementTypeButton', 'Continue', 0, undefined]],
8488
);
85-
assert.deepEqual(published.publication.comparisonIdentity.lineage, {});
89+
assert.deepEqual(published.publication.comparisonIdentity.lineage, { targetId: 'ios-2' });
8690
});
8791

8892
test('Appium regular presentation omits unavailable hittability while raw preserves supplied facts', async () => {
@@ -93,8 +97,9 @@ test('Appium regular presentation omits unavailable hittability while raw preser
9397

9498
const regular = await captureWebDriverIosSnapshot({ source: async () => source });
9599
const regularButton = regular.nodes?.find((node) => node.label === 'Continue');
100+
assert.ok(regularButton);
96101
assert.equal(regularButton?.hittable, undefined);
97-
assert.equal('hittable' in (regularButton ?? {}), false);
102+
assert.equal('hittable' in regularButton, false);
98103

99104
const raw = await captureWebDriverIosSnapshot({ source: async () => source }, { raw: true });
100105
assert.equal(raw.nodes?.find((node) => node.label === 'Continue')?.hittable, true);

0 commit comments

Comments
 (0)