androidviewclient 25.0.0__tar.gz → 25.1.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.
- {androidviewclient-25.0.0/src/androidviewclient.egg-info → androidviewclient-25.1.0}/PKG-INFO +2 -3
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/README.md +25 -14
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/setup.py +4 -3
- {androidviewclient-25.0.0 → androidviewclient-25.1.0/src/androidviewclient.egg-info}/PKG-INFO +2 -3
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/androidviewclient.egg-info/requires.txt +1 -2
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/adb/adbclient.py +1 -1
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/adb/dumpsys.py +1 -1
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/code_generator.py +1 -1
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/common.py +1 -1
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/concertina.py +1 -1
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/controlpanel.py +1 -1
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/culebron.py +25 -5
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/mcp/__init__.py +1 -1
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/mcp/object_store.py +1 -1
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/mcp/server.py +1 -1
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/mcp/tools.py +22 -12
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/plot.py +1 -1
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/robotframework/viewclientwrapper.py +1 -1
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/uiautomator/uiautomatorhelper.py +10 -3
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/viewclient.py +17 -13
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/tools/culebra +1 -1
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/tools/dump +1 -1
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/LICENSE +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/setup.cfg +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/androidviewclient.egg-info/SOURCES.txt +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/androidviewclient.egg-info/dependency_links.txt +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/androidviewclient.egg-info/entry_points.txt +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/androidviewclient.egg-info/top_level.txt +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/__init__.py +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/__init__.py +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/__init__.py +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/adb/__init__.py +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/adb/androidkeymap.py +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/distance.py +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/kato/__init__.py +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/kato/kato.py +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/keyevent.py +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/robotframework/__init__.py +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/uiautomator/__init__.py +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/uiautomator/utils.py +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/window.py +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/share/__init__.py +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/share/pixmaps/__init__.py +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/share/pixmaps/culebra.png +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/share/pixmaps/plugins/__init__.py +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/share/pixmaps/plugins/android/__init__.py +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/share/pixmaps/plugins/android/lib/__init__.py +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/share/pixmaps/plugins/android/lib/device-art-resources/__init__.py +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/share/pixmaps/plugins/android/lib/device-art-resources/samsung_s4/__init__.py +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/share/pixmaps/plugins/android/lib/device-art-resources/samsung_s4/port_back.png +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/share/pixmaps/plugins/android/lib/device-art-resources/samsung_s4/port_fore.png +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/share/pixmaps/plugins/android/lib/device-art-resources/samsung_s4/port_shadow.png +0 -0
- {androidviewclient-25.0.0 → androidviewclient-25.1.0}/tools/culebra-mcp +0 -0
{androidviewclient-25.0.0/src/androidviewclient.egg-info → androidviewclient-25.1.0}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: androidviewclient
|
|
3
|
-
Version: 25.
|
|
3
|
+
Version: 25.1.0
|
|
4
4
|
Summary: AndroidViewClient is a 100% pure python library and tools
|
|
5
5
|
Home-page: https://github.com/dtmilano/AndroidViewClient/
|
|
6
6
|
Author: Diego Torres Milano
|
|
@@ -16,12 +16,11 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.12
|
|
17
17
|
Requires-Python: >=3.9
|
|
18
18
|
License-File: LICENSE
|
|
19
|
-
Requires-Dist: setuptools
|
|
20
19
|
Requires-Dist: requests
|
|
21
20
|
Requires-Dist: numpy
|
|
22
21
|
Requires-Dist: matplotlib
|
|
23
22
|
Requires-Dist: culebratester-client>=2.0.73
|
|
24
|
-
Requires-Dist: mcp
|
|
23
|
+
Requires-Dist: mcp<2,>=0.9.0
|
|
25
24
|
Provides-Extra: dev
|
|
26
25
|
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
27
26
|
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
@@ -41,7 +41,7 @@ Or check the wiki for more alternatives.
|
|
|
41
41
|
|
|
42
42
|
# AI-Powered Testing with MCP
|
|
43
43
|
|
|
44
|
-
**NEW!** AndroidViewClient now includes a Model Context Protocol (MCP) server that enables AI assistants like Kiro to interact with Android devices through natural language.
|
|
44
|
+
**NEW!** AndroidViewClient now includes a Model Context Protocol (MCP) server that enables AI assistants like Claude Code and Kiro to interact with Android devices through natural language.
|
|
45
45
|
|
|
46
46
|
## Quick Start with MCP
|
|
47
47
|
|
|
@@ -53,11 +53,15 @@ Or check the wiki for more alternatives.
|
|
|
53
53
|
2. **Start CulebraTester2 on your device:**
|
|
54
54
|
|
|
55
55
|
Check the details at [How to run CulebraTester2 ?](https://github.com/dtmilano/CulebraTester2-public?tab=readme-ov-file#how-to-run-culebratester2-)
|
|
56
|
-
|
|
57
56
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
3. **Configure your AI assistant:**
|
|
58
|
+
|
|
59
|
+
**Claude Code** — register the server with one command:
|
|
60
|
+
```bash
|
|
61
|
+
claude mcp add culebratester2 --env CULEBRATESTER2_URL=http://localhost:9987 -- culebra-mcp
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Or add it to `.mcp.json` in your project root, so everyone who clones the project gets it:
|
|
61
65
|
```json
|
|
62
66
|
{
|
|
63
67
|
"mcpServers": {
|
|
@@ -71,12 +75,14 @@ Or check the wiki for more alternatives.
|
|
|
71
75
|
}
|
|
72
76
|
```
|
|
73
77
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
- "
|
|
78
|
-
- "
|
|
79
|
-
- "
|
|
78
|
+
**Kiro** — add the same entry to `.kiro/settings/mcp.json` or `~/.kiro/settings/mcp.json`.
|
|
79
|
+
|
|
80
|
+
4. **Start testing with natural language:**
|
|
81
|
+
- "_Get the device screen size_"
|
|
82
|
+
- "_Launch the Calculator app_"
|
|
83
|
+
- "_Find the button with text Submit and click it_"
|
|
84
|
+
- "_Take a screenshot_"
|
|
85
|
+
- "_Swipe up to scroll_"
|
|
80
86
|
|
|
81
87
|
## MCP Tools Available
|
|
82
88
|
|
|
@@ -103,9 +109,14 @@ The MCP server provides 20 tools for Android automation:
|
|
|
103
109
|
For detailed MCP configuration options, see the [MCP Configuration Guide](docs/MCP_CONFIGURATION.md).
|
|
104
110
|
|
|
105
111
|
Quick reference:
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
112
|
+
|
|
113
|
+
| | Claude Code | Kiro |
|
|
114
|
+
|---|---|---|
|
|
115
|
+
| **Project config** | `.mcp.json` (repository root) | `.kiro/settings/mcp.json` |
|
|
116
|
+
| **User config** | `~/.claude.json` (via `claude mcp add --scope user`) | `~/.kiro/settings/mcp.json` |
|
|
117
|
+
| **Tool pre-approval** | `permissions.allow` in `.claude/settings.json` | `autoApprove` in the server entry |
|
|
118
|
+
| **Example** | `examples/mcp_config.json` | `examples/mcp_config_kiro.json` |
|
|
119
|
+
|
|
109
120
|
- **Usage examples:** `examples/test_calculator_mcp.py`
|
|
110
121
|
|
|
111
122
|
## Environment Variables
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
from setuptools import setup, find_packages
|
|
4
4
|
|
|
5
5
|
setup(name='androidviewclient',
|
|
6
|
-
version='25.
|
|
6
|
+
version='25.1.0',
|
|
7
7
|
description='''AndroidViewClient is a 100% pure python library and tools
|
|
8
8
|
that simplifies test script creation providing higher level
|
|
9
9
|
operations and the ability of obtaining the tree of Views present at
|
|
@@ -33,12 +33,13 @@ setup(name='androidviewclient',
|
|
|
33
33
|
'Programming Language :: Python :: 3.11',
|
|
34
34
|
'Programming Language :: Python :: 3.12'],
|
|
35
35
|
install_requires=[
|
|
36
|
-
'setuptools',
|
|
37
36
|
'requests',
|
|
38
37
|
'numpy',
|
|
39
38
|
'matplotlib',
|
|
40
39
|
'culebratester-client >= 2.0.73',
|
|
41
|
-
|
|
40
|
+
# mcp 2.x renamed FastMCP to MCPServer and changed other APIs;
|
|
41
|
+
# com.dtmilano.android.mcp.server still uses the v1 API.
|
|
42
|
+
'mcp >= 0.9.0, < 2',
|
|
42
43
|
],
|
|
43
44
|
extras_require={
|
|
44
45
|
'dev': [
|
{androidviewclient-25.0.0 → androidviewclient-25.1.0/src/androidviewclient.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: androidviewclient
|
|
3
|
-
Version: 25.
|
|
3
|
+
Version: 25.1.0
|
|
4
4
|
Summary: AndroidViewClient is a 100% pure python library and tools
|
|
5
5
|
Home-page: https://github.com/dtmilano/AndroidViewClient/
|
|
6
6
|
Author: Diego Torres Milano
|
|
@@ -16,12 +16,11 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.12
|
|
17
17
|
Requires-Python: >=3.9
|
|
18
18
|
License-File: LICENSE
|
|
19
|
-
Requires-Dist: setuptools
|
|
20
19
|
Requires-Dist: requests
|
|
21
20
|
Requires-Dist: numpy
|
|
22
21
|
Requires-Dist: matplotlib
|
|
23
22
|
Requires-Dist: culebratester-client>=2.0.73
|
|
24
|
-
Requires-Dist: mcp
|
|
23
|
+
Requires-Dist: mcp<2,>=0.9.0
|
|
25
24
|
Provides-Extra: dev
|
|
26
25
|
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
27
26
|
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
@@ -38,7 +38,7 @@ from com.dtmilano.android.keyevent import KEY_EVENT
|
|
|
38
38
|
from com.dtmilano.android.uiautomator.uiautomatorhelper import UiAutomatorHelper
|
|
39
39
|
from com.dtmilano.android.viewclient import ViewClient, View, VERSION_SDK_PROPERTY
|
|
40
40
|
|
|
41
|
-
__version__ = '25.
|
|
41
|
+
__version__ = '25.1.0'
|
|
42
42
|
|
|
43
43
|
import sys
|
|
44
44
|
import threading
|
|
@@ -46,7 +46,28 @@ import warnings
|
|
|
46
46
|
import copy
|
|
47
47
|
import os
|
|
48
48
|
import platform
|
|
49
|
-
from
|
|
49
|
+
from importlib.metadata import PackageNotFoundError, distribution
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _culebra_icon_path() -> Optional[str]:
|
|
53
|
+
"""
|
|
54
|
+
Path to the culebra window icon, or None if it cannot be found.
|
|
55
|
+
|
|
56
|
+
Replaces pkg_resources.resource_filename(Requirement.parse("androidviewclient"), ...),
|
|
57
|
+
which resolved the file relative to the installed distribution's location. pkg_resources
|
|
58
|
+
has been removed from setuptools, so it is looked up with the standard library instead,
|
|
59
|
+
falling back to the source tree when running from a checkout.
|
|
60
|
+
"""
|
|
61
|
+
relative = os.path.join('share', 'pixmaps', 'culebra.png')
|
|
62
|
+
try:
|
|
63
|
+
located = str(distribution('androidviewclient').locate_file(relative))
|
|
64
|
+
if os.path.isfile(located):
|
|
65
|
+
return located
|
|
66
|
+
except PackageNotFoundError:
|
|
67
|
+
pass
|
|
68
|
+
# src/com/dtmilano/android/culebron.py -> src/share/pixmaps/culebra.png
|
|
69
|
+
in_tree = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..', '..', relative)
|
|
70
|
+
return os.path.normpath(in_tree) if os.path.isfile(in_tree) else None
|
|
50
71
|
|
|
51
72
|
# noinspection PyBroadException
|
|
52
73
|
try:
|
|
@@ -289,9 +310,8 @@ This is usually installed by python package. Check your distribution details.
|
|
|
289
310
|
self.concertinaConfigFile = concertinaConfigFile
|
|
290
311
|
self.window = tkinter.Tk()
|
|
291
312
|
try:
|
|
292
|
-
f =
|
|
293
|
-
|
|
294
|
-
icon = ImageTk.PhotoImage(file=f)
|
|
313
|
+
f = _culebra_icon_path()
|
|
314
|
+
icon = ImageTk.PhotoImage(file=f) if f else None
|
|
295
315
|
except:
|
|
296
316
|
icon = None
|
|
297
317
|
if icon:
|
{androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/mcp/server.py
RENAMED
|
@@ -31,7 +31,7 @@ from culebratester_client import ApiClient, Configuration
|
|
|
31
31
|
from culebratester_client.api import DefaultApi
|
|
32
32
|
from com.dtmilano.android.mcp.object_store import ObjectStore
|
|
33
33
|
|
|
34
|
-
__version__ = '25.
|
|
34
|
+
__version__ = '25.1.0'
|
|
35
35
|
|
|
36
36
|
# Configure logging
|
|
37
37
|
DEBUG = os.environ.get('CULEBRATESTER2_DEBUG', '').lower() in ('1', 'true', 'yes')
|
|
@@ -65,10 +65,10 @@ def getDeviceInfo() -> str:
|
|
|
65
65
|
@mcp.tool()
|
|
66
66
|
def dumpUiHierarchy() -> str:
|
|
67
67
|
"""
|
|
68
|
-
Dump the current UI hierarchy
|
|
69
|
-
|
|
68
|
+
Dump the current UI hierarchy.
|
|
69
|
+
|
|
70
70
|
Returns:
|
|
71
|
-
JSON string
|
|
71
|
+
JSON string whose "data" is the window hierarchy as a nested dict
|
|
72
72
|
"""
|
|
73
73
|
try:
|
|
74
74
|
hierarchy = client.ui_device_dump_window_hierarchy_get()
|
|
@@ -351,19 +351,29 @@ def startApp(packageName: str, activityName: str = None) -> str:
|
|
|
351
351
|
|
|
352
352
|
Args:
|
|
353
353
|
packageName: The package name of the app (e.g., "com.example.app")
|
|
354
|
-
activityName:
|
|
355
|
-
|
|
354
|
+
activityName: The activity to start, either fully qualified
|
|
355
|
+
("com.example.app.MainActivity") or relative to the package
|
|
356
|
+
(".MainActivity"). Required: CulebraTester2's startActivity
|
|
357
|
+
endpoint takes an explicit class and cannot resolve a launcher
|
|
358
|
+
activity from the package name alone.
|
|
359
|
+
|
|
356
360
|
Returns:
|
|
357
361
|
JSON string with success status
|
|
358
362
|
"""
|
|
359
363
|
try:
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
364
|
+
if not activityName:
|
|
365
|
+
return json.dumps({
|
|
366
|
+
"success": False,
|
|
367
|
+
"error": "activityName is required (e.g. \".MainActivity\"): "
|
|
368
|
+
"CulebraTester2 starts activities by explicit class"
|
|
369
|
+
})
|
|
370
|
+
|
|
371
|
+
# The endpoint takes pkg and cls as separate required query params,
|
|
372
|
+
# and the server does not expand a relative class name -- ".Main"
|
|
373
|
+
# reaches the Intent verbatim and fails with ActivityNotFoundException.
|
|
374
|
+
cls = packageName + activityName if activityName.startswith('.') else activityName
|
|
375
|
+
|
|
376
|
+
result = client.target_context_start_activity_get(pkg=packageName, cls=cls)
|
|
367
377
|
return json.dumps({
|
|
368
378
|
"success": True,
|
|
369
379
|
"data": str(result) if result else "OK"
|
|
@@ -20,7 +20,7 @@ limitations under the License.
|
|
|
20
20
|
|
|
21
21
|
from __future__ import print_function
|
|
22
22
|
|
|
23
|
-
__version__ = '25.
|
|
23
|
+
__version__ = '25.1.0'
|
|
24
24
|
|
|
25
25
|
import math
|
|
26
26
|
import os
|
|
@@ -500,8 +500,15 @@ class UiAutomatorHelper:
|
|
|
500
500
|
|
|
501
501
|
:see https://github.com/dtmilano/CulebraTester2-public/blob/master/openapi.yaml
|
|
502
502
|
:param _format: the format (e.g.: JSON, XML)
|
|
503
|
-
:return: the window hierarchy
|
|
504
|
-
"""
|
|
503
|
+
:return: the window hierarchy: a WindowHierarchy for JSON, the XML document as a str for XML
|
|
504
|
+
"""
|
|
505
|
+
if _format and _format.upper() == 'XML':
|
|
506
|
+
# The server answers XML as a text/plain document, but the generated client declares a
|
|
507
|
+
# single response type (WindowHierarchy) for this endpoint and tries to deserialize the
|
|
508
|
+
# XML into it, which fails. Take the body undeserialized and hand back the document.
|
|
509
|
+
response = self.uiAutomatorHelper.api_instance.ui_device_dump_window_hierarchy_get(
|
|
510
|
+
format=_format, _preload_content=False)
|
|
511
|
+
return response.data.decode('utf-8')
|
|
505
512
|
return self.uiAutomatorHelper.api_instance.ui_device_dump_window_hierarchy_get(format=_format)
|
|
506
513
|
|
|
507
514
|
@kato.kato
|
{androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/viewclient.py
RENAMED
|
@@ -18,15 +18,15 @@ limitations under the License.
|
|
|
18
18
|
@author: Diego Torres Milano
|
|
19
19
|
"""
|
|
20
20
|
|
|
21
|
-
from __future__ import print_function
|
|
21
|
+
from __future__ import annotations, print_function
|
|
22
22
|
|
|
23
23
|
import json
|
|
24
|
-
from typing import Optional, Union, Dict, Tuple
|
|
24
|
+
from typing import Literal, Optional, Union, Dict, Tuple
|
|
25
25
|
|
|
26
26
|
import culebratester_client
|
|
27
27
|
from culebratester_client import WindowHierarchyChild, WindowHierarchy
|
|
28
28
|
|
|
29
|
-
__version__ = '25.
|
|
29
|
+
__version__ = '25.1.0'
|
|
30
30
|
|
|
31
31
|
import sys
|
|
32
32
|
import warnings
|
|
@@ -3738,15 +3738,15 @@ class ViewClient:
|
|
|
3738
3738
|
self.windows[int('0x' + wid, 16)] = package
|
|
3739
3739
|
return self.windows
|
|
3740
3740
|
|
|
3741
|
-
def findViewById(self, viewId, root="ROOT", viewFilter=None):
|
|
3741
|
+
def findViewById(self, viewId: str, root: View | Literal["ROOT"] = "ROOT", viewFilter=None) -> View | None:
|
|
3742
3742
|
"""
|
|
3743
3743
|
Finds the View with the specified viewId.
|
|
3744
3744
|
|
|
3745
3745
|
@type viewId: str
|
|
3746
3746
|
@param viewId: the ID of the view to find
|
|
3747
|
-
@type root: str
|
|
3748
|
-
@
|
|
3749
|
-
|
|
3747
|
+
@type root: View or str
|
|
3748
|
+
@param root: the root node of the tree where the View will be searched, or the
|
|
3749
|
+
string C{"ROOT"} to search the whole tree
|
|
3750
3750
|
@type: viewFilter: function
|
|
3751
3751
|
@param viewFilter: a function that will be invoked providing the candidate View as a parameter
|
|
3752
3752
|
and depending on the return value (C{True} or C{False}) the View will be
|
|
@@ -3754,6 +3754,7 @@ class ViewClient:
|
|
|
3754
3754
|
This can be C{None} and no extra filtering is applied.
|
|
3755
3755
|
|
|
3756
3756
|
@return: the C{View} found or C{None}
|
|
3757
|
+
@raise ValueError: if C{root} is a str other than C{"ROOT"}
|
|
3757
3758
|
"""
|
|
3758
3759
|
|
|
3759
3760
|
if self.uiAutomatorHelper:
|
|
@@ -3763,8 +3764,10 @@ class ViewClient:
|
|
|
3763
3764
|
if not root:
|
|
3764
3765
|
return None
|
|
3765
3766
|
|
|
3766
|
-
if root
|
|
3767
|
-
|
|
3767
|
+
if isinstance(root, str):
|
|
3768
|
+
if root == "ROOT":
|
|
3769
|
+
return self.findViewById(viewId, self.root, viewFilter)
|
|
3770
|
+
raise ValueError("Invalid root: '%s', the only str accepted is 'ROOT'" % root)
|
|
3768
3771
|
|
|
3769
3772
|
try:
|
|
3770
3773
|
rootId = root.getId()
|
|
@@ -3806,15 +3809,15 @@ class ViewClient:
|
|
|
3806
3809
|
else:
|
|
3807
3810
|
return foundView
|
|
3808
3811
|
|
|
3809
|
-
def findViewByIdOrRaise(self, viewId, root="ROOT", viewFilter=None):
|
|
3812
|
+
def findViewByIdOrRaise(self, viewId: str, root: View | Literal["ROOT"] = "ROOT", viewFilter=None) -> View:
|
|
3810
3813
|
"""
|
|
3811
3814
|
Finds the View or raise a ViewNotFoundException.
|
|
3812
3815
|
|
|
3813
3816
|
@type viewId: str
|
|
3814
3817
|
@param viewId: the ID of the view to find
|
|
3815
|
-
@type root: str
|
|
3816
|
-
@
|
|
3817
|
-
|
|
3818
|
+
@type root: View or str
|
|
3819
|
+
@param root: the root node of the tree where the View will be searched, or the
|
|
3820
|
+
string C{"ROOT"} to search the whole tree
|
|
3818
3821
|
@type: viewFilter: function
|
|
3819
3822
|
@param viewFilter: a function that will be invoked providing the candidate View as a parameter
|
|
3820
3823
|
and depending on the return value (C{True} or C{False}) the View will be
|
|
@@ -3822,6 +3825,7 @@ class ViewClient:
|
|
|
3822
3825
|
This can be C{None} and no extra filtering is applied.
|
|
3823
3826
|
@return: the View found
|
|
3824
3827
|
@raise ViewNotFoundException: raise the exception if View not found
|
|
3828
|
+
@raise ValueError: if C{root} is a str other than C{"ROOT"}
|
|
3825
3829
|
"""
|
|
3826
3830
|
|
|
3827
3831
|
view = self.findViewById(viewId, root, viewFilter)
|
|
File without changes
|
|
File without changes
|
{androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/androidviewclient.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/androidviewclient.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/adb/__init__.py
RENAMED
|
File without changes
|
{androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/adb/androidkeymap.py
RENAMED
|
File without changes
|
|
File without changes
|
{androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/kato/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/com/dtmilano/android/uiautomator/utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{androidviewclient-25.0.0 → androidviewclient-25.1.0}/src/share/pixmaps/plugins/android/__init__.py
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
|