@qontinui/ui-bridge-native 0.6.7 → 0.6.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/server/handlers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,KAAK,sBAAsB,EAG5B,MAAM,kBAAkB,CAAC;AAQ1B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,KAAK,EAQV,oBAAoB,EAKrB,MAAM,SAAS,CAAC;AAEjB,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAiQhF;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,sBAAsB,EAChC,QAAQ,EAAE,oBAAoB,EAC9B,MAAM,CAAC,EAAE;IACP,OAAO,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClF,iFAAiF;IACjF,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,iFAAiF;IACjF,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C;;;;;;;;;OASG;IACH,gBAAgB,CAAC,EAAE,MAAM;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5D,GACA,oBAAoB,CAy1BtB"}
1
+ {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/server/handlers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,KAAK,sBAAsB,EAG5B,MAAM,kBAAkB,CAAC;AAQ1B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,KAAK,EAQV,oBAAoB,EAKrB,MAAM,SAAS,CAAC;AAEjB,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAyThF;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,sBAAsB,EAChC,QAAQ,EAAE,oBAAoB,EAC9B,MAAM,CAAC,EAAE;IACP,OAAO,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClF,iFAAiF;IACjF,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,iFAAiF;IACjF,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C;;;;;;;;;OASG;IACH,gBAAgB,CAAC,EAAE,MAAM;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5D,GACA,oBAAoB,CA47BtB"}
@@ -1 +1 @@
1
- {"version":3,"file":"http-server.d.ts","sourceRoot":"","sources":["../../src/server/http-server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"http-server.d.ts","sourceRoot":"","sources":["../../src/server/http-server.ts"],"names":[],"mappings":"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"}
@@ -914,6 +914,35 @@ function diagnosePageHealth(elements, viewport) {
914
914
  }
915
915
 
916
916
  // src/server/handlers.ts
917
+ function matchElementsByText(registry, text, opts) {
918
+ const needle = text.toLowerCase();
919
+ const contains = (v) => typeof v === "string" && v.toLowerCase().includes(needle);
920
+ let all = registry.getAllElements();
921
+ if (opts?.visibleOnly) {
922
+ all = all.filter((e) => e.getState().visible);
923
+ }
924
+ const scored = [];
925
+ for (const e of all) {
926
+ let rank = Number.POSITIVE_INFINITY;
927
+ if (contains(e.label)) rank = Math.min(rank, 0);
928
+ const ident = e.getIdentifier();
929
+ if (ident) {
930
+ if (contains(ident.testId)) rank = Math.min(rank, 1);
931
+ if (contains(ident.accessibilityLabel)) rank = Math.min(rank, 1);
932
+ if (contains(ident.treePath)) rank = Math.min(rank, 1);
933
+ if (contains(ident.uiId)) rank = Math.min(rank, 1);
934
+ }
935
+ if (rank === Number.POSITIVE_INFINITY) {
936
+ const handlers = extractHandlerNames(e.props);
937
+ if (handlers.some((h) => h.toLowerCase().includes(needle))) rank = 2;
938
+ }
939
+ if (rank !== Number.POSITIVE_INFINITY) {
940
+ scored.push({ rank, element: { id: e.id, type: e.type, label: e.label } });
941
+ }
942
+ }
943
+ scored.sort((a, b) => a.rank - b.rank);
944
+ return scored.map((s) => s.element);
945
+ }
917
946
  async function executeWorkflowStep(step, registry, executor) {
918
947
  const startTime = Date.now();
919
948
  try {
@@ -1510,6 +1539,89 @@ function createServerHandlers(registry, executor, config) {
1510
1539
  const failedCount = results.length - succeededCount;
1511
1540
  return success2({ results, succeededCount, failedCount });
1512
1541
  },
1542
+ // ========================================================================
1543
+ // App-agnostic interaction parity (cross-platform `/control/page/*`)
1544
+ //
1545
+ // Mirrors the web/runner convenience endpoints so the SAME contract drives
1546
+ // mobile. Text/label interactions compose `executor.find` (registry-based
1547
+ // discovery) + `executor.executeAction` (press/type). Selector-only
1548
+ // variants have no React-Native analog and return NOT_SUPPORTED — the
1549
+ // mobile bridge's snapshot + `/control/find` (testID / accessibilityLabel)
1550
+ // cover what a selector would on web.
1551
+ // ========================================================================
1552
+ clickByText: async (ctx) => {
1553
+ const body = ctx.body;
1554
+ const text = typeof body?.text === "string" ? body.text.trim() : "";
1555
+ if (!text) {
1556
+ return error2("text is required and must not be empty", "INVALID_REQUEST");
1557
+ }
1558
+ const match = matchElementsByText(registry, text, { visibleOnly: body?.visibleOnly })[0];
1559
+ if (!match) {
1560
+ return error2(`No element found with text "${text}"`, "ELEMENT_NOT_FOUND");
1561
+ }
1562
+ const response = await executor.executeAction(match.id, { action: "press" });
1563
+ if (!response.success) {
1564
+ return error2(response.error || "Press failed", "ACTION_FAILED");
1565
+ }
1566
+ return success2({
1567
+ clicked: true,
1568
+ element: { id: match.id, type: match.type, label: match.label }
1569
+ });
1570
+ },
1571
+ clickBySelector: async () => {
1572
+ return error2(
1573
+ "clickBySelector is not supported on native platform \u2014 React Native has no CSS-selector DOM. Use clickByText, or /control/find with testIdPattern/accessibilityLabelPattern then /control/element/:id/action.",
1574
+ "NOT_SUPPORTED"
1575
+ );
1576
+ },
1577
+ typeInto: async (ctx) => {
1578
+ const body = ctx.body;
1579
+ const label = typeof body?.label === "string" ? body.label.trim() : "";
1580
+ if (!label) {
1581
+ return error2(
1582
+ "label is required on native (selector-based typeInto is web-only)",
1583
+ "INVALID_REQUEST"
1584
+ );
1585
+ }
1586
+ const text = typeof body?.text === "string" ? body.text : "";
1587
+ const match = matchElementsByText(registry, label, { visibleOnly: body?.visibleOnly })[0];
1588
+ if (!match) {
1589
+ return error2(`No input found for label "${label}"`, "ELEMENT_NOT_FOUND");
1590
+ }
1591
+ const response = await executor.executeAction(match.id, {
1592
+ action: "type",
1593
+ params: { text, clear: body?.clear === true }
1594
+ });
1595
+ if (!response.success) {
1596
+ return error2(response.error || "Type failed", "ACTION_FAILED");
1597
+ }
1598
+ return success2({
1599
+ typed: true,
1600
+ element: { id: match.id, type: match.type, label: match.label }
1601
+ });
1602
+ },
1603
+ readValue: async () => {
1604
+ return error2(
1605
+ "readValue is not supported on native platform \u2014 React Native has no CSS-selector DOM. Use /control/element/:id/state to read an element value.",
1606
+ "NOT_SUPPORTED"
1607
+ );
1608
+ },
1609
+ findByText: async (ctx) => {
1610
+ const body = ctx.body;
1611
+ const text = typeof body?.text === "string" ? body.text.trim() : "";
1612
+ if (!text) {
1613
+ return error2("text is required and must not be empty", "INVALID_REQUEST");
1614
+ }
1615
+ const matches = matchElementsByText(registry, text, { visibleOnly: body?.visibleOnly });
1616
+ return success2(
1617
+ matches.map((el, index) => ({
1618
+ index,
1619
+ id: el.id,
1620
+ type: el.type,
1621
+ label: el.label
1622
+ }))
1623
+ );
1624
+ },
1513
1625
  // Coord-based tap
1514
1626
  //
1515
1627
  // Synthesizes a press at the given screen coordinates by scanning the
@@ -2116,6 +2228,17 @@ var WS_ROUTES = [
2116
2228
  // Coord-based tap — synthesizes a press at the given screen coords by
2117
2229
  // matching against registered elements' layout rects.
2118
2230
  { pattern: "control/tap", handler: "tapAt", httpMethods: ["POST"] },
2231
+ // App-agnostic interaction parity — mirrors the web/runner convenience
2232
+ // endpoints (`/control/page/click-by-text` etc.) so the SAME cross-platform
2233
+ // contract drives mobile. Text/label-based interactions compose
2234
+ // `executor.find` + `executor.executeAction` over the registry; the
2235
+ // DOM-selector-only variants (`click-by-selector`, `read-value`) have no RN
2236
+ // analog and return a structured NOT_SUPPORTED envelope.
2237
+ { pattern: "control/page/click-by-text", handler: "clickByText", httpMethods: ["POST"] },
2238
+ { pattern: "control/page/click-by-selector", handler: "clickBySelector", httpMethods: ["POST"] },
2239
+ { pattern: "control/page/type-into", handler: "typeInto", httpMethods: ["POST"] },
2240
+ { pattern: "control/page/read-value", handler: "readValue", httpMethods: ["POST"] },
2241
+ { pattern: "control/page/find-by-text", handler: "findByText", httpMethods: ["POST"] },
2119
2242
  // Test hooks — gated behind `features.testHooks`. Let external runners
2120
2243
  // drive the ModalDetector over HTTP so tests can flip `snapshot.modalStack`
2121
2244
  // without mounting React components.
@@ -2191,6 +2314,11 @@ var HANDLER_DESCRIPTIONS = {
2191
2314
  aiChangeBufferEnable: "STUB \u2014 runner-only; mobile returns NOT_SUPPORTED. Use WS event subscriptions for change notifications.",
2192
2315
  aiWaitForElement: "STUB \u2014 runner-only; mobile returns NOT_SUPPORTED. Use the WS waitForElement / waitForCondition JSON-RPC methods.",
2193
2316
  tapAt: "Synthesize a press at given screen coords by matching registered element layout rects: body { x, y, action? }",
2317
+ clickByText: "App-agnostic: press the first element matching free-text (label/accessibilityLabel/testID): body { text, visibleOnly? }",
2318
+ clickBySelector: "STUB \u2014 selector-based; NOT_SUPPORTED on native (no DOM). Use clickByText or /control/find + /control/element/:id/action.",
2319
+ typeInto: "App-agnostic: type into the input matching a label: body { label, text, clear?, visibleOnly? }. (selector form is web-only)",
2320
+ readValue: "STUB \u2014 selector-based; NOT_SUPPORTED on native (no DOM). Use /control/element/:id/state to read a value.",
2321
+ findByText: "App-agnostic: list elements matching free-text (no press): body { text, visibleOnly? }",
2194
2322
  getConsoleErrors: "TEST HOOK \u2014 last-N console.error/console.warn entries; ?since=<ms>&limit=<n>",
2195
2323
  getNetworkRequests: "TEST HOOK \u2014 last-N fetch/XHR entries with status + duration; ?since=<ms>&limit=<n>",
2196
2324
  pushModal: "TEST HOOK \u2014 push a modal onto the snapshot.modalStack via the registry ModalDetector",