Skip to content

Commit a896332

Browse files
committed
fix: better ios step logging
1 parent 9f69957 commit a896332

File tree

11 files changed

+387
-156
lines changed

11 files changed

+387
-156
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
5
2+
[]
3+
{}
4+
"{}"
5+
"abc"
6+
{"type":"anything"}
7+
{"type":"anything","params":null}
8+
{"type":"deliverPayload","params":null}
9+
{"type":"invoke","params":null}
10+
{"type":"invoke","params":{"type":"action"}}}
11+
{"type":"invoke","params":{"type":"action","action":"accessibilityAction","params":null}}
12+
{"type":"invoke","params":{"type":"action","action":"accessibilityAction","params":[]}}
13+
{"type":"invoke","params":{"type":"action","action":"accessibilityAction","params":[],"predicate":null}}
14+
{"type":"invoke","params":{"type":"action","action":"accessibilityAction","params":[],"predicate":{"type":"unknown"}}}
15+
{"type":"invoke","params":{"type":"action","action":"accessibilityAction","params":[],"predicate":{"type":"and"}}}
16+
{"type":"invoke","params":{"type":"action","action":"accessibilityAction","params":[],"predicate":{"type":"and","predicates":null}}}
17+
{"type":"invoke","params":{"type":"action","action":"accessibilityAction","params":[],"predicate":{"type":"and","predicates":[]}}}
18+
{"type":"invoke","params":{"type":"action","action":"accessibilityAction","params":[],"predicate":{"type":"id"}}}
19+
{"type":"invoke","params":{"type":"action","action":"accessibilityAction","params":[],"predicate":{"type":"id","value":null}}}
20+
{"type":"invoke","params":{"type":"action","action":"longPress","params":[],"predicate":{"type":"id","value":"draggable"},"targetElement":null}}
21+
{"type":"invoke","params":{"type":"expectation","predicate":null,"modifiers":["not"],"expectation":"toExist"}}
22+
{"type":"invoke","params":{"type":"expectation","predicate":{"type":"and","predicates":[{"type":"id","value":"Father883","isRegex":false},{"type":"ancestor","predicate":{}}]},"modifiers":null,"expectation":"toExist"}}
23+
{"type":"invoke","params":{"type":"expectation","predicate":{"type":"and","predicates":[{"type":"id","value":"Father883","isRegex":false},{"type":"ancestor","predicate":{}}]},"modifiers":["not"],"expectation":null}}
24+
{"type":"invoke","params":{"type":"expectation","predicate":{"type":"and","predicates":[{"type":"id","value":"Father883","isRegex":false},{"type":"ancestor","predicate":{}}]},"modifiers":["not"],"expectation":"toBeWeird"}}

src/steps/description-maker/ios/__fixtures__/tap-with-ancestor.json

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,20 @@
44
"type": "action",
55
"action": "tap",
66
"predicate": {
7-
"type": "id",
8-
"value": "childButton",
9-
"ancestor": {
10-
"type": "id",
11-
"value": "parentView"
12-
}
7+
"type": "and",
8+
"predicates": [
9+
{
10+
"type": "id",
11+
"value": "childButton"
12+
},
13+
{
14+
"type": "ancestor",
15+
"predicate": {
16+
"type": "id",
17+
"value": "parentView"
18+
}
19+
}
20+
]
1321
}
1422
}
1523
}

src/steps/description-maker/ios/__snapshots__/ios-description-maker.test.ts.snap

Lines changed: 134 additions & 57 deletions
Large diffs are not rendered by default.

src/steps/description-maker/ios/detox-payload.ts

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,32 @@ export type PredicateType =
99
| 'accessibilityLabel'
1010
| 'accessibilityIdentifier';
1111

12-
export interface Predicate {
13-
type: PredicateType | 'and';
14-
value: string | string[] | number | boolean;
12+
export type Predicate =
13+
| AtomicPredicate
14+
| AncestorPredicate
15+
| DescendantPredicate
16+
| CompoundPredicate;
17+
18+
export interface CompoundPredicate {
19+
type: 'and';
20+
predicates?: Predicate[];
21+
}
22+
23+
export interface AncestorPredicate {
24+
type: 'ancestor';
25+
predicate?: Predicate;
26+
}
27+
28+
export interface DescendantPredicate {
29+
type: 'descendant';
30+
predicate?: Predicate;
31+
}
32+
33+
export interface AtomicPredicate {
34+
type?: PredicateType;
35+
value?: string | string[] | number | boolean;
1536
isRegex?: boolean;
1637
atIndex?: number;
17-
predicates?: Predicate[];
18-
ancestor?: Predicate;
19-
descendant?: Predicate;
2038
targetElement?: {
2139
predicate: Predicate;
2240
};
@@ -51,7 +69,10 @@ export type ScrollEdge = 'top' | 'bottom' | 'left' | 'right';
5169

5270
//#region Base Invocation
5371
interface BaseInvocation {
54-
predicate: Predicate;
72+
type?: string;
73+
action?: unknown;
74+
expectation?: unknown;
75+
predicate?: Predicate;
5576
timeout?: number;
5677
atIndex?: number;
5778
params?: readonly unknown[];
@@ -61,13 +82,13 @@ interface BaseInvocation {
6182
//#region Invocations
6283
export interface ExpectationInvocation extends BaseInvocation {
6384
type: 'expectation';
64-
expectation: DetoxExpectation;
85+
expectation?: DetoxExpectation;
6586
modifiers?: ExpectationModifier[];
6687
}
6788

6889
export interface BaseActionInvocation extends BaseInvocation {
6990
type: 'action';
70-
action: DetoxAction;
91+
action?: DetoxAction;
7192
while?: ExpectationInvocation;
7293
}
7394
//#endregion Invocations
@@ -151,16 +172,16 @@ export type ActionParams =
151172
//#region Messages
152173
export interface InvokeMessage {
153174
type: 'invoke';
154-
params: Invocation;
175+
params?: Invocation;
155176
}
156177

157178
export interface DeliverPayloadMessage {
158179
type: 'deliverPayload';
159-
params: DeliverPayloadParams;
180+
params?: DeliverPayloadParams;
160181
}
161182

162183
export interface DeliverPayloadParams {
163-
url: string;
184+
url?: string;
164185
delayPayload?: boolean;
165186
viewHierarchyURL?: string;
166187
detoxUserActivityDataURL?: string;

src/steps/description-maker/ios/formatters/action-formatters.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ const actionFormatters: ActionFormatterMap = {
1818

1919
scroll: ({ predicate, params: [distance, direction], while: whileCondition }) => {
2020
return concat(
21-
msg(`Scroll ${direction} on`, { direction, distance }),
21+
msg(`Scroll ${direction || 'somewhere'} on`, { direction, distance }),
2222
p(predicate),
2323
formatWhileCondition(whileCondition),
2424
);
2525
},
2626

2727
scrollTo: ({ predicate, params: [edge, normalizedX, normalizedY] }) =>
2828
concat(
29-
msg(`Scroll to ${edge}`, {
29+
msg(`Scroll to ${edge || 'edge'}`, {
3030
edge,
3131
...(normalizedX !== undefined && { x: normalizedX, y: normalizedY }),
3232
}),
@@ -40,7 +40,7 @@ const actionFormatters: ActionFormatterMap = {
4040
typeText: ({ predicate, params: [text] }) => concat(msg('Type text in', { text }), p(predicate)),
4141

4242
accessibilityAction: ({ predicate, params: [action] }) =>
43-
concat(msg(`Activate a11y "${action}" on`, { action }), p(predicate)),
43+
concat(msg(`Activate a11y ${action ? `"${action}"` : 'action'} on`, { action }), p(predicate)),
4444

4545
setDatePickerDate: ({ predicate, params: [date, format] }) =>
4646
concat('Set date picker', p(predicate), msg(`${date}`, { date, format })),
@@ -49,5 +49,6 @@ const actionFormatters: ActionFormatterMap = {
4949
// Main entry point that routes to the correct formatter based on action type
5050
export const formatAction = (action: ActionInvocation): StepDescription | null => {
5151
const formatter = actionFormatters[action.action];
52-
return formatter ? formatter(action as any) : null;
52+
const safeAction = action?.params ? action : { ...action, params: [] };
53+
return formatter ? formatter(safeAction as any) : null;
5354
};

src/steps/description-maker/ios/formatters/expectation-formatters.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
import type { StepDescription } from '../../types';
2-
import type { ExpectationInvocation } from '../detox-payload';
2+
import type { ExpectationInvocation, Invocation } from '../detox-payload';
33
import { formatPredicate } from './predicate-formatters';
44
import { concat, msg, percent, truncate } from './utils';
55

66
const formatExpectationVerb = (invocation: ExpectationInvocation): string => {
77
const hasNot = invocation.modifiers?.includes('not');
8-
const verb = invocation.expectation
9-
.replace(/([A-Z])/g, ' $1')
8+
const verb = invocation
9+
.expectation!.replace(/([A-Z])/g, ' $1')
1010
.toLowerCase()
1111
.trim();
1212
return `${hasNot ? 'not ' : ''}${verb}`;
1313
};
1414

1515
const formatExpectationParams = (invocation: ExpectationInvocation): StepDescription | null => {
16-
const [expected] = invocation.params || [];
16+
if (!Array.isArray(invocation.params)) {
17+
return null;
18+
}
19+
20+
const [expected] = invocation.params;
1721

1822
switch (invocation.expectation) {
1923
case 'toBeVisible': {
@@ -38,11 +42,15 @@ export const formatWhileCondition = (
3842
: null;
3943
};
4044

41-
export const formatExpectation = (invocation: ExpectationInvocation): StepDescription => {
45+
export const formatExpectation = (invocation: Invocation): StepDescription | null => {
46+
if (!invocation.expectation) {
47+
return null;
48+
}
49+
4250
return concat(
4351
'Expect',
4452
formatPredicate(invocation.predicate),
45-
formatExpectationVerb(invocation),
46-
formatExpectationParams(invocation),
53+
formatExpectationVerb(invocation as ExpectationInvocation),
54+
formatExpectationParams(invocation as ExpectationInvocation),
4755
);
4856
};

src/steps/description-maker/ios/formatters/message-formatters.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,20 @@ const messageFormatters: MessageFormatterMap = {
1515
const invocation = message.params;
1616
return formatInvocation(invocation);
1717
},
18-
deliverPayload: ({ params: { url, delayPayload } }) =>
19-
msg('Deliver payload', { url, delayPayload }),
18+
deliverPayload: (message) => {
19+
const data = message.params
20+
? {
21+
url: message.params.url,
22+
delayPayload: message.params.delayPayload,
23+
}
24+
: undefined;
25+
26+
return msg('Deliver payload', data);
27+
},
2028
};
2129

22-
const formatInvocation = (invocation: Invocation): StepDescription | null => {
23-
switch (invocation.type) {
30+
const formatInvocation = (invocation?: Invocation): StepDescription | null => {
31+
switch (invocation?.type) {
2432
case 'action': {
2533
return formatAction(invocation);
2634
}

0 commit comments

Comments
 (0)