@testdroid-ai/cli 0.1.2
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.
- package/dist/adb/adb-path-resolver.d.ts +6 -0
- package/dist/adb/adb-path-resolver.d.ts.map +1 -0
- package/dist/adb/adb-path-resolver.js +93 -0
- package/dist/adb/adb-path-resolver.js.map +1 -0
- package/dist/adb/adb-shell.d.ts +29 -0
- package/dist/adb/adb-shell.d.ts.map +1 -0
- package/dist/adb/adb-shell.js +128 -0
- package/dist/adb/adb-shell.js.map +1 -0
- package/dist/adb/detector.d.ts +12 -0
- package/dist/adb/detector.d.ts.map +1 -0
- package/dist/adb/detector.js +44 -0
- package/dist/adb/detector.js.map +1 -0
- package/dist/adb/device-tracker.d.ts +23 -0
- package/dist/adb/device-tracker.d.ts.map +1 -0
- package/dist/adb/device-tracker.js +134 -0
- package/dist/adb/device-tracker.js.map +1 -0
- package/dist/adb/emulator-detector.d.ts +11 -0
- package/dist/adb/emulator-detector.d.ts.map +1 -0
- package/dist/adb/emulator-detector.js +54 -0
- package/dist/adb/emulator-detector.js.map +1 -0
- package/dist/appium/health-check.d.ts +6 -0
- package/dist/appium/health-check.d.ts.map +1 -0
- package/dist/appium/health-check.js +61 -0
- package/dist/appium/health-check.js.map +1 -0
- package/dist/appium/session-manager.d.ts +15 -0
- package/dist/appium/session-manager.d.ts.map +1 -0
- package/dist/appium/session-manager.js +82 -0
- package/dist/appium/session-manager.js.map +1 -0
- package/dist/auth/credential-store.d.ts +31 -0
- package/dist/auth/credential-store.d.ts.map +1 -0
- package/dist/auth/credential-store.js +154 -0
- package/dist/auth/credential-store.js.map +1 -0
- package/dist/auth/pairing-auth.d.ts +26 -0
- package/dist/auth/pairing-auth.d.ts.map +1 -0
- package/dist/auth/pairing-auth.js +177 -0
- package/dist/auth/pairing-auth.js.map +1 -0
- package/dist/auth/token-manager.d.ts +20 -0
- package/dist/auth/token-manager.d.ts.map +1 -0
- package/dist/auth/token-manager.js +101 -0
- package/dist/auth/token-manager.js.map +1 -0
- package/dist/commands/connect.d.ts +9 -0
- package/dist/commands/connect.d.ts.map +1 -0
- package/dist/commands/connect.js +270 -0
- package/dist/commands/connect.js.map +1 -0
- package/dist/commands/devices.d.ts +2 -0
- package/dist/commands/devices.d.ts.map +1 -0
- package/dist/commands/devices.js +52 -0
- package/dist/commands/devices.js.map +1 -0
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +214 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/mirror.d.ts +2 -0
- package/dist/commands/mirror.d.ts.map +1 -0
- package/dist/commands/mirror.js +77 -0
- package/dist/commands/mirror.js.map +1 -0
- package/dist/commands/prompt.d.ts +12 -0
- package/dist/commands/prompt.d.ts.map +1 -0
- package/dist/commands/prompt.js +174 -0
- package/dist/commands/prompt.js.map +1 -0
- package/dist/commands/record.d.ts +7 -0
- package/dist/commands/record.d.ts.map +1 -0
- package/dist/commands/record.js +129 -0
- package/dist/commands/record.js.map +1 -0
- package/dist/commands/run.d.ts +16 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +271 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/setup.d.ts +6 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +50 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +32 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/healing/ai-adapter.d.ts +44 -0
- package/dist/healing/ai-adapter.d.ts.map +1 -0
- package/dist/healing/ai-adapter.js +87 -0
- package/dist/healing/ai-adapter.js.map +1 -0
- package/dist/healing/healer.d.ts +109 -0
- package/dist/healing/healer.d.ts.map +1 -0
- package/dist/healing/healer.js +475 -0
- package/dist/healing/healer.js.map +1 -0
- package/dist/healing/similarity.d.ts +63 -0
- package/dist/healing/similarity.d.ts.map +1 -0
- package/dist/healing/similarity.js +172 -0
- package/dist/healing/similarity.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +107 -0
- package/dist/index.js.map +1 -0
- package/dist/recording/capture-strategies/capture-strategy.interface.d.ts +6 -0
- package/dist/recording/capture-strategies/capture-strategy.interface.d.ts.map +1 -0
- package/dist/recording/capture-strategies/capture-strategy.interface.js +3 -0
- package/dist/recording/capture-strategies/capture-strategy.interface.js.map +1 -0
- package/dist/recording/capture-strategies/getevent.strategy.d.ts +27 -0
- package/dist/recording/capture-strategies/getevent.strategy.d.ts.map +1 -0
- package/dist/recording/capture-strategies/getevent.strategy.js +163 -0
- package/dist/recording/capture-strategies/getevent.strategy.js.map +1 -0
- package/dist/recording/capture-strategies/key-capture.strategy.d.ts +16 -0
- package/dist/recording/capture-strategies/key-capture.strategy.d.ts.map +1 -0
- package/dist/recording/capture-strategies/key-capture.strategy.js +67 -0
- package/dist/recording/capture-strategies/key-capture.strategy.js.map +1 -0
- package/dist/recording/capture-strategies/logcat-capture.strategy.d.ts +32 -0
- package/dist/recording/capture-strategies/logcat-capture.strategy.d.ts.map +1 -0
- package/dist/recording/capture-strategies/logcat-capture.strategy.js +176 -0
- package/dist/recording/capture-strategies/logcat-capture.strategy.js.map +1 -0
- package/dist/recording/confidence-scorer.d.ts +13 -0
- package/dist/recording/confidence-scorer.d.ts.map +1 -0
- package/dist/recording/confidence-scorer.js +34 -0
- package/dist/recording/confidence-scorer.js.map +1 -0
- package/dist/recording/event-capture.d.ts +40 -0
- package/dist/recording/event-capture.d.ts.map +1 -0
- package/dist/recording/event-capture.js +168 -0
- package/dist/recording/event-capture.js.map +1 -0
- package/dist/recording/recorder.d.ts +32 -0
- package/dist/recording/recorder.d.ts.map +1 -0
- package/dist/recording/recorder.js +107 -0
- package/dist/recording/recorder.js.map +1 -0
- package/dist/runner/adb-executor.d.ts +116 -0
- package/dist/runner/adb-executor.d.ts.map +1 -0
- package/dist/runner/adb-executor.js +323 -0
- package/dist/runner/adb-executor.js.map +1 -0
- package/dist/runner/appium-executor.d.ts +35 -0
- package/dist/runner/appium-executor.d.ts.map +1 -0
- package/dist/runner/appium-executor.js +191 -0
- package/dist/runner/appium-executor.js.map +1 -0
- package/dist/runner/parse-strategies/appium-default.strategy.d.ts +12 -0
- package/dist/runner/parse-strategies/appium-default.strategy.d.ts.map +1 -0
- package/dist/runner/parse-strategies/appium-default.strategy.js +342 -0
- package/dist/runner/parse-strategies/appium-default.strategy.js.map +1 -0
- package/dist/runner/parse-strategies/index.d.ts +7 -0
- package/dist/runner/parse-strategies/index.d.ts.map +1 -0
- package/dist/runner/parse-strategies/index.js +14 -0
- package/dist/runner/parse-strategies/index.js.map +1 -0
- package/dist/runner/parse-strategies/java.strategy.d.ts +8 -0
- package/dist/runner/parse-strategies/java.strategy.d.ts.map +1 -0
- package/dist/runner/parse-strategies/java.strategy.js +170 -0
- package/dist/runner/parse-strategies/java.strategy.js.map +1 -0
- package/dist/runner/parse-strategies/maestro.strategy.d.ts +8 -0
- package/dist/runner/parse-strategies/maestro.strategy.d.ts.map +1 -0
- package/dist/runner/parse-strategies/maestro.strategy.js +105 -0
- package/dist/runner/parse-strategies/maestro.strategy.js.map +1 -0
- package/dist/runner/parse-strategies/python.strategy.d.ts +8 -0
- package/dist/runner/parse-strategies/python.strategy.d.ts.map +1 -0
- package/dist/runner/parse-strategies/python.strategy.js +140 -0
- package/dist/runner/parse-strategies/python.strategy.js.map +1 -0
- package/dist/runner/parse-strategies/robot.strategy.d.ts +8 -0
- package/dist/runner/parse-strategies/robot.strategy.d.ts.map +1 -0
- package/dist/runner/parse-strategies/robot.strategy.js +81 -0
- package/dist/runner/parse-strategies/robot.strategy.js.map +1 -0
- package/dist/runner/parse-strategies/types.d.ts +17 -0
- package/dist/runner/parse-strategies/types.d.ts.map +1 -0
- package/dist/runner/parse-strategies/types.js +3 -0
- package/dist/runner/parse-strategies/types.js.map +1 -0
- package/dist/runner/parse-strategies/utils.d.ts +39 -0
- package/dist/runner/parse-strategies/utils.d.ts.map +1 -0
- package/dist/runner/parse-strategies/utils.js +217 -0
- package/dist/runner/parse-strategies/utils.js.map +1 -0
- package/dist/runner/script-parser.d.ts +43 -0
- package/dist/runner/script-parser.d.ts.map +1 -0
- package/dist/runner/script-parser.js +68 -0
- package/dist/runner/script-parser.js.map +1 -0
- package/dist/runner/selector-resolver.d.ts +87 -0
- package/dist/runner/selector-resolver.d.ts.map +1 -0
- package/dist/runner/selector-resolver.js +206 -0
- package/dist/runner/selector-resolver.js.map +1 -0
- package/dist/runner/step-executor.d.ts +112 -0
- package/dist/runner/step-executor.d.ts.map +1 -0
- package/dist/runner/step-executor.js +518 -0
- package/dist/runner/step-executor.js.map +1 -0
- package/dist/runner/test-runner.d.ts +89 -0
- package/dist/runner/test-runner.d.ts.map +1 -0
- package/dist/runner/test-runner.js +320 -0
- package/dist/runner/test-runner.js.map +1 -0
- package/dist/scrcpy/launcher.d.ts +16 -0
- package/dist/scrcpy/launcher.d.ts.map +1 -0
- package/dist/scrcpy/launcher.js +87 -0
- package/dist/scrcpy/launcher.js.map +1 -0
- package/dist/services/device-poller.d.ts +10 -0
- package/dist/services/device-poller.d.ts.map +1 -0
- package/dist/services/device-poller.js +44 -0
- package/dist/services/device-poller.js.map +1 -0
- package/dist/services/execution-manager.d.ts +18 -0
- package/dist/services/execution-manager.d.ts.map +1 -0
- package/dist/services/execution-manager.js +185 -0
- package/dist/services/execution-manager.js.map +1 -0
- package/dist/services/recording-manager.d.ts +13 -0
- package/dist/services/recording-manager.d.ts.map +1 -0
- package/dist/services/recording-manager.js +234 -0
- package/dist/services/recording-manager.js.map +1 -0
- package/dist/setup/adb-installer.d.ts +8 -0
- package/dist/setup/adb-installer.d.ts.map +1 -0
- package/dist/setup/adb-installer.js +115 -0
- package/dist/setup/adb-installer.js.map +1 -0
- package/dist/setup/appium-installer.d.ts +8 -0
- package/dist/setup/appium-installer.d.ts.map +1 -0
- package/dist/setup/appium-installer.js +113 -0
- package/dist/setup/appium-installer.js.map +1 -0
- package/dist/setup/base-installer.d.ts +33 -0
- package/dist/setup/base-installer.d.ts.map +1 -0
- package/dist/setup/base-installer.js +170 -0
- package/dist/setup/base-installer.js.map +1 -0
- package/dist/setup/build-tools-installer.d.ts +8 -0
- package/dist/setup/build-tools-installer.d.ts.map +1 -0
- package/dist/setup/build-tools-installer.js +109 -0
- package/dist/setup/build-tools-installer.js.map +1 -0
- package/dist/setup/java-installer.d.ts +8 -0
- package/dist/setup/java-installer.d.ts.map +1 -0
- package/dist/setup/java-installer.js +132 -0
- package/dist/setup/java-installer.js.map +1 -0
- package/dist/setup/paths.d.ts +12 -0
- package/dist/setup/paths.d.ts.map +1 -0
- package/dist/setup/paths.js +90 -0
- package/dist/setup/paths.js.map +1 -0
- package/dist/setup/scrcpy-installer.d.ts +8 -0
- package/dist/setup/scrcpy-installer.d.ts.map +1 -0
- package/dist/setup/scrcpy-installer.js +143 -0
- package/dist/setup/scrcpy-installer.js.map +1 -0
- package/dist/setup/setup-manager.d.ts +18 -0
- package/dist/setup/setup-manager.d.ts.map +1 -0
- package/dist/setup/setup-manager.js +113 -0
- package/dist/setup/setup-manager.js.map +1 -0
- package/dist/ws/socket.d.ts +38 -0
- package/dist/ws/socket.d.ts.map +1 -0
- package/dist/ws/socket.js +91 -0
- package/dist/ws/socket.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { AdbExecutor } from '../runner/adb-executor';
|
|
2
|
+
import { HealingResult, HealingSelectorType } from '@testdroid-ai/shared';
|
|
3
|
+
import { AiHealingAdapter } from './ai-adapter';
|
|
4
|
+
/**
|
|
5
|
+
* Motor de self-healing para testes Android.
|
|
6
|
+
*
|
|
7
|
+
* Quando um elemento nao e encontrado pelo seletor original,
|
|
8
|
+
* o Healer tenta encontra-lo usando estrategias alternativas:
|
|
9
|
+
*
|
|
10
|
+
* 1. text_match - Busca por texto similar (fuzzy match via Levenshtein)
|
|
11
|
+
* 2. accessibility_tree - Busca por content-description
|
|
12
|
+
* 3. visual_similarity - Busca por classe + posicao relativa
|
|
13
|
+
* 4. parent_child - Busca por resourceId prefix + sibling com texto similar
|
|
14
|
+
* 5. bounds_proximity - Busca por classe + conteudo mais proximo
|
|
15
|
+
* 6. ai_analysis - Analise via Claude AI (se ANTHROPIC_API_KEY disponivel)
|
|
16
|
+
*/
|
|
17
|
+
export declare class Healer {
|
|
18
|
+
private adb;
|
|
19
|
+
private aiAdapter;
|
|
20
|
+
constructor(adb: AdbExecutor, aiAdapter?: AiHealingAdapter);
|
|
21
|
+
/**
|
|
22
|
+
* Tenta curar um seletor que falhou em encontrar um elemento.
|
|
23
|
+
*
|
|
24
|
+
* Obtem a hierarquia UI via ADB e executa as estrategias em sequencia.
|
|
25
|
+
* Use este metodo quando nenhuma sessao UiAutomator2 esta activa.
|
|
26
|
+
*
|
|
27
|
+
* @param failedSelector Seletor original que nao encontrou o elemento
|
|
28
|
+
* @param selectorType Tipo do seletor original
|
|
29
|
+
* @returns Resultado do healing com novo seletor ou erro
|
|
30
|
+
*/
|
|
31
|
+
heal(failedSelector: string, selectorType: HealingSelectorType): Promise<HealingResult>;
|
|
32
|
+
/**
|
|
33
|
+
* Heals a selector using pre-fetched XML hierarchy.
|
|
34
|
+
* Use when UiAutomator2 session is active (adb dumpUi would conflict).
|
|
35
|
+
*
|
|
36
|
+
* @param xml XML hierarchy from driver.getPageSource()
|
|
37
|
+
* @param failedSelector Seletor original que nao encontrou o elemento
|
|
38
|
+
* @param selectorType Tipo do seletor original
|
|
39
|
+
* @returns Resultado do healing com novo seletor ou erro
|
|
40
|
+
*/
|
|
41
|
+
healWithXml(xml: string, failedSelector: string, selectorType: HealingSelectorType): Promise<HealingResult>;
|
|
42
|
+
/**
|
|
43
|
+
* Executa todas as estrategias de healing em sequencia.
|
|
44
|
+
* Retorna na primeira que encontrar match acima do limiar.
|
|
45
|
+
*/
|
|
46
|
+
private runStrategies;
|
|
47
|
+
/**
|
|
48
|
+
* Mapa de padroes para extrair informacoes de seletores.
|
|
49
|
+
* Cada entrada define o tipo, o teste para identificar e a funcao de extracao.
|
|
50
|
+
*/
|
|
51
|
+
private readonly selectorPatterns;
|
|
52
|
+
/**
|
|
53
|
+
* Extrai informacoes estruturadas de um seletor usando o mapa de padroes.
|
|
54
|
+
*/
|
|
55
|
+
private parseSelectorInfo;
|
|
56
|
+
/**
|
|
57
|
+
* Determina o tipo de seletor com base no formato.
|
|
58
|
+
*/
|
|
59
|
+
static detectSelectorType(selector: string): HealingSelectorType;
|
|
60
|
+
/**
|
|
61
|
+
* Constroi um HealingResult de sucesso.
|
|
62
|
+
* Evita duplicacao do objeto em cada estrategia.
|
|
63
|
+
*/
|
|
64
|
+
private buildSuccessResult;
|
|
65
|
+
/**
|
|
66
|
+
* Estrategia 1: Busca por texto similar (fuzzy match).
|
|
67
|
+
* Faz dump da UI, encontra elementos com texto similar ao original.
|
|
68
|
+
*/
|
|
69
|
+
private tryTextMatch;
|
|
70
|
+
/**
|
|
71
|
+
* Estrategia 2: Busca por content-description (accessibility).
|
|
72
|
+
* Verifica atributos de acessibilidade dos elementos.
|
|
73
|
+
*/
|
|
74
|
+
private tryAccessibilityMatch;
|
|
75
|
+
/**
|
|
76
|
+
* Estrategia 3: Busca por classe + posicao visual.
|
|
77
|
+
* Encontra elementos da mesma classe em posicao similar.
|
|
78
|
+
*/
|
|
79
|
+
private tryVisualSimilarity;
|
|
80
|
+
/**
|
|
81
|
+
* Estrategia 4: Busca por prefixo de resourceId (parent-child context).
|
|
82
|
+
*
|
|
83
|
+
* Android resourceIds follow the pattern "com.app.package:id/view_name".
|
|
84
|
+
* When the original element had a resourceId like "com.app:id/submit_button",
|
|
85
|
+
* this strategy finds other elements that share the same package prefix and
|
|
86
|
+
* have similar text or class — a proxy for "sibling in same container".
|
|
87
|
+
*/
|
|
88
|
+
private tryParentChildMatch;
|
|
89
|
+
/**
|
|
90
|
+
* Estrategia 5: Busca por classe + conteudo mais proximo.
|
|
91
|
+
*
|
|
92
|
+
* When resourceId has changed but the element class and content are stable,
|
|
93
|
+
* this strategy scans all elements of the same class and picks the one
|
|
94
|
+
* whose text/contentDesc best matches the original selector info.
|
|
95
|
+
*/
|
|
96
|
+
private tryBoundsProximity;
|
|
97
|
+
/**
|
|
98
|
+
* Estrategia 6: Analise por AI via adapter.
|
|
99
|
+
* Delega ao AiHealingAdapter injectado no construtor.
|
|
100
|
+
* So funciona se o adapter estiver disponivel.
|
|
101
|
+
*/
|
|
102
|
+
private tryAiAnalysis;
|
|
103
|
+
/**
|
|
104
|
+
* Constroi um novo seletor a partir de um elemento encontrado.
|
|
105
|
+
* Prioriza resourceId > text > contentDesc.
|
|
106
|
+
*/
|
|
107
|
+
private buildNewSelector;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=healer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"healer.d.ts","sourceRoot":"","sources":["../../src/healing/healer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EACL,aAAa,EACb,mBAAmB,EAEpB,MAAM,sBAAsB,CAAC;AAO9B,OAAO,EACL,gBAAgB,EAEjB,MAAM,cAAc,CAAC;AAOtB;;;;;;;;;;;;GAYG;AACH,qBAAa,MAAM;IAIf,OAAO,CAAC,GAAG;IAHb,OAAO,CAAC,SAAS,CAAmB;gBAG1B,GAAG,EAAE,WAAW,EACxB,SAAS,CAAC,EAAE,gBAAgB;IAK9B;;;;;;;;;OASG;IACG,IAAI,CACR,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,mBAAmB,GAChC,OAAO,CAAC,aAAa,CAAC;IAoBzB;;;;;;;;OAQG;IACG,WAAW,CACf,GAAG,EAAE,MAAM,EACX,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,mBAAmB,GAChC,OAAO,CAAC,aAAa,CAAC;IAQzB;;;OAGG;YACW,aAAa;IA+D3B;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CA8E/B;IAEF;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAezB;;OAEG;IACH,MAAM,CAAC,kBAAkB,CACvB,QAAQ,EAAE,MAAM,GACf,mBAAmB;IAoBtB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IA2B1B;;;OAGG;IACH,OAAO,CAAC,YAAY;IA6BpB;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IA+C7B;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAgE3B;;;;;;;OAOG;IACH,OAAO,CAAC,mBAAmB;IAoD3B;;;;;;OAMG;IACH,OAAO,CAAC,kBAAkB;IA6D1B;;;;OAIG;YACW,aAAa;IAmC3B;;;OAGG;IACH,OAAO,CAAC,gBAAgB;CAqCzB"}
|
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Healer = void 0;
|
|
4
|
+
const similarity_1 = require("./similarity");
|
|
5
|
+
const ai_adapter_1 = require("./ai-adapter");
|
|
6
|
+
/**
|
|
7
|
+
* Limiar minimo de confianca para aceitar um healing.
|
|
8
|
+
*/
|
|
9
|
+
const CONFIDENCE_THRESHOLD = 70;
|
|
10
|
+
/**
|
|
11
|
+
* Motor de self-healing para testes Android.
|
|
12
|
+
*
|
|
13
|
+
* Quando um elemento nao e encontrado pelo seletor original,
|
|
14
|
+
* o Healer tenta encontra-lo usando estrategias alternativas:
|
|
15
|
+
*
|
|
16
|
+
* 1. text_match - Busca por texto similar (fuzzy match via Levenshtein)
|
|
17
|
+
* 2. accessibility_tree - Busca por content-description
|
|
18
|
+
* 3. visual_similarity - Busca por classe + posicao relativa
|
|
19
|
+
* 4. parent_child - Busca por resourceId prefix + sibling com texto similar
|
|
20
|
+
* 5. bounds_proximity - Busca por classe + conteudo mais proximo
|
|
21
|
+
* 6. ai_analysis - Analise via Claude AI (se ANTHROPIC_API_KEY disponivel)
|
|
22
|
+
*/
|
|
23
|
+
class Healer {
|
|
24
|
+
adb;
|
|
25
|
+
aiAdapter;
|
|
26
|
+
constructor(adb, aiAdapter) {
|
|
27
|
+
this.adb = adb;
|
|
28
|
+
this.aiAdapter = aiAdapter ?? new ai_adapter_1.AnthropicAdapter();
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Tenta curar um seletor que falhou em encontrar um elemento.
|
|
32
|
+
*
|
|
33
|
+
* Obtem a hierarquia UI via ADB e executa as estrategias em sequencia.
|
|
34
|
+
* Use este metodo quando nenhuma sessao UiAutomator2 esta activa.
|
|
35
|
+
*
|
|
36
|
+
* @param failedSelector Seletor original que nao encontrou o elemento
|
|
37
|
+
* @param selectorType Tipo do seletor original
|
|
38
|
+
* @returns Resultado do healing com novo seletor ou erro
|
|
39
|
+
*/
|
|
40
|
+
async heal(failedSelector, selectorType) {
|
|
41
|
+
const xml = this.adb.dumpUi();
|
|
42
|
+
if (!xml) {
|
|
43
|
+
return {
|
|
44
|
+
healed: false,
|
|
45
|
+
error: 'Falha ao obter hierarquia UI para healing',
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
const elements = (0, similarity_1.parseUiElements)(xml);
|
|
49
|
+
if (elements.length === 0) {
|
|
50
|
+
return {
|
|
51
|
+
healed: false,
|
|
52
|
+
error: 'Nenhum elemento encontrado na hierarquia UI',
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
return this.runStrategies(xml, elements, failedSelector, selectorType);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Heals a selector using pre-fetched XML hierarchy.
|
|
59
|
+
* Use when UiAutomator2 session is active (adb dumpUi would conflict).
|
|
60
|
+
*
|
|
61
|
+
* @param xml XML hierarchy from driver.getPageSource()
|
|
62
|
+
* @param failedSelector Seletor original que nao encontrou o elemento
|
|
63
|
+
* @param selectorType Tipo do seletor original
|
|
64
|
+
* @returns Resultado do healing com novo seletor ou erro
|
|
65
|
+
*/
|
|
66
|
+
async healWithXml(xml, failedSelector, selectorType) {
|
|
67
|
+
const elements = (0, similarity_1.parseUiElements)(xml);
|
|
68
|
+
if (elements.length === 0) {
|
|
69
|
+
return { healed: false, error: 'Hierarquia UI vazia' };
|
|
70
|
+
}
|
|
71
|
+
return this.runStrategies(xml, elements, failedSelector, selectorType);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Executa todas as estrategias de healing em sequencia.
|
|
75
|
+
* Retorna na primeira que encontrar match acima do limiar.
|
|
76
|
+
*/
|
|
77
|
+
async runStrategies(xml, elements, failedSelector, selectorType) {
|
|
78
|
+
const selectorInfo = this.parseSelectorInfo(failedSelector, selectorType);
|
|
79
|
+
// Strategy 1: Busca por texto similar
|
|
80
|
+
const textResult = this.tryTextMatch(elements, selectorInfo, failedSelector, selectorType);
|
|
81
|
+
if (textResult)
|
|
82
|
+
return textResult;
|
|
83
|
+
// Strategy 2: Busca por content-desc (accessibility)
|
|
84
|
+
const accessResult = this.tryAccessibilityMatch(elements, selectorInfo, failedSelector, selectorType);
|
|
85
|
+
if (accessResult)
|
|
86
|
+
return accessResult;
|
|
87
|
+
// Strategy 3: Busca por classe + posicao similar
|
|
88
|
+
const visualResult = this.tryVisualSimilarity(elements, selectorInfo, failedSelector, selectorType);
|
|
89
|
+
if (visualResult)
|
|
90
|
+
return visualResult;
|
|
91
|
+
// Strategy 4: Parent-child context (NEW)
|
|
92
|
+
const parentResult = this.tryParentChildMatch(elements, selectorInfo, failedSelector, selectorType);
|
|
93
|
+
if (parentResult)
|
|
94
|
+
return parentResult;
|
|
95
|
+
// Strategy 5: Bounds proximity (NEW)
|
|
96
|
+
const boundsResult = this.tryBoundsProximity(elements, selectorInfo, failedSelector, selectorType);
|
|
97
|
+
if (boundsResult)
|
|
98
|
+
return boundsResult;
|
|
99
|
+
// Strategy 6: AI analysis (last resort)
|
|
100
|
+
const aiResult = await this.tryAiAnalysis(xml, failedSelector, selectorType);
|
|
101
|
+
if (aiResult)
|
|
102
|
+
return aiResult;
|
|
103
|
+
return {
|
|
104
|
+
healed: false,
|
|
105
|
+
error: `Nenhuma estrategia de healing encontrou match para: ${failedSelector}`,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Mapa de padroes para extrair informacoes de seletores.
|
|
110
|
+
* Cada entrada define o tipo, o teste para identificar e a funcao de extracao.
|
|
111
|
+
*/
|
|
112
|
+
selectorPatterns = [
|
|
113
|
+
// UiSelector patterns (codegen v2) - higher priority
|
|
114
|
+
{
|
|
115
|
+
type: 'resourceId',
|
|
116
|
+
test: (s) => s.includes('.resourceId('),
|
|
117
|
+
extract: (s) => {
|
|
118
|
+
const m = s.match(/\.resourceId\("([^"]+)"\)/);
|
|
119
|
+
return m ? { resourceId: m[1] } : {};
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
type: 'text',
|
|
124
|
+
test: (s) => s.includes('.text('),
|
|
125
|
+
extract: (s) => {
|
|
126
|
+
const m = s.match(/\.text\("([^"]+)"\)/);
|
|
127
|
+
return m ? { text: m[1] } : {};
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
type: 'contentDesc',
|
|
132
|
+
test: (s) => s.includes('.description('),
|
|
133
|
+
extract: (s) => {
|
|
134
|
+
const m = s.match(/\.description\("([^"]+)"\)/);
|
|
135
|
+
return m ? { contentDesc: m[1] } : {};
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
type: 'className',
|
|
140
|
+
test: (s) => s.includes('.className('),
|
|
141
|
+
extract: (s) => {
|
|
142
|
+
const m = s.match(/\.className\("([^"]+)"\)/);
|
|
143
|
+
return m ? { className: m[1] } : {};
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
// Legacy patterns (backward compat)
|
|
147
|
+
{
|
|
148
|
+
type: 'resourceId',
|
|
149
|
+
test: (_s, t) => t === 'resourceId',
|
|
150
|
+
extract: (s) => ({ resourceId: s.replace(/^~/, '') }),
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
type: 'text',
|
|
154
|
+
test: (_s, t) => t === 'text',
|
|
155
|
+
extract: (s) => ({
|
|
156
|
+
text: s.replace(/^text="/, '').replace(/"$/, ''),
|
|
157
|
+
}),
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
type: 'xpath',
|
|
161
|
+
test: (_s, t) => t === 'xpath',
|
|
162
|
+
extract: (s) => {
|
|
163
|
+
const info = {};
|
|
164
|
+
const textMatch = s.match(/@text="([^"]*)"/);
|
|
165
|
+
if (textMatch)
|
|
166
|
+
info.text = textMatch[1];
|
|
167
|
+
const idMatch = s.match(/resource-id="([^"]*)"/);
|
|
168
|
+
if (idMatch)
|
|
169
|
+
info.resourceId = idMatch[1];
|
|
170
|
+
return info;
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
type: 'className',
|
|
175
|
+
test: (_s, t) => t === 'className',
|
|
176
|
+
extract: (s) => ({ className: s.replace(/^\/\//, '') }),
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
type: 'contentDesc',
|
|
180
|
+
test: (_s, t) => t === 'contentDesc',
|
|
181
|
+
extract: (s) => ({ contentDesc: s }),
|
|
182
|
+
},
|
|
183
|
+
];
|
|
184
|
+
/**
|
|
185
|
+
* Extrai informacoes estruturadas de um seletor usando o mapa de padroes.
|
|
186
|
+
*/
|
|
187
|
+
parseSelectorInfo(selector, selectorType) {
|
|
188
|
+
const pattern = this.selectorPatterns.find((p) => p.test(selector, selectorType));
|
|
189
|
+
return pattern ? pattern.extract(selector) : {};
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Determina o tipo de seletor com base no formato.
|
|
193
|
+
*/
|
|
194
|
+
static detectSelectorType(selector) {
|
|
195
|
+
// UiSelector patterns (codegen v2)
|
|
196
|
+
if (selector.includes('.resourceId('))
|
|
197
|
+
return 'resourceId';
|
|
198
|
+
if (selector.includes('.text('))
|
|
199
|
+
return 'text';
|
|
200
|
+
if (selector.includes('.description('))
|
|
201
|
+
return 'contentDesc';
|
|
202
|
+
if (selector.includes('.className('))
|
|
203
|
+
return 'className';
|
|
204
|
+
// Legacy patterns (backward compat)
|
|
205
|
+
if (selector.startsWith('~'))
|
|
206
|
+
return 'resourceId';
|
|
207
|
+
if (selector.includes('resource-id="'))
|
|
208
|
+
return 'resourceId';
|
|
209
|
+
if (selector.includes('@text="'))
|
|
210
|
+
return 'xpath';
|
|
211
|
+
if (selector.startsWith('text='))
|
|
212
|
+
return 'text';
|
|
213
|
+
if (selector.startsWith('//'))
|
|
214
|
+
return 'xpath';
|
|
215
|
+
if (selector.includes('content-desc='))
|
|
216
|
+
return 'contentDesc';
|
|
217
|
+
// Default: tentar como resourceId
|
|
218
|
+
return 'resourceId';
|
|
219
|
+
}
|
|
220
|
+
// --- Resultado de healing ---
|
|
221
|
+
/**
|
|
222
|
+
* Constroi um HealingResult de sucesso.
|
|
223
|
+
* Evita duplicacao do objeto em cada estrategia.
|
|
224
|
+
*/
|
|
225
|
+
buildSuccessResult(originalSelector, originalSelectorType, newSelector, newSelectorType, strategy, confidence) {
|
|
226
|
+
return {
|
|
227
|
+
healed: true,
|
|
228
|
+
attempt: {
|
|
229
|
+
testRunId: '',
|
|
230
|
+
stepIndex: 0,
|
|
231
|
+
originalSelector,
|
|
232
|
+
originalSelectorType,
|
|
233
|
+
newSelector,
|
|
234
|
+
newSelectorType,
|
|
235
|
+
confidence,
|
|
236
|
+
strategy,
|
|
237
|
+
applied: true,
|
|
238
|
+
createdAt: new Date(),
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
// --- Estrategias de healing ---
|
|
243
|
+
/**
|
|
244
|
+
* Estrategia 1: Busca por texto similar (fuzzy match).
|
|
245
|
+
* Faz dump da UI, encontra elementos com texto similar ao original.
|
|
246
|
+
*/
|
|
247
|
+
tryTextMatch(elements, selectorInfo, originalSelector, originalSelectorType) {
|
|
248
|
+
const matches = (0, similarity_1.findSimilarElements)(elements, selectorInfo);
|
|
249
|
+
for (const match of matches) {
|
|
250
|
+
if (match.confidence >= CONFIDENCE_THRESHOLD) {
|
|
251
|
+
const newSelector = this.buildNewSelector(match.element, match.matchedBy);
|
|
252
|
+
return this.buildSuccessResult(originalSelector, originalSelectorType, newSelector.selector, newSelector.type, 'text_match', match.confidence);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return null;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Estrategia 2: Busca por content-description (accessibility).
|
|
259
|
+
* Verifica atributos de acessibilidade dos elementos.
|
|
260
|
+
*/
|
|
261
|
+
tryAccessibilityMatch(elements, selectorInfo, originalSelector, originalSelectorType) {
|
|
262
|
+
// Procurar elementos com content-desc similar ao texto ou resourceId do original
|
|
263
|
+
const searchTerms = [];
|
|
264
|
+
if (selectorInfo.text)
|
|
265
|
+
searchTerms.push(selectorInfo.text);
|
|
266
|
+
if (selectorInfo.resourceId) {
|
|
267
|
+
// Extrair parte significativa do resourceId (apos o ultimo '/')
|
|
268
|
+
const parts = selectorInfo.resourceId.split('/');
|
|
269
|
+
const lastPart = parts[parts.length - 1];
|
|
270
|
+
if (lastPart) {
|
|
271
|
+
// Converter snake_case/camelCase para palavras separadas
|
|
272
|
+
const readable = lastPart
|
|
273
|
+
.replace(/_/g, ' ')
|
|
274
|
+
.replace(/([a-z])([A-Z])/g, '$1 $2')
|
|
275
|
+
.toLowerCase();
|
|
276
|
+
searchTerms.push(readable);
|
|
277
|
+
searchTerms.push(lastPart);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
if (selectorInfo.contentDesc)
|
|
281
|
+
searchTerms.push(selectorInfo.contentDesc);
|
|
282
|
+
for (const element of elements) {
|
|
283
|
+
if (!element.contentDesc)
|
|
284
|
+
continue;
|
|
285
|
+
for (const term of searchTerms) {
|
|
286
|
+
const sim = (0, similarity_1.textSimilarity)(term, element.contentDesc);
|
|
287
|
+
if (sim >= CONFIDENCE_THRESHOLD) {
|
|
288
|
+
return this.buildSuccessResult(originalSelector, originalSelectorType, element.contentDesc, 'contentDesc', 'accessibility_tree', sim);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return null;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Estrategia 3: Busca por classe + posicao visual.
|
|
296
|
+
* Encontra elementos da mesma classe em posicao similar.
|
|
297
|
+
*/
|
|
298
|
+
tryVisualSimilarity(elements, selectorInfo, originalSelector, originalSelectorType) {
|
|
299
|
+
if (!selectorInfo.className)
|
|
300
|
+
return null;
|
|
301
|
+
// Encontrar todos os elementos da mesma classe
|
|
302
|
+
const sameClass = elements.filter((el) => el.className === selectorInfo.className);
|
|
303
|
+
if (sameClass.length === 0)
|
|
304
|
+
return null;
|
|
305
|
+
// Se so tem um elemento da mesma classe, alta confianca
|
|
306
|
+
if (sameClass.length === 1) {
|
|
307
|
+
const element = sameClass[0];
|
|
308
|
+
const newSelector = this.buildNewSelector(element, 'text');
|
|
309
|
+
return this.buildSuccessResult(originalSelector, originalSelectorType, newSelector.selector, newSelector.type, 'visual_similarity', 75);
|
|
310
|
+
}
|
|
311
|
+
// Multiplos elementos da mesma classe - verificar se algum tem texto/id similar
|
|
312
|
+
for (const element of sameClass) {
|
|
313
|
+
let confidence = 50; // Base por ser mesma classe
|
|
314
|
+
if (selectorInfo.text && element.text) {
|
|
315
|
+
const sim = (0, similarity_1.textSimilarity)(selectorInfo.text, element.text);
|
|
316
|
+
confidence = Math.max(confidence, sim);
|
|
317
|
+
}
|
|
318
|
+
if (selectorInfo.resourceId && element.resourceId) {
|
|
319
|
+
const sim = (0, similarity_1.textSimilarity)(selectorInfo.resourceId, element.resourceId);
|
|
320
|
+
confidence = Math.max(confidence, sim);
|
|
321
|
+
}
|
|
322
|
+
if (confidence >= CONFIDENCE_THRESHOLD) {
|
|
323
|
+
const newSelector = this.buildNewSelector(element, 'text');
|
|
324
|
+
return this.buildSuccessResult(originalSelector, originalSelectorType, newSelector.selector, newSelector.type, 'visual_similarity', confidence);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
return null;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Estrategia 4: Busca por prefixo de resourceId (parent-child context).
|
|
331
|
+
*
|
|
332
|
+
* Android resourceIds follow the pattern "com.app.package:id/view_name".
|
|
333
|
+
* When the original element had a resourceId like "com.app:id/submit_button",
|
|
334
|
+
* this strategy finds other elements that share the same package prefix and
|
|
335
|
+
* have similar text or class — a proxy for "sibling in same container".
|
|
336
|
+
*/
|
|
337
|
+
tryParentChildMatch(elements, selectorInfo, originalSelector, originalSelectorType) {
|
|
338
|
+
if (!selectorInfo.resourceId)
|
|
339
|
+
return null;
|
|
340
|
+
// Extract the package prefix (e.g. "com.example.app:id") and short name
|
|
341
|
+
const idParts = selectorInfo.resourceId.split('/');
|
|
342
|
+
const packagePrefix = idParts[0]; // e.g. "com.example.app:id"
|
|
343
|
+
const shortId = idParts[idParts.length - 1]; // e.g. "submit_button"
|
|
344
|
+
if (!packagePrefix || !shortId)
|
|
345
|
+
return null;
|
|
346
|
+
for (const el of elements) {
|
|
347
|
+
if (!el.resourceId)
|
|
348
|
+
continue;
|
|
349
|
+
// Skip the exact same resourceId (already tried in text_match)
|
|
350
|
+
if (el.resourceId === selectorInfo.resourceId)
|
|
351
|
+
continue;
|
|
352
|
+
// Must share the same package prefix (same app, same "namespace")
|
|
353
|
+
if (!el.resourceId.startsWith(packagePrefix))
|
|
354
|
+
continue;
|
|
355
|
+
// Look for className match + text similarity (proxy for sibling context)
|
|
356
|
+
if (selectorInfo.className &&
|
|
357
|
+
el.className !== selectorInfo.className)
|
|
358
|
+
continue;
|
|
359
|
+
if (selectorInfo.text && el.text) {
|
|
360
|
+
if (el.text.toLowerCase().includes(selectorInfo.text.toLowerCase()) ||
|
|
361
|
+
selectorInfo.text.toLowerCase().includes(el.text.toLowerCase())) {
|
|
362
|
+
const newSelector = this.buildNewSelector(el, 'resourceId');
|
|
363
|
+
if (newSelector.selector) {
|
|
364
|
+
return this.buildSuccessResult(originalSelector, originalSelectorType, newSelector.selector, newSelector.type, 'parent_child', 60);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
return null;
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Estrategia 5: Busca por classe + conteudo mais proximo.
|
|
373
|
+
*
|
|
374
|
+
* When resourceId has changed but the element class and content are stable,
|
|
375
|
+
* this strategy scans all elements of the same class and picks the one
|
|
376
|
+
* whose text/contentDesc best matches the original selector info.
|
|
377
|
+
*/
|
|
378
|
+
tryBoundsProximity(elements, selectorInfo, originalSelector, originalSelectorType) {
|
|
379
|
+
if (!selectorInfo.className)
|
|
380
|
+
return null;
|
|
381
|
+
const sameClass = elements.filter((e) => e.className === selectorInfo.className &&
|
|
382
|
+
e.resourceId !== selectorInfo.resourceId);
|
|
383
|
+
if (sameClass.length === 0)
|
|
384
|
+
return null;
|
|
385
|
+
let bestMatch = null;
|
|
386
|
+
let bestScore = 0;
|
|
387
|
+
for (const el of sameClass) {
|
|
388
|
+
let score = 0;
|
|
389
|
+
if (el.text && selectorInfo.text) {
|
|
390
|
+
if (el.text.toLowerCase().includes(selectorInfo.text.toLowerCase())) {
|
|
391
|
+
score += 50;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
if (el.contentDesc && selectorInfo.text) {
|
|
395
|
+
if (el.contentDesc
|
|
396
|
+
.toLowerCase()
|
|
397
|
+
.includes(selectorInfo.text.toLowerCase())) {
|
|
398
|
+
score += 40;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
if (score > bestScore) {
|
|
402
|
+
bestScore = score;
|
|
403
|
+
bestMatch = el;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
if (bestMatch && bestScore >= 40) {
|
|
407
|
+
const newSelector = this.buildNewSelector(bestMatch, 'resourceId');
|
|
408
|
+
if (newSelector.selector) {
|
|
409
|
+
return this.buildSuccessResult(originalSelector, originalSelectorType, newSelector.selector, newSelector.type, 'bounds_proximity', bestScore);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
return null;
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Estrategia 6: Analise por AI via adapter.
|
|
416
|
+
* Delega ao AiHealingAdapter injectado no construtor.
|
|
417
|
+
* So funciona se o adapter estiver disponivel.
|
|
418
|
+
*/
|
|
419
|
+
async tryAiAnalysis(xml, originalSelector, originalSelectorType) {
|
|
420
|
+
if (!this.aiAdapter.isAvailable())
|
|
421
|
+
return null;
|
|
422
|
+
try {
|
|
423
|
+
const suggestion = await this.aiAdapter.suggestSelector({
|
|
424
|
+
failedSelector: originalSelector,
|
|
425
|
+
selectorType: originalSelectorType,
|
|
426
|
+
xmlDump: xml,
|
|
427
|
+
});
|
|
428
|
+
if (suggestion &&
|
|
429
|
+
suggestion.selector &&
|
|
430
|
+
suggestion.confidence >= CONFIDENCE_THRESHOLD) {
|
|
431
|
+
return this.buildSuccessResult(originalSelector, originalSelectorType, suggestion.selector, suggestion.selectorType || 'text', 'ai_analysis', suggestion.confidence);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
catch {
|
|
435
|
+
// AI analysis falhou — nao e critico
|
|
436
|
+
}
|
|
437
|
+
return null;
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Constroi um novo seletor a partir de um elemento encontrado.
|
|
441
|
+
* Prioriza resourceId > text > contentDesc.
|
|
442
|
+
*/
|
|
443
|
+
buildNewSelector(element, matchedBy) {
|
|
444
|
+
// Coordinates cannot be healed
|
|
445
|
+
if (matchedBy === 'coordinates') {
|
|
446
|
+
return { selector: '', type: 'coordinates' };
|
|
447
|
+
}
|
|
448
|
+
// Return canonical (raw value) selectors — framework wrapper is handled at code-patch time
|
|
449
|
+
if (element.resourceId) {
|
|
450
|
+
return {
|
|
451
|
+
selector: element.resourceId,
|
|
452
|
+
type: 'resourceId',
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
if (element.text) {
|
|
456
|
+
return {
|
|
457
|
+
selector: element.text,
|
|
458
|
+
type: 'text',
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
if (element.contentDesc) {
|
|
462
|
+
return {
|
|
463
|
+
selector: element.contentDesc,
|
|
464
|
+
type: 'contentDesc',
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
// Fallback para classe
|
|
468
|
+
return {
|
|
469
|
+
selector: element.className,
|
|
470
|
+
type: 'className',
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
exports.Healer = Healer;
|
|
475
|
+
//# sourceMappingURL=healer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"healer.js","sourceRoot":"","sources":["../../src/healing/healer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Funcoes de similaridade para o motor de self-healing.
|
|
3
|
+
*
|
|
4
|
+
* Implementa Levenshtein distance sem dependencias externas
|
|
5
|
+
* para comparar seletores e encontrar elementos semelhantes.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Elemento extraido do UI dump XML.
|
|
9
|
+
*/
|
|
10
|
+
export interface UiElement {
|
|
11
|
+
nodeStr: string;
|
|
12
|
+
resourceId: string;
|
|
13
|
+
text: string;
|
|
14
|
+
className: string;
|
|
15
|
+
contentDesc: string;
|
|
16
|
+
bounds: string;
|
|
17
|
+
clickable: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Calcula a distancia de Levenshtein entre duas strings.
|
|
21
|
+
* Retorna o numero minimo de edicoes (insercoes, remocoes, substituicoes)
|
|
22
|
+
* necessarias para transformar `a` em `b`.
|
|
23
|
+
*/
|
|
24
|
+
export declare function levenshteinDistance(a: string, b: string): number;
|
|
25
|
+
/**
|
|
26
|
+
* Calcula a similaridade entre duas strings (0-100).
|
|
27
|
+
* Baseado na distancia de Levenshtein normalizada.
|
|
28
|
+
*
|
|
29
|
+
* @returns Valor de 0 (completamente diferente) a 100 (identico)
|
|
30
|
+
*/
|
|
31
|
+
export declare function textSimilarity(a: string, b: string): number;
|
|
32
|
+
/**
|
|
33
|
+
* Verifica se uma string contem a outra (match parcial).
|
|
34
|
+
* Retorna confianca de 0-100.
|
|
35
|
+
*/
|
|
36
|
+
export declare function containsSimilarity(a: string, b: string): number;
|
|
37
|
+
/**
|
|
38
|
+
* Extrai todos os elementos do XML do UI dump.
|
|
39
|
+
*/
|
|
40
|
+
export declare function parseUiElements(xml: string): UiElement[];
|
|
41
|
+
/**
|
|
42
|
+
* Resultado de busca de elemento similar.
|
|
43
|
+
*/
|
|
44
|
+
export interface SimilarElementMatch {
|
|
45
|
+
element: UiElement;
|
|
46
|
+
confidence: number;
|
|
47
|
+
matchedBy: 'text' | 'resourceId' | 'contentDesc' | 'className';
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Encontra elementos similares ao alvo no UI dump.
|
|
51
|
+
* Retorna candidatos ordenados por confianca (maior primeiro).
|
|
52
|
+
*
|
|
53
|
+
* @param elements Lista de elementos do UI dump
|
|
54
|
+
* @param target Atributos do elemento original
|
|
55
|
+
* @returns Lista de matches ordenados por confianca
|
|
56
|
+
*/
|
|
57
|
+
export declare function findSimilarElements(elements: UiElement[], target: {
|
|
58
|
+
text?: string;
|
|
59
|
+
resourceId?: string;
|
|
60
|
+
className?: string;
|
|
61
|
+
contentDesc?: string;
|
|
62
|
+
}): SimilarElementMatch[];
|
|
63
|
+
//# sourceMappingURL=similarity.d.ts.map
|