Kea2-python 0.0.1a6__tar.gz → 0.0.1b1__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.
Potentially problematic release.
This version of Kea2-python might be problematic. Click here for more details.
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1/Kea2_python.egg-info}/PKG-INFO +26 -4
- kea2_python-0.0.1a6/README.md → kea2_python-0.0.1b1/PKG-INFO +37 -3
- kea2_python-0.0.1a6/Kea2_python.egg-info/PKG-INFO → kea2_python-0.0.1b1/README.md +25 -15
- kea2_python-0.0.1b1/kea2/__init__.py +4 -0
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/absDriver.py +4 -0
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/adbUtils.py +5 -0
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/quicktest.py +3 -3
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/cli.py +1 -1
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/keaUtils.py +58 -12
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/kea_launcher.py +10 -2
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/u2Driver.py +19 -6
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/pyproject.toml +2 -2
- kea2_python-0.0.1a6/kea2/__init__.py +0 -4
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/Kea2_python.egg-info/SOURCES.txt +0 -0
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/Kea2_python.egg-info/dependency_links.txt +0 -0
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/Kea2_python.egg-info/entry_points.txt +0 -0
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/Kea2_python.egg-info/requires.txt +0 -0
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/Kea2_python.egg-info/top_level.txt +0 -0
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/LICENSE +0 -0
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot-thirdpart.jar +0 -0
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot_configs/ADBKeyBoard.apk +0 -0
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot_configs/abl.strings +0 -0
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot_configs/awl.strings +0 -0
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot_configs/max.config +0 -0
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot_configs/max.fuzzing.strings +0 -0
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot_configs/max.schema.strings +0 -0
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot_configs/max.strings +0 -0
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot_configs/max.tree.pruning +0 -0
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot_configs/widget.block.py +0 -0
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot_libs/arm64-v8a/libfastbot_native.so +0 -0
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot_libs/armeabi-v7a/libfastbot_native.so +0 -0
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot_libs/x86/libfastbot_native.so +0 -0
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot_libs/x86_64/libfastbot_native.so +0 -0
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/framework.jar +0 -0
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/monkeyq.jar +0 -0
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/u2.jar +0 -0
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/logWatcher.py +0 -0
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/utils.py +0 -0
- {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: Kea2-python
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.1b1
|
|
4
4
|
Summary: A python library for supporting and customizing automated UI testing for mobile apps
|
|
5
5
|
Author-email: Xixian Liang <xixian@stu.ecnu.edu.cn>
|
|
6
6
|
Requires-Python: >=3.8
|
|
@@ -12,6 +12,14 @@ Dynamic: license-file
|
|
|
12
12
|
|
|
13
13
|
# Introduction
|
|
14
14
|
|
|
15
|
+
[](https://pypi.python.org/pypi/kea2-python)
|
|
16
|
+
[](https://pepy.tech/projects/kea2-python)
|
|
17
|
+

|
|
18
|
+
|
|
19
|
+
<div>
|
|
20
|
+
<img src="https://github.com/user-attachments/assets/58f68b00-cc9c-4620-9e2e-66c43cf7caae" style="border-radius: 14px; width: 20%; height: 20%;"/>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
15
23
|
Kea2 is an easy-to-use Python library for supporting, customizing and improving automated UI testing for mobile apps. The library is currently built on top of [Fastbot](https://github.com/bytedance/Fastbot_Android) and [uiautomator2](https://github.com/openatx/uiautomator2), and targeting [Android](https://en.wikipedia.org/wiki/Android_(operating_system)) apps.
|
|
16
24
|
|
|
17
25
|
### Kea2 has three important features:
|
|
@@ -297,16 +305,30 @@ class MyFirstTest(unittest.TestCase):
|
|
|
297
305
|
You can read [Kea - Write your fisrt property](https://kea-docs.readthedocs.io/en/latest/part-keaUserManuel/first_property.html) for more details.
|
|
298
306
|
|
|
299
307
|
### Notes
|
|
300
|
-
Currently, in `@precondition` decorator and `widgets.block.py`. We only support basic selector (No parent-child relationship)
|
|
301
|
-
|
|
308
|
+
Currently, in `@precondition` decorator and `widgets.block.py`. We only support basic selector (No parent-child relationship) in uiautomator2. The Script body in the function fully support uiautomator2.
|
|
302
309
|
|
|
303
310
|
| | **Support** | **Not support** |
|
|
304
311
|
| -- | -- | -- |
|
|
305
312
|
| **Selctor** | `d(text="1").exist` | `d(text="1").child(text="2").exist` |
|
|
306
|
-
| **XPath** | `d.xpath(".//[@text='1']")` | `d.xpath(".//[@text='1']").xpath(".//[@text]='2'")` |
|
|
307
313
|
|
|
308
314
|
If you need to specify `parent-child` relation ship in `@precondition`, specify it in xpath.
|
|
309
315
|
|
|
316
|
+
for example:
|
|
317
|
+
|
|
318
|
+
```python
|
|
319
|
+
# Do not use:
|
|
320
|
+
# @precondition(lambda self:
|
|
321
|
+
# self.d(className="android.widget.ListView").child(text="Bluetooth")
|
|
322
|
+
# ):
|
|
323
|
+
# ...
|
|
324
|
+
|
|
325
|
+
# Use
|
|
326
|
+
@precondition(lambda self:
|
|
327
|
+
self.d.xpath('//android.widget.ListView/*[@text="Bluetooth"]')
|
|
328
|
+
):
|
|
329
|
+
...
|
|
330
|
+
```
|
|
331
|
+
|
|
310
332
|
|
|
311
333
|
## Launching Kea2
|
|
312
334
|
|
|
@@ -1,5 +1,25 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: Kea2-python
|
|
3
|
+
Version: 0.0.1b1
|
|
4
|
+
Summary: A python library for supporting and customizing automated UI testing for mobile apps
|
|
5
|
+
Author-email: Xixian Liang <xixian@stu.ecnu.edu.cn>
|
|
6
|
+
Requires-Python: >=3.8
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Requires-Dist: rtree>=1.3.0
|
|
10
|
+
Requires-Dist: uiautomator2>=3.2.9
|
|
11
|
+
Dynamic: license-file
|
|
12
|
+
|
|
1
13
|
# Introduction
|
|
2
14
|
|
|
15
|
+
[](https://pypi.python.org/pypi/kea2-python)
|
|
16
|
+
[](https://pepy.tech/projects/kea2-python)
|
|
17
|
+

|
|
18
|
+
|
|
19
|
+
<div>
|
|
20
|
+
<img src="https://github.com/user-attachments/assets/58f68b00-cc9c-4620-9e2e-66c43cf7caae" style="border-radius: 14px; width: 20%; height: 20%;"/>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
3
23
|
Kea2 is an easy-to-use Python library for supporting, customizing and improving automated UI testing for mobile apps. The library is currently built on top of [Fastbot](https://github.com/bytedance/Fastbot_Android) and [uiautomator2](https://github.com/openatx/uiautomator2), and targeting [Android](https://en.wikipedia.org/wiki/Android_(operating_system)) apps.
|
|
4
24
|
|
|
5
25
|
### Kea2 has three important features:
|
|
@@ -285,16 +305,30 @@ class MyFirstTest(unittest.TestCase):
|
|
|
285
305
|
You can read [Kea - Write your fisrt property](https://kea-docs.readthedocs.io/en/latest/part-keaUserManuel/first_property.html) for more details.
|
|
286
306
|
|
|
287
307
|
### Notes
|
|
288
|
-
Currently, in `@precondition` decorator and `widgets.block.py`. We only support basic selector (No parent-child relationship)
|
|
289
|
-
|
|
308
|
+
Currently, in `@precondition` decorator and `widgets.block.py`. We only support basic selector (No parent-child relationship) in uiautomator2. The Script body in the function fully support uiautomator2.
|
|
290
309
|
|
|
291
310
|
| | **Support** | **Not support** |
|
|
292
311
|
| -- | -- | -- |
|
|
293
312
|
| **Selctor** | `d(text="1").exist` | `d(text="1").child(text="2").exist` |
|
|
294
|
-
| **XPath** | `d.xpath(".//[@text='1']")` | `d.xpath(".//[@text='1']").xpath(".//[@text]='2'")` |
|
|
295
313
|
|
|
296
314
|
If you need to specify `parent-child` relation ship in `@precondition`, specify it in xpath.
|
|
297
315
|
|
|
316
|
+
for example:
|
|
317
|
+
|
|
318
|
+
```python
|
|
319
|
+
# Do not use:
|
|
320
|
+
# @precondition(lambda self:
|
|
321
|
+
# self.d(className="android.widget.ListView").child(text="Bluetooth")
|
|
322
|
+
# ):
|
|
323
|
+
# ...
|
|
324
|
+
|
|
325
|
+
# Use
|
|
326
|
+
@precondition(lambda self:
|
|
327
|
+
self.d.xpath('//android.widget.ListView/*[@text="Bluetooth"]')
|
|
328
|
+
):
|
|
329
|
+
...
|
|
330
|
+
```
|
|
331
|
+
|
|
298
332
|
|
|
299
333
|
## Launching Kea2
|
|
300
334
|
|
|
@@ -1,17 +1,13 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: Kea2-python
|
|
3
|
-
Version: 0.0.1a6
|
|
4
|
-
Summary: A python library for supporting and customizing automated UI testing for mobile apps
|
|
5
|
-
Author-email: Xixian Liang <xixian@stu.ecnu.edu.cn>
|
|
6
|
-
Requires-Python: >=3.8
|
|
7
|
-
Description-Content-Type: text/markdown
|
|
8
|
-
License-File: LICENSE
|
|
9
|
-
Requires-Dist: rtree>=1.3.0
|
|
10
|
-
Requires-Dist: uiautomator2>=3.2.9
|
|
11
|
-
Dynamic: license-file
|
|
12
|
-
|
|
13
1
|
# Introduction
|
|
14
2
|
|
|
3
|
+
[](https://pypi.python.org/pypi/kea2-python)
|
|
4
|
+
[](https://pepy.tech/projects/kea2-python)
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
<div>
|
|
8
|
+
<img src="https://github.com/user-attachments/assets/58f68b00-cc9c-4620-9e2e-66c43cf7caae" style="border-radius: 14px; width: 20%; height: 20%;"/>
|
|
9
|
+
</div>
|
|
10
|
+
|
|
15
11
|
Kea2 is an easy-to-use Python library for supporting, customizing and improving automated UI testing for mobile apps. The library is currently built on top of [Fastbot](https://github.com/bytedance/Fastbot_Android) and [uiautomator2](https://github.com/openatx/uiautomator2), and targeting [Android](https://en.wikipedia.org/wiki/Android_(operating_system)) apps.
|
|
16
12
|
|
|
17
13
|
### Kea2 has three important features:
|
|
@@ -297,16 +293,30 @@ class MyFirstTest(unittest.TestCase):
|
|
|
297
293
|
You can read [Kea - Write your fisrt property](https://kea-docs.readthedocs.io/en/latest/part-keaUserManuel/first_property.html) for more details.
|
|
298
294
|
|
|
299
295
|
### Notes
|
|
300
|
-
Currently, in `@precondition` decorator and `widgets.block.py`. We only support basic selector (No parent-child relationship)
|
|
301
|
-
|
|
296
|
+
Currently, in `@precondition` decorator and `widgets.block.py`. We only support basic selector (No parent-child relationship) in uiautomator2. The Script body in the function fully support uiautomator2.
|
|
302
297
|
|
|
303
298
|
| | **Support** | **Not support** |
|
|
304
299
|
| -- | -- | -- |
|
|
305
300
|
| **Selctor** | `d(text="1").exist` | `d(text="1").child(text="2").exist` |
|
|
306
|
-
| **XPath** | `d.xpath(".//[@text='1']")` | `d.xpath(".//[@text='1']").xpath(".//[@text]='2'")` |
|
|
307
301
|
|
|
308
302
|
If you need to specify `parent-child` relation ship in `@precondition`, specify it in xpath.
|
|
309
303
|
|
|
304
|
+
for example:
|
|
305
|
+
|
|
306
|
+
```python
|
|
307
|
+
# Do not use:
|
|
308
|
+
# @precondition(lambda self:
|
|
309
|
+
# self.d(className="android.widget.ListView").child(text="Bluetooth")
|
|
310
|
+
# ):
|
|
311
|
+
# ...
|
|
312
|
+
|
|
313
|
+
# Use
|
|
314
|
+
@precondition(lambda self:
|
|
315
|
+
self.d.xpath('//android.widget.ListView/*[@text="Bluetooth"]')
|
|
316
|
+
):
|
|
317
|
+
...
|
|
318
|
+
```
|
|
319
|
+
|
|
310
320
|
|
|
311
321
|
## Launching Kea2
|
|
312
322
|
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import subprocess
|
|
2
2
|
from typing import List, Optional
|
|
3
|
+
from .utils import getLogger
|
|
4
|
+
|
|
5
|
+
logger = getLogger(__name__)
|
|
6
|
+
|
|
3
7
|
|
|
4
8
|
def run_adb_command(cmd: List[str], timeout=10):
|
|
5
9
|
"""
|
|
@@ -13,6 +17,7 @@ def run_adb_command(cmd: List[str], timeout=10):
|
|
|
13
17
|
str: The standard output from the command. If an error occurs, returns None.
|
|
14
18
|
"""
|
|
15
19
|
full_cmd = ["adb"] + cmd
|
|
20
|
+
logger.debug(f"{' '.join(full_cmd)}")
|
|
16
21
|
try:
|
|
17
22
|
result = subprocess.run(full_cmd, capture_output=True, text=True, timeout=timeout)
|
|
18
23
|
if result.returncode != 0:
|
|
@@ -57,7 +57,7 @@ PACKAGE_NAME = "it.feio.android.omninotes.alpha"
|
|
|
57
57
|
FILE_NAME = "omninotes.apk"
|
|
58
58
|
|
|
59
59
|
|
|
60
|
-
def check_installation():
|
|
60
|
+
def check_installation(serial=None):
|
|
61
61
|
import os
|
|
62
62
|
from pathlib import Path
|
|
63
63
|
if not os.path.exists(Path(".") / FILE_NAME):
|
|
@@ -65,7 +65,7 @@ def check_installation():
|
|
|
65
65
|
import urllib.request
|
|
66
66
|
urllib.request.urlretrieve(URL, FILE_NAME)
|
|
67
67
|
|
|
68
|
-
d = u2.connect()
|
|
68
|
+
d = u2.connect(serial)
|
|
69
69
|
# automatically install omni-notes
|
|
70
70
|
if PACKAGE_NAME not in d.app_list():
|
|
71
71
|
print("[INFO] Installing omninotes.", flush=True)
|
|
@@ -74,7 +74,7 @@ def check_installation():
|
|
|
74
74
|
|
|
75
75
|
|
|
76
76
|
if __name__ == "__main__":
|
|
77
|
-
check_installation()
|
|
77
|
+
check_installation(serial=None)
|
|
78
78
|
KeaTestRunner.setOptions(
|
|
79
79
|
Options(
|
|
80
80
|
driverName="d",
|
|
@@ -19,9 +19,10 @@ from .utils import TimeStamp, getProjectRoot, getLogger
|
|
|
19
19
|
from .u2Driver import StaticU2UiObject
|
|
20
20
|
import uiautomator2 as u2
|
|
21
21
|
import types
|
|
22
|
+
|
|
22
23
|
PRECONDITIONS_MARKER = "preconds"
|
|
23
24
|
PROP_MARKER = "prop"
|
|
24
|
-
|
|
25
|
+
MAX_TRIES_MARKER = "max_tries"
|
|
25
26
|
|
|
26
27
|
logger = getLogger(__name__)
|
|
27
28
|
|
|
@@ -30,14 +31,14 @@ logger = getLogger(__name__)
|
|
|
30
31
|
PropName = NewType("PropName", str)
|
|
31
32
|
PropertyStore = NewType("PropertyStore", Dict[PropName, TestCase])
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
LOGFILE = f"fastbot_{
|
|
35
|
-
RESFILE = f"result_{
|
|
34
|
+
STAMP = TimeStamp().getTimeStamp()
|
|
35
|
+
LOGFILE = f"fastbot_{STAMP}.log"
|
|
36
|
+
RESFILE = f"result_{STAMP}.json"
|
|
36
37
|
|
|
37
38
|
def precondition(precond: Callable[[Any], bool]) -> Callable:
|
|
38
39
|
"""the decorator @precondition
|
|
39
40
|
|
|
40
|
-
|
|
41
|
+
@precondition specifies when the property could be executed.
|
|
41
42
|
A property could have multiple preconditions, each of which is specified by @precondition.
|
|
42
43
|
"""
|
|
43
44
|
def accept(f):
|
|
@@ -56,7 +57,7 @@ def precondition(precond: Callable[[Any], bool]) -> Callable:
|
|
|
56
57
|
def prob(p: float):
|
|
57
58
|
"""the decorator @prob
|
|
58
59
|
|
|
59
|
-
|
|
60
|
+
@prob specify the propbability of execution when a property is satisfied.
|
|
60
61
|
"""
|
|
61
62
|
p = float(p)
|
|
62
63
|
if not 0 < p <= 1.0:
|
|
@@ -73,6 +74,26 @@ def prob(p: float):
|
|
|
73
74
|
return accept
|
|
74
75
|
|
|
75
76
|
|
|
77
|
+
def max_tries(n: int):
|
|
78
|
+
"""the decorator @max_tries
|
|
79
|
+
|
|
80
|
+
@max_tries specify the maximum tries of executing a property.
|
|
81
|
+
"""
|
|
82
|
+
n = int(n)
|
|
83
|
+
if not n > 0:
|
|
84
|
+
raise ValueError("The maxium tries should be a positive integer.")
|
|
85
|
+
def accept(f):
|
|
86
|
+
@wraps(f)
|
|
87
|
+
def precondition_wrapper(*args, **kwargs):
|
|
88
|
+
return f(*args, **kwargs)
|
|
89
|
+
|
|
90
|
+
setattr(precondition_wrapper, MAX_TRIES_MARKER, n)
|
|
91
|
+
|
|
92
|
+
return precondition_wrapper
|
|
93
|
+
|
|
94
|
+
return accept
|
|
95
|
+
|
|
96
|
+
|
|
76
97
|
@dataclass
|
|
77
98
|
class Options:
|
|
78
99
|
"""
|
|
@@ -96,6 +117,16 @@ class Options:
|
|
|
96
117
|
throttle: int = 200
|
|
97
118
|
# the output_dir for saving logs and results
|
|
98
119
|
output_dir: str = "output"
|
|
120
|
+
# the stamp for log file and result file, default: current time stamp
|
|
121
|
+
log_stamp: str = None
|
|
122
|
+
|
|
123
|
+
def __post_init__(self):
|
|
124
|
+
if self.serial and self.Driver:
|
|
125
|
+
self.Driver.setDeviceSerial(self.serial)
|
|
126
|
+
if self.log_stamp:
|
|
127
|
+
global LOGFILE, RESFILE
|
|
128
|
+
LOGFILE = f"fastbot_{self.log_stamp}.log"
|
|
129
|
+
RESFILE = f"result_{self.log_stamp}.json"
|
|
99
130
|
|
|
100
131
|
|
|
101
132
|
@dataclass
|
|
@@ -147,6 +178,9 @@ class JsonResult(TextTestResult):
|
|
|
147
178
|
super().addError(test, err)
|
|
148
179
|
self.res[getFullPropName(test)].error += 1
|
|
149
180
|
|
|
181
|
+
def getExcuted(self, test: TestCase):
|
|
182
|
+
return self.res[getFullPropName(test)].executed
|
|
183
|
+
|
|
150
184
|
|
|
151
185
|
def activateFastbot(options: Options, port=None) -> threading.Thread:
|
|
152
186
|
"""
|
|
@@ -270,6 +304,8 @@ class KeaTestRunner(TextTestRunner):
|
|
|
270
304
|
global LOGFILE, RESFILE
|
|
271
305
|
LOGFILE = output_dir / Path(LOGFILE)
|
|
272
306
|
RESFILE = output_dir / Path(RESFILE)
|
|
307
|
+
logger.debug(f"Log file: {LOGFILE}")
|
|
308
|
+
logger.debug(f"Result file: {RESFILE}")
|
|
273
309
|
|
|
274
310
|
def run(self, test):
|
|
275
311
|
|
|
@@ -329,7 +365,7 @@ class KeaTestRunner(TextTestRunner):
|
|
|
329
365
|
, flush=True)
|
|
330
366
|
|
|
331
367
|
try:
|
|
332
|
-
propsSatisfiedPrecond = self.getValidProperties()
|
|
368
|
+
propsSatisfiedPrecond = self.getValidProperties(result)
|
|
333
369
|
except requests.ConnectionError:
|
|
334
370
|
print(
|
|
335
371
|
"[INFO] Exploration times up (--running-minutes)."
|
|
@@ -421,6 +457,8 @@ class KeaTestRunner(TextTestRunner):
|
|
|
421
457
|
"""
|
|
422
458
|
block_widgets: List[str] = self._getBlockedWidgets()
|
|
423
459
|
URL = f"http://localhost:{self.scriptDriver.lport}/stepMonkey"
|
|
460
|
+
logger.debug(f"Sending request: {URL}")
|
|
461
|
+
logger.debug(f"Blocking widgets: {block_widgets}")
|
|
424
462
|
r = requests.post(
|
|
425
463
|
url=URL,
|
|
426
464
|
json={
|
|
@@ -436,12 +474,14 @@ class KeaTestRunner(TextTestRunner):
|
|
|
436
474
|
"""
|
|
437
475
|
send a stop monkey request to the server and get the xml string.
|
|
438
476
|
"""
|
|
439
|
-
|
|
477
|
+
URL = f"http://localhost:{self.scriptDriver.lport}/stopMonkey"
|
|
478
|
+
logger.debug(f"Sending request: {URL}")
|
|
479
|
+
r = requests.get(URL)
|
|
440
480
|
|
|
441
481
|
res = r.content.decode(encoding="utf-8")
|
|
442
482
|
print(f"[Server INFO] {res}", flush=True)
|
|
443
483
|
|
|
444
|
-
def getValidProperties(self) -> PropertyStore:
|
|
484
|
+
def getValidProperties(self, result: JsonResult) -> PropertyStore:
|
|
445
485
|
|
|
446
486
|
xml_raw = self.stepMonkey()
|
|
447
487
|
staticCheckerDriver = self.options.Driver.getStaticChecker(hierarchy=xml_raw)
|
|
@@ -466,6 +506,10 @@ class KeaTestRunner(TextTestRunner):
|
|
|
466
506
|
break
|
|
467
507
|
# if all the precond passed. make it the candidate prop.
|
|
468
508
|
if valid:
|
|
509
|
+
logger.debug(f"precond satisfied: {getFullPropName(test)}")
|
|
510
|
+
if result.getExcuted(test) >= getattr(prop, MAX_TRIES_MARKER, float("inf")):
|
|
511
|
+
logger.debug(f"{getFullPropName(test)} has reached its max_tries. Skip.")
|
|
512
|
+
continue
|
|
469
513
|
validProps[propName] = test
|
|
470
514
|
return validProps
|
|
471
515
|
|
|
@@ -566,6 +610,8 @@ class KeaTestRunner(TextTestRunner):
|
|
|
566
610
|
|
|
567
611
|
return blocked_widgets
|
|
568
612
|
|
|
569
|
-
def
|
|
570
|
-
|
|
571
|
-
|
|
613
|
+
def __del__(self):
|
|
614
|
+
"""tearDown method. Cleanup the env.
|
|
615
|
+
"""
|
|
616
|
+
if self.options.Driver:
|
|
617
|
+
self.options.Driver.tearDown()
|
|
@@ -76,6 +76,14 @@ def _set_runner_parser(subparsers: "argparse._SubParsersAction[argparse.Argument
|
|
|
76
76
|
help="The name of driver in script.",
|
|
77
77
|
)
|
|
78
78
|
|
|
79
|
+
parser.add_argument(
|
|
80
|
+
"--log-stamp",
|
|
81
|
+
dest="log_stamp",
|
|
82
|
+
type=str,
|
|
83
|
+
required=False,
|
|
84
|
+
help="the stamp for log file and result file, default: current time stamp",
|
|
85
|
+
)
|
|
86
|
+
|
|
79
87
|
parser.add_argument(
|
|
80
88
|
"extra",
|
|
81
89
|
nargs=argparse.REMAINDER,
|
|
@@ -130,7 +138,6 @@ def run(args=None):
|
|
|
130
138
|
|
|
131
139
|
from kea2 import KeaTestRunner, Options
|
|
132
140
|
from kea2.u2Driver import U2Driver
|
|
133
|
-
U2Driver.setDeviceSerial(args.serial)
|
|
134
141
|
options = Options(
|
|
135
142
|
agent=args.agent,
|
|
136
143
|
driverName=args.driver_name,
|
|
@@ -139,7 +146,8 @@ def run(args=None):
|
|
|
139
146
|
serial=args.serial,
|
|
140
147
|
running_mins=args.running_minutes if args.running_minutes else 10,
|
|
141
148
|
maxStep=args.max_step if args.max_step else 500,
|
|
142
|
-
throttle=args.throttle_ms if args.throttle_ms else 200
|
|
149
|
+
throttle=args.throttle_ms if args.throttle_ms else 200,
|
|
150
|
+
log_stamp=args.log_stamp
|
|
143
151
|
)
|
|
144
152
|
|
|
145
153
|
KeaTestRunner.setOptions(options)
|
|
@@ -8,7 +8,7 @@ from typing import Dict, List, Union
|
|
|
8
8
|
from lxml import etree
|
|
9
9
|
from .absDriver import AbstractScriptDriver, AbstractStaticChecker, AbstractDriver
|
|
10
10
|
from .adbUtils import list_forwards, remove_forward, create_forward
|
|
11
|
-
from .utils import TimeStamp
|
|
11
|
+
from .utils import TimeStamp, getLogger
|
|
12
12
|
|
|
13
13
|
TIME_STAMP = TimeStamp().getTimeStamp()
|
|
14
14
|
|
|
@@ -16,6 +16,8 @@ import logging
|
|
|
16
16
|
logging.getLogger("urllib3").setLevel(logging.INFO)
|
|
17
17
|
logging.getLogger("uiautomator2").setLevel(logging.INFO)
|
|
18
18
|
|
|
19
|
+
logger = getLogger(__name__)
|
|
20
|
+
|
|
19
21
|
"""
|
|
20
22
|
The definition of U2ScriptDriver
|
|
21
23
|
"""
|
|
@@ -57,16 +59,13 @@ class U2ScriptDriver(AbstractScriptDriver):
|
|
|
57
59
|
setattr(self.d._dev, "msg", "meta")
|
|
58
60
|
print(f"[U2] local port: {lport}", flush=True)
|
|
59
61
|
return lport
|
|
60
|
-
|
|
62
|
+
|
|
61
63
|
self._remove_remote_port(8090)
|
|
62
64
|
self.d.lport = get_u2_forward_port()
|
|
63
65
|
self._remove_remote_port(9008)
|
|
64
66
|
|
|
65
67
|
return self.d
|
|
66
68
|
|
|
67
|
-
def tearDown(self):
|
|
68
|
-
self.d.stop_uiautomator()
|
|
69
|
-
|
|
70
69
|
def _remove_remote_port(self, port:int):
|
|
71
70
|
"""remove the forward port
|
|
72
71
|
"""
|
|
@@ -76,6 +75,11 @@ class U2ScriptDriver(AbstractScriptDriver):
|
|
|
76
75
|
forward_local = forward["local"]
|
|
77
76
|
remove_forward(local_spec=forward_local, device=self.deviceSerial)
|
|
78
77
|
|
|
78
|
+
def tearDown(self):
|
|
79
|
+
logger.debug("U2Driver tearDown: stop_uiautomator")
|
|
80
|
+
self.d.stop_uiautomator()
|
|
81
|
+
logger.debug("U2Driver tearDown: remove forward")
|
|
82
|
+
self._remove_remote_port(8090)
|
|
79
83
|
|
|
80
84
|
"""
|
|
81
85
|
The definition of U2StaticChecker
|
|
@@ -88,7 +92,9 @@ class StaticU2UiObject(u2.UiObject):
|
|
|
88
92
|
def _transferU2Keys(self, originKey):
|
|
89
93
|
filterDict = {
|
|
90
94
|
"resourceId": "resource-id",
|
|
91
|
-
"description": "content-desc"
|
|
95
|
+
"description": "content-desc",
|
|
96
|
+
"className": "class",
|
|
97
|
+
"longClickable": "long-clickable",
|
|
92
98
|
}
|
|
93
99
|
if filterDict.get(originKey, None):
|
|
94
100
|
return filterDict[originKey]
|
|
@@ -229,6 +235,7 @@ class U2StaticDevice(u2.Device):
|
|
|
229
235
|
|
|
230
236
|
def __getattr__(self, attr):
|
|
231
237
|
"""Proxy other methods to script_driver"""
|
|
238
|
+
# logger.debug(f"{attr} not exists in static checker, proxy to script_driver.")
|
|
232
239
|
return getattr(self._script_driver, attr)
|
|
233
240
|
|
|
234
241
|
class _XPathEntry(u2.xpath.XPathEntry):
|
|
@@ -237,6 +244,7 @@ class _XPathEntry(u2.xpath.XPathEntry):
|
|
|
237
244
|
super().__init__(d)
|
|
238
245
|
|
|
239
246
|
def __call__(self, xpath, source = None):
|
|
247
|
+
# TODO fully support xpath in widget.block.py
|
|
240
248
|
self.xpath = xpath
|
|
241
249
|
return super().__call__(xpath, source)
|
|
242
250
|
|
|
@@ -290,6 +298,10 @@ class U2Driver(AbstractDriver):
|
|
|
290
298
|
self.staticChecker = U2StaticChecker()
|
|
291
299
|
return self.staticChecker.getInstance(hierarchy)
|
|
292
300
|
|
|
301
|
+
@classmethod
|
|
302
|
+
def tearDown(self):
|
|
303
|
+
self.scriptDriver.tearDown()
|
|
304
|
+
|
|
293
305
|
|
|
294
306
|
"""
|
|
295
307
|
Other Utils
|
|
@@ -308,6 +320,7 @@ def forward_port(self, remote: Union[int, str]) -> int:
|
|
|
308
320
|
return int(f.local[len("tcp:") :])
|
|
309
321
|
local_port = get_free_port()
|
|
310
322
|
self.forward("tcp:" + str(local_port), remote)
|
|
323
|
+
logger.debug(f"forwading port: tcp:{local_port} -> {remote}")
|
|
311
324
|
return local_port
|
|
312
325
|
|
|
313
326
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "Kea2-python"
|
|
3
|
-
version = "0.0.
|
|
3
|
+
version = "0.0.1b1"
|
|
4
4
|
description = "A python library for supporting and customizing automated UI testing for mobile apps"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.8"
|
|
@@ -19,4 +19,4 @@ kea2 = "kea2.cli:main"
|
|
|
19
19
|
include = ["kea2"]
|
|
20
20
|
|
|
21
21
|
[tool.setuptools.package-data]
|
|
22
|
-
kea2 = ["assets/**/*"]
|
|
22
|
+
kea2 = ["assets/**/*"]
|
|
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
|
{kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot_libs/arm64-v8a/libfastbot_native.so
RENAMED
|
File without changes
|
|
File without changes
|
{kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot_libs/x86/libfastbot_native.so
RENAMED
|
File without changes
|
{kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot_libs/x86_64/libfastbot_native.so
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|