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.

Files changed (39) hide show
  1. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1/Kea2_python.egg-info}/PKG-INFO +26 -4
  2. kea2_python-0.0.1a6/README.md → kea2_python-0.0.1b1/PKG-INFO +37 -3
  3. kea2_python-0.0.1a6/Kea2_python.egg-info/PKG-INFO → kea2_python-0.0.1b1/README.md +25 -15
  4. kea2_python-0.0.1b1/kea2/__init__.py +4 -0
  5. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/absDriver.py +4 -0
  6. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/adbUtils.py +5 -0
  7. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/quicktest.py +3 -3
  8. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/cli.py +1 -1
  9. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/keaUtils.py +58 -12
  10. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/kea_launcher.py +10 -2
  11. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/u2Driver.py +19 -6
  12. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/pyproject.toml +2 -2
  13. kea2_python-0.0.1a6/kea2/__init__.py +0 -4
  14. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/Kea2_python.egg-info/SOURCES.txt +0 -0
  15. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/Kea2_python.egg-info/dependency_links.txt +0 -0
  16. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/Kea2_python.egg-info/entry_points.txt +0 -0
  17. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/Kea2_python.egg-info/requires.txt +0 -0
  18. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/Kea2_python.egg-info/top_level.txt +0 -0
  19. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/LICENSE +0 -0
  20. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot-thirdpart.jar +0 -0
  21. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot_configs/ADBKeyBoard.apk +0 -0
  22. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot_configs/abl.strings +0 -0
  23. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot_configs/awl.strings +0 -0
  24. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot_configs/max.config +0 -0
  25. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot_configs/max.fuzzing.strings +0 -0
  26. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot_configs/max.schema.strings +0 -0
  27. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot_configs/max.strings +0 -0
  28. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot_configs/max.tree.pruning +0 -0
  29. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot_configs/widget.block.py +0 -0
  30. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot_libs/arm64-v8a/libfastbot_native.so +0 -0
  31. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot_libs/armeabi-v7a/libfastbot_native.so +0 -0
  32. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot_libs/x86/libfastbot_native.so +0 -0
  33. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/fastbot_libs/x86_64/libfastbot_native.so +0 -0
  34. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/framework.jar +0 -0
  35. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/monkeyq.jar +0 -0
  36. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/assets/u2.jar +0 -0
  37. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/logWatcher.py +0 -0
  38. {kea2_python-0.0.1a6 → kea2_python-0.0.1b1}/kea2/utils.py +0 -0
  39. {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.1a6
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
+ [![PyPI](https://img.shields.io/pypi/v/kea2-python.svg)](https://pypi.python.org/pypi/kea2-python)
16
+ [![PyPI Downloads](https://static.pepy.tech/badge/kea2-python)](https://pepy.tech/projects/kea2-python)
17
+ ![Python](https://img.shields.io/badge/python-3.8%2B-blue)
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) and basic xpath (No chain call like `.xpath().xpath()`) in uiautomator2. The Script body in the function fully support uiautomator2.
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
+ [![PyPI](https://img.shields.io/pypi/v/kea2-python.svg)](https://pypi.python.org/pypi/kea2-python)
16
+ [![PyPI Downloads](https://static.pepy.tech/badge/kea2-python)](https://pepy.tech/projects/kea2-python)
17
+ ![Python](https://img.shields.io/badge/python-3.8%2B-blue)
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) and basic xpath (No chain call like `.xpath().xpath()`) in uiautomator2. The Script body in the function fully support uiautomator2.
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
+ [![PyPI](https://img.shields.io/pypi/v/kea2-python.svg)](https://pypi.python.org/pypi/kea2-python)
4
+ [![PyPI Downloads](https://static.pepy.tech/badge/kea2-python)](https://pepy.tech/projects/kea2-python)
5
+ ![Python](https://img.shields.io/badge/python-3.8%2B-blue)
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) and basic xpath (No chain call like `.xpath().xpath()`) in uiautomator2. The Script body in the function fully support uiautomator2.
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
 
@@ -0,0 +1,4 @@
1
+ from .keaUtils import KeaTestRunner, precondition, prob, max_tries, Options
2
+
3
+ import logging
4
+ logging.basicConfig(level=logging.DEBUG)
@@ -50,3 +50,7 @@ class AbstractDriver(abc.ABC):
50
50
  @abc.abstractmethod
51
51
  def getStaticChecker(self, hierarchy) -> AbstractStaticChecker:
52
52
  pass
53
+
54
+ @classmethod
55
+ @abc.abstractmethod
56
+ def tearDown(self): ...
@@ -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",
@@ -3,7 +3,7 @@
3
3
 
4
4
  from __future__ import absolute_import, print_function
5
5
  import sys
6
- from kea2.utils import getProjectRoot, getLogger
6
+ from .utils import getProjectRoot, getLogger
7
7
  from .kea_launcher import run
8
8
  import argparse
9
9
 
@@ -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
- TIME_STAMP = TimeStamp().getTimeStamp()
34
- LOGFILE = f"fastbot_{TIME_STAMP}.log"
35
- RESFILE = f"result_{TIME_STAMP}.json"
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
- The precondition specifies when the property could be executed.
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
- The prob specify the propbability of execution when a property is satisfied.
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
- r = requests.get(f"http://localhost:{self.scriptDriver.lport}/stopMonkey")
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 tearDown(self):
570
- # TODO Add tearDown method (remove local port, etc.)
571
- pass
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.1a6"
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/**/*"]
@@ -1,4 +0,0 @@
1
- from .keaUtils import KeaTestRunner, precondition, prob, Options
2
-
3
- import logging
4
- logging.basicConfig(level=logging.DEBUG)
File without changes
File without changes