Skip to content

Commit 38e3569

Browse files
authored
Merge pull request #163 from Lykhoyda/test/maestro-error-parser-1.0.9-patterns
test(gh-105): parser unit tests for maestro-runner 1.0.9 stderr shape
2 parents a5d7071 + 589304f commit 38e3569

1 file changed

Lines changed: 74 additions & 0 deletions

File tree

scripts/cdp-bridge/test/unit/maestro-error-parser.test.js

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,3 +208,77 @@ exit code 1
208208
assert.equal(out.selectorKind, 'id');
209209
assert.equal(out.selector, 'fab-create-task');
210210
});
211+
212+
// ─────────────────────────────────────────────────────────────────────────────
213+
// GH #105 / B152: maestro-runner 1.0.9 stderr shape
214+
// ─────────────────────────────────────────────────────────────────────────────
215+
// The shape `Element not found: id='X'` (with colon + equals) is emitted by
216+
// maestro-runner 1.0.9+. Before PR #159 the parser only recognized the
217+
// classic `Element with id 'X' not found` shape and returned UNKNOWN for
218+
// the modern form — silently disabling the L3 self-healing loop. These
219+
// tests pin the new patterns so a regression would be immediately visible.
220+
221+
test('parser: 1.0.9 shape — id=\'X\' single-quoted', () => {
222+
const out = parseMaestroFailure(" ✗ tapOn: id=\"task-mark-all-done\" (12.7s)\n ╰─ Element not found: id='task-mark-all-done'\n");
223+
assert.equal(out.kind, 'SELECTOR_NOT_FOUND');
224+
assert.equal(out.selectorKind, 'id');
225+
assert.equal(out.selector, 'task-mark-all-done');
226+
});
227+
228+
test('parser: 1.0.9 shape — id="X" double-quoted', () => {
229+
const out = parseMaestroFailure('Element not found: id="btn-submit"');
230+
assert.equal(out.kind, 'SELECTOR_NOT_FOUND');
231+
assert.equal(out.selectorKind, 'id');
232+
assert.equal(out.selector, 'btn-submit');
233+
});
234+
235+
test('parser: 1.0.9 shape — text=\'X\' single-quoted', () => {
236+
const out = parseMaestroFailure("Element not found: text='All done'");
237+
assert.equal(out.kind, 'SELECTOR_NOT_FOUND');
238+
assert.equal(out.selectorKind, 'text');
239+
assert.equal(out.selector, 'All done');
240+
});
241+
242+
test('parser: 1.0.9 shape — extra whitespace between : and id= tolerated', () => {
243+
// maestro-runner formatting could insert any amount of whitespace; the
244+
// pattern uses \s* so this must match.
245+
const out = parseMaestroFailure("Element not found: id='spinner'");
246+
assert.equal(out.kind, 'SELECTOR_NOT_FOUND');
247+
assert.equal(out.selector, 'spinner');
248+
});
249+
250+
test('parser: 1.0.9 shape — embedded opposite quote in id (e.g. user\\\'s-tasks)', () => {
251+
// Matched-quote backreference pattern allows the opposite quote inside
252+
// the value. Same invariant we test for the classic shape (line 176-189).
253+
const out = parseMaestroFailure(`Element not found: id="say-'hi'-btn"`);
254+
assert.equal(out.kind, 'SELECTOR_NOT_FOUND');
255+
assert.equal(out.selector, "say-'hi'-btn");
256+
});
257+
258+
test('parser: 1.0.9 shape — full realistic maestro-runner 1.0.9 stderr', () => {
259+
// Captured verbatim from the #105 MTTR experiment session. The earlier
260+
// classic patterns must NOT match (no "Element with id 'X' not found"
261+
// string), but the new 1.0.9 patterns must classify correctly.
262+
const realistic = `maestro-runner 1.0.9 - by DeviceLab.dev
263+
✓ launchApp (2.3s)
264+
✓ tapOn: id="tab-tasks" (2.8s)
265+
✓ assertVisible: text="Tasks" (1.3s)
266+
✗ tapOn: id="task-mark-all-done" (12.7s)
267+
╰─ Element not found: id='task-mark-all-done'
268+
3 steps passing
269+
1 steps failing
270+
✗ rn-maestro-run 23.8s`;
271+
const out = parseMaestroFailure(realistic);
272+
assert.equal(out.kind, 'SELECTOR_NOT_FOUND', `expected SELECTOR_NOT_FOUND, got ${out.kind} — the 1.0.9 pattern MUST match this verbatim stderr`);
273+
assert.equal(out.selectorKind, 'id');
274+
assert.equal(out.selector, 'task-mark-all-done');
275+
});
276+
277+
test('parser: 1.0.9 id= shape has priority over the generic fallback', () => {
278+
// The 1.0.9 id= pattern is more specific than the catch-all "Element 'X' not found".
279+
// Pattern order in maestro-error-parser.ts MUST keep id-shape ahead of the fallback.
280+
// If a regression reorders patterns, this test catches it.
281+
const out = parseMaestroFailure("Element not found: id='specific-id'\nAlso seen: Element 'fallback-id' not found");
282+
assert.equal(out.selectorKind, 'id', 'id= shape must win over fallback when both present');
283+
assert.equal(out.selector, 'specific-id');
284+
});

0 commit comments

Comments
 (0)