smartwright 0.2.0__tar.gz

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.
Files changed (54) hide show
  1. smartwright-0.2.0/LICENSE +21 -0
  2. smartwright-0.2.0/PKG-INFO +523 -0
  3. smartwright-0.2.0/README.md +487 -0
  4. smartwright-0.2.0/pyproject.toml +81 -0
  5. smartwright-0.2.0/setup.cfg +4 -0
  6. smartwright-0.2.0/smartwright/__init__.py +1224 -0
  7. smartwright-0.2.0/smartwright/_logging.py +27 -0
  8. smartwright-0.2.0/smartwright/ai_recovery/__init__.py +1 -0
  9. smartwright-0.2.0/smartwright/ai_recovery/groq_provider.py +82 -0
  10. smartwright-0.2.0/smartwright/ai_recovery/recovery.py +41 -0
  11. smartwright-0.2.0/smartwright/api_executor/__init__.py +1 -0
  12. smartwright-0.2.0/smartwright/api_executor/executor.py +22 -0
  13. smartwright-0.2.0/smartwright/constants.py +74 -0
  14. smartwright-0.2.0/smartwright/core/__init__.py +1 -0
  15. smartwright-0.2.0/smartwright/core/engine.py +146 -0
  16. smartwright-0.2.0/smartwright/core/models.py +33 -0
  17. smartwright-0.2.0/smartwright/core/store.py +68 -0
  18. smartwright-0.2.0/smartwright/exceptions.py +63 -0
  19. smartwright-0.2.0/smartwright/fingerprint/__init__.py +1 -0
  20. smartwright-0.2.0/smartwright/fingerprint/tracker.py +17 -0
  21. smartwright-0.2.0/smartwright/healing/__init__.py +1 -0
  22. smartwright-0.2.0/smartwright/healing/layer.py +18 -0
  23. smartwright-0.2.0/smartwright/intent/__init__.py +1 -0
  24. smartwright-0.2.0/smartwright/intent/manager.py +39 -0
  25. smartwright-0.2.0/smartwright/network_learning/__init__.py +1 -0
  26. smartwright-0.2.0/smartwright/network_learning/observer.py +466 -0
  27. smartwright-0.2.0/smartwright/py.typed +0 -0
  28. smartwright-0.2.0/smartwright/recorder/__init__.py +799 -0
  29. smartwright-0.2.0/smartwright/resolver/__init__.py +4 -0
  30. smartwright-0.2.0/smartwright/resolver/_base.py +109 -0
  31. smartwright-0.2.0/smartwright/resolver/_capture.py +325 -0
  32. smartwright-0.2.0/smartwright/resolver/_content.py +365 -0
  33. smartwright-0.2.0/smartwright/resolver/_debug.py +197 -0
  34. smartwright-0.2.0/smartwright/resolver/_form.py +146 -0
  35. smartwright-0.2.0/smartwright/resolver/_helpers.py +453 -0
  36. smartwright-0.2.0/smartwright/resolver/_interact.py +413 -0
  37. smartwright-0.2.0/smartwright/resolver/_page.py +774 -0
  38. smartwright-0.2.0/smartwright/resolver/_replay.py +598 -0
  39. smartwright-0.2.0/smartwright/resolver/_response.py +539 -0
  40. smartwright-0.2.0/smartwright/resolver/_run_json.py +845 -0
  41. smartwright-0.2.0/smartwright/resolver/adaptive.py +107 -0
  42. smartwright-0.2.0/smartwright/resolver/adaptive_replay.py +578 -0
  43. smartwright-0.2.0/smartwright/resolver/dom_serializer.py +528 -0
  44. smartwright-0.2.0/smartwright/resolver/emergency.py +56 -0
  45. smartwright-0.2.0/smartwright/resolver/replay_mode.py +185 -0
  46. smartwright-0.2.0/smartwright/semantic_finder/__init__.py +1 -0
  47. smartwright-0.2.0/smartwright/semantic_finder/finder.py +35 -0
  48. smartwright-0.2.0/smartwright/stealth/__init__.py +447 -0
  49. smartwright-0.2.0/smartwright.egg-info/PKG-INFO +523 -0
  50. smartwright-0.2.0/smartwright.egg-info/SOURCES.txt +52 -0
  51. smartwright-0.2.0/smartwright.egg-info/dependency_links.txt +1 -0
  52. smartwright-0.2.0/smartwright.egg-info/requires.txt +11 -0
  53. smartwright-0.2.0/smartwright.egg-info/top_level.txt +1 -0
  54. smartwright-0.2.0/tests/test_smartwright_complete.py +539 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 smartwright contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,523 @@
1
+ Metadata-Version: 2.4
2
+ Name: smartwright
3
+ Version: 0.2.0
4
+ Summary: Adaptive web automation engine — intent-driven, type+index, replay, DOM serializer, network learning
5
+ Author: smartwright contributors
6
+ License: MIT
7
+ Project-URL: Documentation, https://github.com/lhabacuc/smartwright/tree/main/docs
8
+ Project-URL: Repository, https://github.com/lhabacuc/smartwright
9
+ Project-URL: Changelog, https://github.com/lhabacuc/smartwright/blob/main/CHANGELOG.md
10
+ Keywords: playwright,automation,web,scraping,testing,replay,adaptive
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Software Development :: Testing
20
+ Classifier: Topic :: Internet :: WWW/HTTP :: Browsers
21
+ Classifier: Framework :: AsyncIO
22
+ Classifier: Typing :: Typed
23
+ Requires-Python: >=3.10
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: playwright<2.0,>=1.45
27
+ Provides-Extra: ai
28
+ Requires-Dist: groq<1.0,>=0.9.0; extra == "ai"
29
+ Provides-Extra: dev
30
+ Requires-Dist: pytest>=7.0; extra == "dev"
31
+ Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
32
+ Requires-Dist: pytest-cov>=4.0; extra == "dev"
33
+ Requires-Dist: ruff>=0.4; extra == "dev"
34
+ Requires-Dist: mypy>=1.8; extra == "dev"
35
+ Dynamic: license-file
36
+
37
+ # Smartwright
38
+
39
+ Motor de automacao web adaptativo com gravacao ao vivo, replay inteligente e 270+ funcoes para qualquer tarefa.
40
+
41
+ ## Instalacao
42
+
43
+ ```bash
44
+ pip install playwright
45
+ playwright install chromium
46
+ ```
47
+
48
+ ## CLI (qwen-cap.py)
49
+
50
+ ```bash
51
+ python qwen-cap.py record # grava acoes em recording.json
52
+ python qwen-cap.py record meu_fluxo.json # grava em arquivo customizado
53
+ python qwen-cap.py replay # replay com debug (padrao)
54
+ python qwen-cap.py replay --no-debug # sem screenshots/highlight
55
+ python qwen-cap.py replay --mode rapido # modo rapido
56
+ python qwen-cap.py replay --mode mix # modo mais resiliente
57
+ python qwen-cap.py full # record + replay sequencial
58
+ python qwen-cap.py full --mode forcado # full com modo forcado
59
+ ```
60
+
61
+ ## Modos de execucao
62
+
63
+ | Modo | Descricao | Uso ideal |
64
+ |---|---|---|
65
+ | `rapido` | Sem verificacao, timeouts curtos, sem delay | Paginas estaveis, testes rapidos |
66
+ | `padrao` | Todos os 6 steps de resolucao (default) | Uso geral |
67
+ | `por_index` | So usa tag + indice ordinal | DOM fixo |
68
+ | `por_id_e_class` | So CSS com #id, .class, [data-testid] | Sites com bons IDs |
69
+ | `forcado` | Resolucao completa + force click | Overlays, modais |
70
+ | `mix` | Todos os steps + 3 retries + scroll | Maximo resiliencia |
71
+
72
+ ## Uso como biblioteca — exemplos rapidos
73
+
74
+ ```python
75
+ from smartwright import Smartwright
76
+ from smartwright.recorder import ActionRecorder
77
+ ```
78
+
79
+ ### Gravacao e Replay
80
+
81
+ ```python
82
+ # Gravar acoes do usuario
83
+ recorder = ActionRecorder(save_path="acoes.json")
84
+ page = await recorder.start(url="https://example.com")
85
+ actions = await recorder.wait_until_closed()
86
+
87
+ # Replay com modo
88
+ smart = Smartwright(page=page, request_context=context.request)
89
+ results = await smart.emergency_replay_actions(actions, mode="mix")
90
+
91
+ # Replay direto do JSON
92
+ results = await smart.emergency_replay_json("acoes.json", mode="padrao")
93
+ ```
94
+
95
+ ### Executar JSON manual (run_json)
96
+
97
+ Executa JSONs escritos a mao, tolerante com campos em falta. So precisa de `action` + os campos essenciais.
98
+
99
+ ```python
100
+ # ── Inline (lista de dicts) ──
101
+ results = await smart.run_json([
102
+ {"action": "goto", "url": "https://example.com"},
103
+ {"action": "fill", "selector": "#email", "value": "user@test.com"},
104
+ {"action": "fill", "text": "Password", "value": "123456"},
105
+ {"action": "click", "text": "Login"},
106
+ {"action": "wait", "ms": 2000},
107
+ {"action": "screenshot", "path": "resultado.png"},
108
+ ])
109
+
110
+ # ── De arquivo JSON ──
111
+ results = await smart.run_json_file("meu_fluxo.json", mode="mix")
112
+
113
+ # ── Com base_url (URLs relativas) ──
114
+ results = await smart.run_json([
115
+ {"action": "goto", "url": "/login"},
116
+ {"action": "fill", "selector": "input[name=user]", "value": "admin"},
117
+ ], base_url="https://meusite.com")
118
+
119
+ # ── Parar no primeiro erro ──
120
+ results = await smart.run_json(actions, continue_on_error=False)
121
+ ```
122
+
123
+ **JSON minimo por acao:**
124
+
125
+ ```json
126
+ [
127
+ {"action": "goto", "url": "https://example.com"},
128
+ {"action": "click", "selector": "#btn"},
129
+ {"action": "click", "text": "Enviar"},
130
+ {"action": "fill", "selector": "#email", "value": "a@b.com"},
131
+ {"action": "fill", "text": "Senha", "value": "123"},
132
+ {"action": "select", "selector": "#pais", "value": "BR"},
133
+ {"action": "select", "selector": "#pais", "option": "Brasil"},
134
+ {"action": "check", "selector": "#aceito", "checked": true},
135
+ {"action": "press", "key": "Enter"},
136
+ {"action": "scroll", "dir": "down", "px": 500},
137
+ {"action": "wait", "ms": 3000},
138
+ {"action": "wait_text", "text": "Sucesso"},
139
+ {"action": "wait_element", "selector": "div.resultado"},
140
+ {"action": "screenshot", "path": "captura.png"},
141
+ {"action": "back"},
142
+ {"action": "js", "code": "document.title"},
143
+ {"action": "drag", "from": "#item", "to": "#destino"},
144
+ {"action": "upload", "selector": "input[type=file]", "file": "/path/doc.pdf"},
145
+ {"action": "download", "dir": "downloads"},
146
+ {"action": "copy", "value": "texto copiado"}
147
+ ]
148
+ ```
149
+
150
+ **Aliases aceitos:** `press`/`key`/`keys` → press_keys, `type`/`write`/`input` → fill, `go`/`open`/`nav` → goto, `tap` → click, `sleep`/`delay`/`pause` → wait, `snap` → screenshot, `back` → go_back, `forward` → go_forward, `refresh` → reload, `js`/`eval` → eval_js, `drag`/`dnd` → drag_drop, `checkbox` → check, `radio` → select_radio, `dropdown` → select_custom, `download` → wait_download, `clipboard` → wait_clipboard, `copy` → copy_to_clipboard, `alert`/`confirm`/`prompt` → dialog.
151
+
152
+ **Campos flexiveis:** `selector`/`css`/`sel`, `element_type`/`type`/`tag`, `index`/`idx`/`i`, `text`/`label`/`contains`, `value`/`val`, `url`/`href`/`link`, `timeout_ms`/`timeout`.
153
+
154
+ ### Clicks
155
+
156
+ ```python
157
+ await smart.emergency_click("button", 0) # por tipo + indice
158
+ await smart.emergency_click_by_text("Enviar") # por texto visivel
159
+ await smart.emergency_click_by_role("button", 2) # por role ARIA
160
+ await smart.emergency_click_first_type_containing("button", "*salvar*") # glob pattern
161
+ await smart.emergency_click_by_type_at_index_containing("a", 0, "*download*") # tipo + pos + texto
162
+ await smart.emergency_click_link("Ver mais") # link por texto
163
+ await smart.double_click("div", 3) # duplo click
164
+ await smart.right_click("tr", 0) # click direito
165
+ await smart.click_at_coordinates(500, 300) # x, y absoluto
166
+ ```
167
+
168
+ ### Fill / Input
169
+
170
+ ```python
171
+ await smart.emergency_fill("input", 0, "user@test.com") # por tipo + indice
172
+ await smart.emergency_fill_first_type_containing("input", "*email*", "a@b.com") # glob pattern
173
+ await smart.emergency_fill_by_type_at_index_containing("input", 2, "*senha*", "123")
174
+ await smart.emergency_fill_by_label("Email", "user@test.com") # por label do campo
175
+ await smart.emergency_clear_input("input", 0) # limpar campo
176
+ val = await smart.emergency_read_input_value("input", 0) # ler valor atual
177
+ ```
178
+
179
+ ### Read / Extrair texto
180
+
181
+ ```python
182
+ text = await smart.emergency_read("span", 5) # texto por tipo + indice
183
+ text = await smart.emergency_read_by_text("Total:", 0) # por texto visivel
184
+ text = await smart.emergency_read_first_type_containing("div", "*preco*") # glob pattern
185
+ text = await smart.emergency_read_by_type_at_index_containing("p", 0, "*desc*") # tipo + pos + texto
186
+ texts = await smart.emergency_read_all("li") # todos os textos de um tipo
187
+ ```
188
+
189
+ ### Formularios
190
+
191
+ ```python
192
+ await smart.emergency_select_option("select", 0, "opcao_valor") # select por value
193
+ await smart.emergency_select_option_by_label("select", 0, "Opcao visivel") # select por label
194
+ sel = await smart.emergency_read_selected_option("select", 0) # ler selecionado
195
+ opts = await smart.emergency_read_all_options("select", 0) # listar opcoes
196
+
197
+ await smart.emergency_check("input", 3, checked=True) # marcar checkbox
198
+ await smart.emergency_toggle_checkbox("input", 3) # alternar checkbox
199
+ await smart.emergency_select_radio("genero", "masculino") # radio por name+value
200
+ await smart.emergency_upload_file("input", 0, "/path/file.pdf") # upload arquivo
201
+
202
+ state = await smart.emergency_read_form_state(0) # estado de todos os campos
203
+ await smart.emergency_submit_form(0) # submit form
204
+ await smart.emergency_reset_form(0) # reset form
205
+ ```
206
+
207
+ ### Tabelas
208
+
209
+ ```python
210
+ cell = await smart.emergency_read_table_cell(0, 2, 3) # tabela[0] linha 2 col 3
211
+ row = await smart.emergency_read_table_row(0, 1) # linha inteira
212
+ data = await smart.emergency_read_full_table(0) # tabela completa -> [[str]]
213
+ await smart.emergency_click_table_cell(0, 1, 2) # clicar na celula
214
+ ```
215
+
216
+ ### Listas
217
+
218
+ ```python
219
+ items = await smart.emergency_read_list_items(0, list_type="ul") # textos de uma <ul>
220
+ await smart.emergency_click_list_item(0, 2, list_type="ul") # clicar no 3o item
221
+ ```
222
+
223
+ ### Links
224
+
225
+ ```python
226
+ await smart.emergency_click_link("Saiba mais", index=0) # clicar link por texto
227
+ href = await smart.emergency_get_link_href("Download") # pegar href
228
+ links = await smart.emergency_capture_all_links() # todos os links da pagina
229
+ ```
230
+
231
+ ### Hover / Scroll / Teclas
232
+
233
+ ```python
234
+ await smart.emergency_hover("div", 0) # hover no elemento
235
+ await smart.emergency_scroll_page("down", 500) # scroll direcional
236
+ await smart.emergency_scroll_to_top() # topo da pagina
237
+ await smart.emergency_scroll_to_bottom() # final da pagina
238
+ await smart.emergency_scroll_to("div.footer") # scroll ate elemento
239
+ await smart.mouse_move(400, 200) # mover mouse
240
+ await smart.mouse_wheel(0, -500) # scroll por mouse wheel
241
+ await smart.emergency_press_keys("Enter") # teclas especiais
242
+ await smart.emergency_press_keys("Control+a") # atalhos
243
+ ```
244
+
245
+ ### Waits / Esperas
246
+
247
+ ```python
248
+ el = await smart.emergency_wait_for_element("div.resultado", timeout_ms=15000) # esperar elemento
249
+ await smart.emergency_wait_for_text("Sucesso!", timeout_ms=10000) # esperar texto visivel
250
+ url = await smart.emergency_wait_for_url_contains("/dashboard") # esperar URL mudar
251
+ await smart.wait_for_load("networkidle", timeout_ms=30000) # esperar pagina carregar
252
+ resp = await smart.wait_for_response("*/api/data*", timeout_ms=30000) # esperar resposta HTTP
253
+ ```
254
+
255
+ ### Download e Clipboard
256
+
257
+ ```python
258
+ dl = await smart.emergency_wait_download(save_dir="downloads", timeout_ms=30000)
259
+ print(dl["filename"], dl["path"], dl["size"])
260
+
261
+ clip = await smart.emergency_wait_clipboard(timeout_ms=10000)
262
+ print(clip["text"])
263
+
264
+ await smart.emergency_copy_to_clipboard("texto copiado")
265
+ ```
266
+
267
+ ### Estado dos elementos
268
+
269
+ ```python
270
+ exists = await smart.element_exists("div.modal") # existe no DOM?
271
+ count = await smart.element_count("li.item") # quantos existem?
272
+ vis = await smart.is_visible("button", 0) # visivel?
273
+ ena = await smart.is_enabled("input", 1) # habilitado?
274
+ chk = await smart.is_checked("input", 3) # marcado?
275
+ has = await smart.has_class("div", 0, "active") # tem classe?
276
+ cls = await smart.get_classes("div", 0) # listar classes
277
+ box = await smart.get_bounding_box("img", 0) # x, y, width, height
278
+ ```
279
+
280
+ ### Pagina
281
+
282
+ ```python
283
+ title = await smart.emergency_get_page_title() # titulo da pagina
284
+ url = await smart.emergency_get_page_url() # URL atual
285
+ await smart.page_screenshot("captura.png", full_page=True) # screenshot
286
+ text = await smart.page_text() # todo texto visivel
287
+ html = await smart.page_html() # HTML completo
288
+ await smart.page_pdf("relatorio.pdf") # exportar PDF
289
+ await smart.set_viewport(1920, 1080) # mudar tamanho
290
+ await smart.go_back() # voltar
291
+ await smart.go_forward() # avancar
292
+ await smart.reload() # recarregar
293
+ ```
294
+
295
+ ### CSS / Estilo
296
+
297
+ ```python
298
+ style = await smart.emergency_get_computed_style("div", 0, "background-color")
299
+ attr = await smart.emergency_get_attribute("a", 0, "href")
300
+ ```
301
+
302
+ ### Cookies
303
+
304
+ ```python
305
+ cookies = await smart.get_cookies() # listar cookies
306
+ await smart.set_cookie("token", "abc123", domain=".example.com") # criar cookie
307
+ await smart.clear_cookies() # limpar tudo
308
+ ```
309
+
310
+ ### LocalStorage e SessionStorage
311
+
312
+ ```python
313
+ val = await smart.get_local_storage("user_id") # ler
314
+ await smart.set_local_storage("theme", "dark") # salvar
315
+ await smart.remove_local_storage("temp") # remover chave
316
+ all_data = await smart.get_all_local_storage() # tudo
317
+ await smart.clear_local_storage() # limpar tudo
318
+
319
+ val = await smart.get_session_storage("cart") # session storage
320
+ await smart.set_session_storage("step", "2")
321
+ await smart.clear_session_storage()
322
+ ```
323
+
324
+ ### JavaScript
325
+
326
+ ```python
327
+ result = await smart.eval_js("document.title") # executar JS
328
+ result = await smart.eval_js("el => el.dataset.id", element) # JS com argumento
329
+ ```
330
+
331
+ ### Iframes
332
+
333
+ ```python
334
+ frame = await smart.emergency_switch_to_iframe(0) # por indice
335
+ frame = await smart.emergency_switch_to_iframe("#meu-iframe") # por selector
336
+ await smart.emergency_switch_to_main_frame() # voltar ao principal
337
+ ```
338
+
339
+ ### Dialogs (alert, confirm, prompt)
340
+
341
+ ```python
342
+ msg = await smart.emergency_handle_dialog("accept") # aceitar alert
343
+ msg = await smart.emergency_handle_dialog("dismiss") # cancelar
344
+ msg = await smart.emergency_handle_dialog("accept", prompt_text="resposta") # prompt com texto
345
+ ```
346
+
347
+ ### Drag and Drop
348
+
349
+ ```python
350
+ await smart.emergency_drag_and_drop("#item", "#destino")
351
+ ```
352
+
353
+ ### Media (audio/video)
354
+
355
+ ```python
356
+ await smart.emergency_control_media("video", 0, "play") # play/pause/mute
357
+ state = await smart.emergency_get_media_state("video", 0) # currentTime, paused, etc.
358
+ src = await smart.emergency_get_media_src("video", 0) # URL do media
359
+ ```
360
+
361
+ ### Imagens
362
+
363
+ ```python
364
+ info = await smart.emergency_get_image_info(0) # src, alt, naturalWidth...
365
+ images = await smart.emergency_capture_all_images() # todas as imagens
366
+ ```
367
+
368
+ ### Captura em massa
369
+
370
+ ```python
371
+ inputs = await smart.emergency_capture_all_inputs() # todos os inputs
372
+ buttons = await smart.emergency_capture_all_buttons() # todos os botoes
373
+ selects = await smart.emergency_capture_all_selects() # todos os selects
374
+ heads = await smart.emergency_capture_all_headings() # todos os h1-h6
375
+ full = await smart.emergency_capture_page_elements() # mapa completo da pagina
376
+ ```
377
+
378
+ ### Capture e Relocate (persistir referencia a elementos)
379
+
380
+ ```python
381
+ cap = await smart.emergency_capture("button", 0) # captura snapshot
382
+ cap = await smart.emergency_capture_by_selector("#btn-enviar") # por selector
383
+ cap = await smart.emergency_capture_containing("button", "*enviar*") # por glob
384
+
385
+ # Mais tarde, relocar o mesmo elemento (mesmo se DOM mudou)
386
+ el = await smart.emergency_relocate(cap)
387
+ await smart.emergency_click_captured(cap)
388
+ await smart.emergency_fill_captured(cap, "novo valor")
389
+ text = await smart.emergency_read_captured(cap)
390
+ await smart.emergency_hover_captured(cap)
391
+ ```
392
+
393
+ ### Intent-driven (modo avancado)
394
+
395
+ ```python
396
+ smart = Smartwright(page=page, request_context=context.request)
397
+ await smart.goto("https://example.com")
398
+ await smart.fill("email_field", "user@test.com")
399
+ await smart.fill("password_field", "senha123")
400
+ await smart.click("login_button")
401
+ ```
402
+
403
+ ### Resposta de assistente (chat bots)
404
+
405
+ ```python
406
+ answer = await smart.wait_response_text(timeout_ms=60000, stable_rounds=3)
407
+ await smart.wait_and_click_copy_button()
408
+ ```
409
+
410
+ ### File system
411
+
412
+ ```python
413
+ data = await smart.read_file("config.json") # ler arquivo
414
+ await smart.write_file("output.txt", "resultado") # escrever
415
+ await smart.write_file("log.txt", "nova linha\n", append=True) # append
416
+ files = await smart.list_files("downloads", "*.pdf", recursive=True) # listar
417
+ exists = await smart.file_exists("data.csv") # existe?
418
+ info = await smart.file_info("report.pdf") # metadata
419
+ await smart.copy_file("a.txt", "backup/a.txt") # copiar
420
+ await smart.move_file("temp.txt", "final.txt") # mover
421
+ await smart.delete_file("temp.txt") # deletar
422
+ ```
423
+
424
+ ### Anti-deteccao (stealth)
425
+
426
+ ```python
427
+ from smartwright.stealth import StealthConfig, apply_stealth, get_stealth_args
428
+
429
+ # Config com todas protecoes (default)
430
+ cfg = StealthConfig()
431
+
432
+ # Ou config minima (so webdriver + automation flags)
433
+ cfg = StealthConfig.minimal()
434
+
435
+ # Usar no recorder
436
+ recorder = ActionRecorder(save_path="acoes.json", stealth=True)
437
+
438
+ # Usar manualmente
439
+ browser = await p.chromium.launch(
440
+ args=get_stealth_args(cfg),
441
+ ignore_default_args=["--enable-automation"],
442
+ )
443
+ context = await browser.new_context(**get_context_options(cfg))
444
+ await apply_stealth(context, cfg)
445
+ ```
446
+
447
+ Protecoes: navigator.webdriver, plugins, chrome object, permissions, hardware (concurrency/memory/platform), WebGL vendor/renderer, canvas noise, audio noise, connection rtt, WebRTC IP leak. 6 fingerprint profiles (Windows/Mac/Linux com GPUs realistas).
448
+
449
+ ### Gravacao de video e HAR
450
+
451
+ ```python
452
+ # Gravar com video
453
+ recorder = ActionRecorder(
454
+ save_path="acoes.json",
455
+ record_video_dir="videos/",
456
+ record_har_path="network.har",
457
+ )
458
+ page = await recorder.start(url="https://example.com")
459
+ actions = await recorder.wait_until_closed()
460
+ print(recorder.video_paths) # paths dos videos
461
+
462
+ # Ler HAR
463
+ har = await smart.read_har("network.har") # parse HAR
464
+ print(har["total_entries"])
465
+
466
+ # Extrair APIs do HAR
467
+ apis = await smart.extract_har_apis("network.har", "/api/") # so endpoints API
468
+ for api in apis:
469
+ print(api["method"], api["url"], api["status"])
470
+
471
+ # Gerar GIF dos screenshots de debug
472
+ gif = await smart.generate_gif("debug_screenshots/", "replay.gif", duration_ms=600)
473
+ print(gif["frames"], "frames,", gif["size"], "bytes")
474
+ ```
475
+
476
+ CLI:
477
+ ```bash
478
+ python qwen-cap.py record --stealth # record com anti-deteccao
479
+ python qwen-cap.py record --record-video # grava video da sessao
480
+ python qwen-cap.py record --record-har network.har # grava trace HTTP
481
+ python qwen-cap.py replay --stealth --record-video # replay stealth + video
482
+ ```
483
+
484
+ ## Resolucao de elementos (6 steps)
485
+
486
+ O replay busca cada elemento nesta ordem:
487
+
488
+ 1. **Capture CSS selectors** — selectors gravados (#id, .class, [data-testid])
489
+ 2. **Action selector** — selector do JSON com proximidade de bbox
490
+ 3. **Type + index + text** — N-esimo elemento com texto correspondente
491
+ 4. **Type + text** — primeiro match por texto (resiliente a mudancas de DOM)
492
+ 5. **Type + index** — lookup ordinal por tag
493
+ 6. **Coordenadas** — click por posicao x/y (ultimo recurso)
494
+
495
+ ## Arquitetura
496
+
497
+ ```
498
+ smartwright/
499
+ __init__.py Facade (Smartwright class, 290+ metodos)
500
+ recorder/
501
+ __init__.py ActionRecorder — gravacao ao vivo com JS injection
502
+ resolver/
503
+ emergency.py EmergencyResolver — replay, resolucao, click/fill/etc.
504
+ replay_mode.py ReplayMode enum + ModeConfig — configuracao dos modos
505
+ adaptive.py Resolver adaptativo com score de estrategia
506
+ stealth/
507
+ __init__.py StealthConfig, apply_stealth — anti-deteccao
508
+ core/ Decision engine, modelos, knowledge store
509
+ intent/ Mapeamento de intencoes semanticas
510
+ semantic_finder/ Busca por conceito
511
+ healing/ Auto-repair adaptativo
512
+ fingerprint/ Deteccao de mudancas estruturais
513
+ network_learning/ Descoberta automatica de APIs
514
+ api_executor/ Execucao direta via HTTP
515
+ ai_recovery/ Fallback com IA
516
+ ```
517
+
518
+ ## Persistencia
519
+
520
+ - `.smartwright_profile/` — perfil do Chromium (login, cookies, sessao)
521
+ - `.smartwright_knowledge.json` — historico de estrategias, APIs, scores
522
+ - `recording.json` — acoes gravadas
523
+ - `debug_screenshots/` — screenshots de debug por step