ai-dev-browser 0.12.2__tar.gz → 0.12.4__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.
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/.github/workflows/ci.yml +2 -1
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/PKG-INFO +1 -1
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/_tab.py +63 -25
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser.egg-info/PKG-INFO +1 -1
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser.egg-info/SOURCES.txt +1 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser.egg-info/scm_file_list.json +1 -0
- ai_dev_browser-0.12.4/ai_dev_browser.egg-info/scm_version.json +8 -0
- ai_dev_browser-0.12.4/tests/integration/test_scroll_embedded_target.py +211 -0
- ai_dev_browser-0.12.2/ai_dev_browser.egg-info/scm_version.json +0 -8
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/.github/workflows/publish.yml +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/.gitignore +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/.gitmodules +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/.pre-commit-config.yaml +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/.secrets.baseline +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/LICENSE +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/README.md +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/__init__.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/_cli.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/_version.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/__init__.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/accessibility.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/animation.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/audits.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/autofill.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/background_service.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/bluetooth_emulation.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/browser.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/cache_storage.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/cast.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/console.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/crash_report_context.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/css.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/debugger.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/device_access.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/device_orientation.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/dom.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/dom_debugger.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/dom_snapshot.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/dom_storage.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/emulation.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/event_breakpoints.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/extensions.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/fed_cm.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/fetch.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/file_system.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/headless_experimental.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/heap_profiler.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/indexed_db.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/input_.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/inspector.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/io.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/layer_tree.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/log.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/media.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/memory.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/network.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/overlay.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/page.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/performance.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/performance_timeline.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/preload.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/profiler.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/pwa.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/py.typed +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/runtime.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/schema.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/security.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/service_worker.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/smart_card_emulation.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/storage.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/system_info.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/target.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/tethering.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/tracing.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/util.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/web_audio.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/web_authn.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/cdp/web_mcp.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/__init__.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/_case.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/_element.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/_image_cap.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/_transport.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/ax.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/browser.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/cdp.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/chrome.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/cleanup.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/config.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/connection.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/cookies.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/cookies_import.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/dialog.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/download.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/elements.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/human.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/login.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/mouse.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/navigation.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/overlays.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/page.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/port.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/process.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/snapshot.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/storage.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/tabs.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/text_match.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/core/window.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/pool/__init__.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/pool/job.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/pool/persistence.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/pool/pool.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/pool/worker.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/profile.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/py.typed +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/__init__.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/_generate.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/browser_list.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/browser_start.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/browser_stop.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/cdp_send.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/click_by_html_id.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/click_by_ref.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/click_by_text.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/click_by_xpath.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/cookies_extract.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/cookies_import.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/cookies_list.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/cookies_load.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/cookies_save.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/dialog_respond.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/download.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/drag_by_ref.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/find_by_html_id.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/find_by_text.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/find_by_xpath.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/focus_by_ref.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/highlight_by_ref.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/hover_by_ref.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/html_by_ref.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/js_evaluate.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/login_interactive.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/mouse_click.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/mouse_drag.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/mouse_move.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/page_discover.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/page_emulate_focus.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/page_goto.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/page_html.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/page_info.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/page_pdf.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/page_reload.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/page_screenshot.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/page_scroll.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/page_wait_element.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/page_wait_ready.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/page_wait_url.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/screenshot_by_ref.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/select_by_ref.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/storage_get.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/storage_set.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/tab_close.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/tab_list.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/tab_new.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/tab_switch.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/type_by_ref.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/type_by_text.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/upload_by_ref.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser/tools/window_set.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser.egg-info/dependency_links.txt +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser.egg-info/requires.txt +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser.egg-info/top_level.txt +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/pyproject.toml +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/scripts/sync_cdp.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/setup.cfg +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/tests/__init__.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/tests/conftest.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/tests/integration/__init__.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/tests/integration/scenarios_workspace.json +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/tests/integration/test_ci_integration.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/tests/integration/test_cli_unicode_help.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/tests/integration/test_cookies_extract_windows.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/tests/integration/test_cookies_import.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/tests/integration/test_dialog_respond.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/tests/integration/test_find_and_interact_workflows.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/tests/integration/test_image_cap.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/tests/integration/test_locator_workflows.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/tests/integration/test_multi_profile_pool.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/tests/integration/test_page_reload.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/tests/integration/test_port_detection.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/tests/integration/test_startup_timeout.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/tests/integration/test_timeout_and_retry.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/tests/integration/test_workspace_workflows.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/tests/unit/test_case.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/tests/unit/test_cli_param_type.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/tests/unit/test_no_acronym_rot.py +0 -0
- {ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/uv.lock +0 -0
|
@@ -71,7 +71,8 @@ jobs:
|
|
|
71
71
|
tests/integration/test_ci_integration.py \
|
|
72
72
|
tests/integration/test_cookies_extract_windows.py \
|
|
73
73
|
tests/integration/test_cli_unicode_help.py \
|
|
74
|
-
tests/integration/test_image_cap.py
|
|
74
|
+
tests/integration/test_image_cap.py \
|
|
75
|
+
tests/integration/test_scroll_embedded_target.py
|
|
75
76
|
|
|
76
77
|
# ─────────────────────────────────────────────────────────────────────
|
|
77
78
|
# CI-integration dogfood: prove the documented "consumer's CI" recipe
|
|
@@ -27,6 +27,26 @@ if typing.TYPE_CHECKING:
|
|
|
27
27
|
|
|
28
28
|
logger = logging.getLogger(__name__)
|
|
29
29
|
|
|
30
|
+
# CDP JSON-RPC error code for "method not found" — sent by the
|
|
31
|
+
# target when a domain method the client called isn't implemented
|
|
32
|
+
# there. Embedded CDP targets (Electron, CEF, packaged Chromium
|
|
33
|
+
# exposing --remote-debugging-port) commonly return this on
|
|
34
|
+
# Chrome-browser-specific methods like Browser.getWindowForTarget or
|
|
35
|
+
# Input.synthesizeScrollGesture. Anything else (protocol violation,
|
|
36
|
+
# malformed params, target crash) must not be silently downgraded.
|
|
37
|
+
_CDP_METHOD_NOT_FOUND = -32601
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _is_cdp_method_not_found(exc: ProtocolException) -> bool:
|
|
41
|
+
"""Robust match: prefer the numeric code from the CDP error dict;
|
|
42
|
+
fall back to the human-readable variants for older transports
|
|
43
|
+
that surface the error as a bare string."""
|
|
44
|
+
err = exc.args[0] if exc.args else None
|
|
45
|
+
if isinstance(err, dict) and err.get("code") == _CDP_METHOD_NOT_FOUND:
|
|
46
|
+
return True
|
|
47
|
+
text = str(exc)
|
|
48
|
+
return str(_CDP_METHOD_NOT_FOUND) in text or "wasn't found" in text
|
|
49
|
+
|
|
30
50
|
|
|
31
51
|
class Tab:
|
|
32
52
|
"""CDP tab connection."""
|
|
@@ -493,36 +513,54 @@ class Tab:
|
|
|
493
513
|
# Scroll
|
|
494
514
|
# =========================================================================
|
|
495
515
|
|
|
516
|
+
async def _scroll_by_viewport_percent(self, percent: float) -> None:
|
|
517
|
+
"""Scroll by `percent` of viewport height (positive = down,
|
|
518
|
+
negative = up).
|
|
519
|
+
|
|
520
|
+
Prefers Chrome's gesture-based path
|
|
521
|
+
(`Browser.getWindowForTarget` for bounds +
|
|
522
|
+
`Input.synthesizeScrollGesture` for a smooth swipe) so scroll
|
|
523
|
+
looks human-like — the gesture-shape acceleration + easing
|
|
524
|
+
matter for anti-bot heuristics that flag instant jumps.
|
|
525
|
+
|
|
526
|
+
Falls back to `Runtime.evaluate` + `window.scrollBy` only
|
|
527
|
+
when the gesture path returns CDP -32601 "method not found".
|
|
528
|
+
That signals an embedded target (Electron, CEF, packaged
|
|
529
|
+
Chromium exposing CDP via `--remote-debugging-port`) that
|
|
530
|
+
doesn't implement Browser or synthesizeScrollGesture. On
|
|
531
|
+
the fallback path, scroll events still fire so lazy-load /
|
|
532
|
+
IntersectionObserver / scroll-listener triggers still work —
|
|
533
|
+
we just lose the gesture-shape (which the embedded target
|
|
534
|
+
can't observe anyway).
|
|
535
|
+
"""
|
|
536
|
+
try:
|
|
537
|
+
_window_id, bounds = await self.get_window()
|
|
538
|
+
await self.send(
|
|
539
|
+
cdp_input.synthesize_scroll_gesture(
|
|
540
|
+
x=0,
|
|
541
|
+
y=0,
|
|
542
|
+
y_distance=-(bounds.height * (percent / 100)),
|
|
543
|
+
y_overscroll=0,
|
|
544
|
+
x_overscroll=0,
|
|
545
|
+
prevent_fling=True,
|
|
546
|
+
repeat_delay_ms=0,
|
|
547
|
+
speed=7777,
|
|
548
|
+
)
|
|
549
|
+
)
|
|
550
|
+
except ProtocolException as e:
|
|
551
|
+
if not _is_cdp_method_not_found(e):
|
|
552
|
+
raise
|
|
553
|
+
await self.evaluate(
|
|
554
|
+
f"window.scrollBy(0, window.innerHeight * {percent / 100})"
|
|
555
|
+
)
|
|
556
|
+
|
|
496
557
|
async def scroll_down(self, amount: int = 25):
|
|
497
558
|
"""Scroll down by percentage of viewport height."""
|
|
498
|
-
|
|
499
|
-
await self.send(
|
|
500
|
-
cdp_input.synthesize_scroll_gesture(
|
|
501
|
-
x=0,
|
|
502
|
-
y=0,
|
|
503
|
-
y_distance=-(bounds.height * (amount / 100)),
|
|
504
|
-
y_overscroll=0,
|
|
505
|
-
x_overscroll=0,
|
|
506
|
-
prevent_fling=True,
|
|
507
|
-
repeat_delay_ms=0,
|
|
508
|
-
speed=7777,
|
|
509
|
-
)
|
|
510
|
-
)
|
|
559
|
+
await self._scroll_by_viewport_percent(amount)
|
|
511
560
|
|
|
512
561
|
async def scroll_up(self, amount: int = 25):
|
|
513
562
|
"""Scroll up by percentage of viewport height."""
|
|
514
|
-
|
|
515
|
-
await self.send(
|
|
516
|
-
cdp_input.synthesize_scroll_gesture(
|
|
517
|
-
x=0,
|
|
518
|
-
y=0,
|
|
519
|
-
y_distance=(bounds.height * (amount / 100)),
|
|
520
|
-
x_overscroll=0,
|
|
521
|
-
prevent_fling=True,
|
|
522
|
-
repeat_delay_ms=0,
|
|
523
|
-
speed=7777,
|
|
524
|
-
)
|
|
525
|
-
)
|
|
563
|
+
await self._scroll_by_viewport_percent(-amount)
|
|
526
564
|
|
|
527
565
|
# =========================================================================
|
|
528
566
|
# Navigation
|
|
@@ -185,6 +185,7 @@ tests/integration/test_locator_workflows.py
|
|
|
185
185
|
tests/integration/test_multi_profile_pool.py
|
|
186
186
|
tests/integration/test_page_reload.py
|
|
187
187
|
tests/integration/test_port_detection.py
|
|
188
|
+
tests/integration/test_scroll_embedded_target.py
|
|
188
189
|
tests/integration/test_startup_timeout.py
|
|
189
190
|
tests/integration/test_timeout_and_retry.py
|
|
190
191
|
tests/integration/test_workspace_workflows.py
|
|
@@ -175,6 +175,7 @@
|
|
|
175
175
|
"tests/integration/test_cookies_import.py",
|
|
176
176
|
"tests/integration/test_multi_profile_pool.py",
|
|
177
177
|
"tests/integration/test_port_detection.py",
|
|
178
|
+
"tests/integration/test_scroll_embedded_target.py",
|
|
178
179
|
"tests/integration/test_startup_timeout.py",
|
|
179
180
|
"tests/integration/test_image_cap.py",
|
|
180
181
|
"tests/integration/test_locator_workflows.py",
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
"""Regression: page_scroll must work on embedded CDP targets that
|
|
2
|
+
don't implement Chrome's `Browser` domain (Electron / CEF / packaged
|
|
3
|
+
Chromium apps exposing CDP via `--remote-debugging-port`).
|
|
4
|
+
|
|
5
|
+
Pre-fix, `page_scroll(direction="down")` walked:
|
|
6
|
+
page_scroll → tab.scroll_down → tab.get_window (Browser.getWindowForTarget)
|
|
7
|
+
|
|
8
|
+
That CDP method is Chrome-browser-specific; embedded targets return
|
|
9
|
+
`-32601 Method not found` and the whole scroll path aborts. Reported
|
|
10
|
+
by a downstream integrator attaching to a packaged Electron app.
|
|
11
|
+
|
|
12
|
+
Fix (in `_tab._scroll_by_viewport_percent`): try the Chrome
|
|
13
|
+
gesture path first (`get_window` + `synthesize_scroll_gesture` —
|
|
14
|
+
still the preferred path because gesture-shape acceleration helps
|
|
15
|
+
evade anti-bot heuristics that flag instant scroll jumps). If that
|
|
16
|
+
returns CDP `-32601 method not found`, fall back to
|
|
17
|
+
`Runtime.evaluate` + `window.scrollBy` — Runtime is universally
|
|
18
|
+
supported. Any OTHER ProtocolException still surfaces so real
|
|
19
|
+
protocol violations aren't silently downgraded to the fallback.
|
|
20
|
+
|
|
21
|
+
Tests below pin all three contracts:
|
|
22
|
+
1. Positive — scroll_down actually scrolls a real Chrome fixture
|
|
23
|
+
via the gesture path (proves it wasn't broken by the fallback
|
|
24
|
+
plumbing).
|
|
25
|
+
2. Fallback — scroll_down succeeds when `get_window` is patched
|
|
26
|
+
to raise `-32601 method not found` (proves the embedded-target
|
|
27
|
+
path works).
|
|
28
|
+
3. Guardrail — a NON-32601 ProtocolException must NOT be
|
|
29
|
+
downgraded to fallback (proves we didn't paper over real
|
|
30
|
+
protocol bugs).
|
|
31
|
+
|
|
32
|
+
Tests 2 + 3 are the load-bearing pair — without them a future
|
|
33
|
+
"cleanup" could either reintroduce `get_window()` in the fallback
|
|
34
|
+
path (re-breaking Electron users) or widen the except-clause to
|
|
35
|
+
swallow all protocol errors (masking real bugs), and regular Chrome
|
|
36
|
+
CI would go green for both regressions.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
from __future__ import annotations
|
|
40
|
+
|
|
41
|
+
import base64
|
|
42
|
+
import contextlib
|
|
43
|
+
import os
|
|
44
|
+
|
|
45
|
+
import pytest
|
|
46
|
+
|
|
47
|
+
from ai_dev_browser.core import page_goto, page_scroll
|
|
48
|
+
from ai_dev_browser.core.browser import browser_start, browser_stop
|
|
49
|
+
from ai_dev_browser.core.connection import connect_browser, get_active_tab
|
|
50
|
+
|
|
51
|
+
SKIP_INTEGRATION = os.environ.get("SKIP_INTEGRATION", "").lower() in (
|
|
52
|
+
"1",
|
|
53
|
+
"true",
|
|
54
|
+
"yes",
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@pytest.fixture(autouse=True)
|
|
59
|
+
def _integration_guard():
|
|
60
|
+
if SKIP_INTEGRATION:
|
|
61
|
+
pytest.skip("SKIP_INTEGRATION is set")
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@pytest.fixture
|
|
65
|
+
async def tab():
|
|
66
|
+
"""Headless Chrome loaded with a tall data:URL so scrollY has
|
|
67
|
+
room to change. Deliberately >5x viewport so a 25% scroll is a
|
|
68
|
+
detectable delta."""
|
|
69
|
+
result = browser_start(headless=True, temp=True, reuse="none")
|
|
70
|
+
assert "error" not in result, f"browser_start failed: {result}"
|
|
71
|
+
port = result["port"]
|
|
72
|
+
browser_client = None
|
|
73
|
+
try:
|
|
74
|
+
browser_client = await connect_browser(port=port)
|
|
75
|
+
the_tab = await get_active_tab(browser_client)
|
|
76
|
+
html = (
|
|
77
|
+
"<html><body style='margin:0'>"
|
|
78
|
+
+ "".join(
|
|
79
|
+
f"<div style='height:200px;background:hsl({i * 37 % 360},60%,50%);"
|
|
80
|
+
f"color:white;padding:20px;font-size:22px'>Row {i}</div>"
|
|
81
|
+
for i in range(30)
|
|
82
|
+
)
|
|
83
|
+
+ "</body></html>"
|
|
84
|
+
)
|
|
85
|
+
data_url = "data:text/html;base64," + base64.b64encode(html.encode()).decode()
|
|
86
|
+
await page_goto(the_tab, data_url)
|
|
87
|
+
yield the_tab
|
|
88
|
+
finally:
|
|
89
|
+
if browser_client is not None:
|
|
90
|
+
with contextlib.suppress(Exception):
|
|
91
|
+
await browser_client.close()
|
|
92
|
+
with contextlib.suppress(Exception):
|
|
93
|
+
browser_stop(port=port)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
async def _get_scroll_y(tab) -> float:
|
|
97
|
+
"""Read window.scrollY through the same Runtime.evaluate channel
|
|
98
|
+
the fix uses — deep-serialization deserialization of a numeric
|
|
99
|
+
RemoteObject varies, so pull via .value from the eval envelope."""
|
|
100
|
+
result = await tab.evaluate("window.scrollY", return_by_value=True)
|
|
101
|
+
return float(result if result is not None else 0)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
async def test_page_scroll_down_actually_scrolls(tab):
|
|
105
|
+
"""Positive: real headless Chrome + tall fixture → scroll_down
|
|
106
|
+
must observably move window.scrollY forward. Baseline that proves
|
|
107
|
+
the JS-based rewrite works at all before we go asserting Electron
|
|
108
|
+
compat."""
|
|
109
|
+
before = await _get_scroll_y(tab)
|
|
110
|
+
assert before == 0, f"fixture should start at scrollY=0, got {before}"
|
|
111
|
+
|
|
112
|
+
ok = await page_scroll(tab, direction="down", amount=50)
|
|
113
|
+
assert ok is True
|
|
114
|
+
|
|
115
|
+
after = await _get_scroll_y(tab)
|
|
116
|
+
assert after > before, (
|
|
117
|
+
f"scroll_down(50%) did not move scrollY: before={before}, after={after}"
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
async def test_page_scroll_up_after_down_reverses(tab):
|
|
122
|
+
"""Positive: scroll_up unwinds a prior scroll_down. Two-step
|
|
123
|
+
verifies the sign convention (positive percent = down / content
|
|
124
|
+
moves up) is preserved after the rewrite — a reversed sign would
|
|
125
|
+
slip past 'did it scroll?' asserts."""
|
|
126
|
+
await page_scroll(tab, direction="down", amount=50)
|
|
127
|
+
peak = await _get_scroll_y(tab)
|
|
128
|
+
assert peak > 0
|
|
129
|
+
|
|
130
|
+
await page_scroll(tab, direction="up", amount=50)
|
|
131
|
+
after_up = await _get_scroll_y(tab)
|
|
132
|
+
assert after_up < peak, (
|
|
133
|
+
f"scroll_up did not reduce scrollY: peak={peak}, after_up={after_up}"
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
async def test_page_scroll_falls_back_on_cdp_method_not_found(tab, monkeypatch):
|
|
138
|
+
"""The Electron path: `get_window` raises CDP -32601 'method not
|
|
139
|
+
found' → scroll must fall back to `window.scrollBy` via
|
|
140
|
+
Runtime.evaluate and still scroll.
|
|
141
|
+
|
|
142
|
+
Simulating the failure mode with the actual `ProtocolException`
|
|
143
|
+
shape the CDP transport produces (dict with `code: -32601`), not
|
|
144
|
+
a generic Exception — otherwise a future edit narrowing the
|
|
145
|
+
except-clause to only catch method-not-found would break this
|
|
146
|
+
test and force a re-think, which is exactly the point."""
|
|
147
|
+
from ai_dev_browser.core._transport import ProtocolException
|
|
148
|
+
|
|
149
|
+
async def _boom():
|
|
150
|
+
raise ProtocolException(
|
|
151
|
+
{"code": -32601, "message": "'Browser.getWindowForTarget' wasn't found"}
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
monkeypatch.setattr(tab, "get_window", _boom)
|
|
155
|
+
|
|
156
|
+
before = await _get_scroll_y(tab)
|
|
157
|
+
ok = await page_scroll(tab, direction="down", amount=50)
|
|
158
|
+
assert ok is True
|
|
159
|
+
|
|
160
|
+
after = await _get_scroll_y(tab)
|
|
161
|
+
assert after > before, (
|
|
162
|
+
f"scroll_down did not fall back to JS scroll on -32601: "
|
|
163
|
+
f"before={before}, after={after}"
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
async def test_page_scroll_does_not_swallow_other_protocol_errors(tab, monkeypatch):
|
|
168
|
+
"""Guardrail: only -32601 method-not-found triggers fallback. A
|
|
169
|
+
different CDP error (say a target crash, code -32000, or protocol
|
|
170
|
+
violation) must NOT be silently downgraded to the JS path —
|
|
171
|
+
that would mask real bugs in the transport / gesture pipeline.
|
|
172
|
+
|
|
173
|
+
Without this test, a maintainer could widen the except clause to
|
|
174
|
+
`except ProtocolException:` (catch-all) and Chrome CI would go
|
|
175
|
+
green, but any transport-layer failure would silently succeed
|
|
176
|
+
with a JS fallback — losing observability of a real bug."""
|
|
177
|
+
from ai_dev_browser.core._transport import ProtocolException
|
|
178
|
+
|
|
179
|
+
async def _boom():
|
|
180
|
+
# -32000 is a generic server error, NOT method-not-found.
|
|
181
|
+
raise ProtocolException(
|
|
182
|
+
{"code": -32000, "message": "Target crashed while loading window bounds"}
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
monkeypatch.setattr(tab, "get_window", _boom)
|
|
186
|
+
|
|
187
|
+
with pytest.raises(ProtocolException) as ei:
|
|
188
|
+
await page_scroll(tab, direction="down", amount=50)
|
|
189
|
+
assert ei.value.args[0].get("code") == -32000, (
|
|
190
|
+
f"expected -32000 to propagate, got: {ei.value.args}"
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
async def test_page_scroll_to_bottom_survives_broken_get_window(tab, monkeypatch):
|
|
195
|
+
"""The other two page_scroll branches (to_bottom / to_top) already
|
|
196
|
+
used tab.evaluate, so they should already work on embedded
|
|
197
|
+
targets. This test pins that assumption so a future refactor
|
|
198
|
+
doesn't route them through get_window()."""
|
|
199
|
+
|
|
200
|
+
async def _boom():
|
|
201
|
+
raise RuntimeError("simulated Electron: Browser domain unavailable")
|
|
202
|
+
|
|
203
|
+
monkeypatch.setattr(tab, "get_window", _boom)
|
|
204
|
+
|
|
205
|
+
ok = await page_scroll(tab, to_bottom=True)
|
|
206
|
+
assert ok is True
|
|
207
|
+
|
|
208
|
+
after = await _get_scroll_y(tab)
|
|
209
|
+
assert after > 500, (
|
|
210
|
+
f"to_bottom should scroll a 6000px page substantially; got scrollY={after}"
|
|
211
|
+
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/ai_dev_browser.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/tests/integration/test_cookies_extract_windows.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/tests/integration/test_multi_profile_pool.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ai_dev_browser-0.12.2 → ai_dev_browser-0.12.4}/tests/integration/test_workspace_workflows.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|