Kea2-python 0.3.0__py3-none-any.whl → 0.3.2__py3-none-any.whl
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/bug_report_generator.py +66 -75
- kea2/fastbotManager.py +3 -2
- kea2/keaUtils.py +11 -20
- kea2/report_merger.py +29 -16
- kea2/templates/bug_report_template.html +606 -285
- kea2/templates/merged_bug_report_template.html +1057 -355
- kea2/u2Driver.py +128 -5
- kea2/utils.py +50 -9
- {kea2_python-0.3.0.dist-info → kea2_python-0.3.2.dist-info}/METADATA +71 -8
- {kea2_python-0.3.0.dist-info → kea2_python-0.3.2.dist-info}/RECORD +14 -14
- {kea2_python-0.3.0.dist-info → kea2_python-0.3.2.dist-info}/WHEEL +0 -0
- {kea2_python-0.3.0.dist-info → kea2_python-0.3.2.dist-info}/entry_points.txt +0 -0
- {kea2_python-0.3.0.dist-info → kea2_python-0.3.2.dist-info}/licenses/LICENSE +0 -0
- {kea2_python-0.3.0.dist-info → kea2_python-0.3.2.dist-info}/top_level.txt +0 -0
kea2/u2Driver.py
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
import functools
|
|
1
2
|
import random
|
|
2
3
|
import socket
|
|
4
|
+
import time
|
|
3
5
|
from time import sleep
|
|
4
6
|
import uiautomator2 as u2
|
|
5
7
|
import adbutils
|
|
6
8
|
import types
|
|
7
9
|
import rtree
|
|
8
10
|
import re
|
|
9
|
-
from typing import Any, Dict, List, Union
|
|
11
|
+
from typing import Any, Dict, List, Union, Optional
|
|
10
12
|
from http.client import HTTPResponse
|
|
11
13
|
from lxml import etree
|
|
12
14
|
from .absDriver import AbstractScriptDriver, AbstractStaticChecker, AbstractDriver
|
|
@@ -205,6 +207,122 @@ class StaticU2UiObject(u2.UiObject):
|
|
|
205
207
|
def __getattr__(self, attr):
|
|
206
208
|
return getattr(super(), attr)
|
|
207
209
|
|
|
210
|
+
"""
|
|
211
|
+
The definition of XpathStaticChecker
|
|
212
|
+
"""
|
|
213
|
+
class StaticXpathUiObject(u2.xpath.XPathSelector):
|
|
214
|
+
def __init__(self, session, selector):
|
|
215
|
+
self.session: U2StaticDevice = session
|
|
216
|
+
self.selector = selector
|
|
217
|
+
|
|
218
|
+
@property
|
|
219
|
+
def exists(self):
|
|
220
|
+
source = self.session.get_page_source()
|
|
221
|
+
return len(self.selector.all(source)) > 0
|
|
222
|
+
|
|
223
|
+
def __and__(self, value) -> 'StaticXpathUiObjectr':
|
|
224
|
+
s = u2.xpath.XPathSelector(self.selector)
|
|
225
|
+
s._next_xpath = u2.xpath.XPathSelector.create(value.selector)
|
|
226
|
+
s._operator = u2.xpath.Operator.AND
|
|
227
|
+
s._parent = self.selector._parent
|
|
228
|
+
self.selector = s
|
|
229
|
+
return self
|
|
230
|
+
|
|
231
|
+
def __or__(self, value) -> 'StaticXpathUiObject':
|
|
232
|
+
s = u2.xpath.XPathSelector(self.selector)
|
|
233
|
+
s._next_xpath = u2.xpath.XPathSelector.create(value.selector)
|
|
234
|
+
s._operator = u2.xpath.Operator.OR
|
|
235
|
+
s._parent = self.selector._parent
|
|
236
|
+
self.selector = s
|
|
237
|
+
return self
|
|
238
|
+
|
|
239
|
+
def selector_to_xpath(self, selector: u2.xpath.XPathSelector) -> str:
|
|
240
|
+
"""
|
|
241
|
+
Convert an XPathSelector to a standard XPath expression.
|
|
242
|
+
|
|
243
|
+
Args:
|
|
244
|
+
selector: The XPathSelector object to convert.
|
|
245
|
+
|
|
246
|
+
Returns:
|
|
247
|
+
A standard XPath expression as a string.
|
|
248
|
+
"""
|
|
249
|
+
|
|
250
|
+
def _handle_path(path):
|
|
251
|
+
if isinstance(path, u2.xpath.XPathSelector):
|
|
252
|
+
return self.selector_to_xpath(path)
|
|
253
|
+
elif isinstance(path, u2.xpath.XPath):
|
|
254
|
+
return str(path)
|
|
255
|
+
else:
|
|
256
|
+
return path
|
|
257
|
+
|
|
258
|
+
base_xpath = _handle_path(selector._base_xpath)
|
|
259
|
+
base_xpath = base_xpath.replace('//*', './/node')
|
|
260
|
+
|
|
261
|
+
if selector._operator is None:
|
|
262
|
+
return base_xpath
|
|
263
|
+
else:
|
|
264
|
+
print("Unsupported operator: {}".format(selector._operator))
|
|
265
|
+
return "//error"
|
|
266
|
+
|
|
267
|
+
def xpath(self, _xpath: Union[list, tuple, str]) -> 'StaticXpathUiObject':
|
|
268
|
+
"""
|
|
269
|
+
add xpath to condition list
|
|
270
|
+
the element should match all conditions
|
|
271
|
+
|
|
272
|
+
Deprecated, using a & b instead
|
|
273
|
+
"""
|
|
274
|
+
if isinstance(_xpath, (list, tuple)):
|
|
275
|
+
self.selector = functools.reduce(lambda a, b: a & b, _xpath, self)
|
|
276
|
+
else:
|
|
277
|
+
self.selector = self.selector & _xpath
|
|
278
|
+
return self
|
|
279
|
+
|
|
280
|
+
def child(self, _xpath: str) -> "StaticXpathUiObject":
|
|
281
|
+
"""
|
|
282
|
+
add child xpath
|
|
283
|
+
"""
|
|
284
|
+
if self.selector._operator or not isinstance(self.selector._base_xpath, u2.xpath.XPath):
|
|
285
|
+
raise u2.xpath.XPathError("can't use child when base is not XPath or operator is set")
|
|
286
|
+
new = self.selector.copy()
|
|
287
|
+
new._base_xpath = self.selector._base_xpath.joinpath(_xpath)
|
|
288
|
+
self.selector = new
|
|
289
|
+
return self
|
|
290
|
+
|
|
291
|
+
def get(self, timeout=None) -> "XMLElement":
|
|
292
|
+
"""
|
|
293
|
+
Get first matched element
|
|
294
|
+
|
|
295
|
+
Args:
|
|
296
|
+
timeout (float): max seconds to wait
|
|
297
|
+
|
|
298
|
+
Returns:
|
|
299
|
+
XMLElement
|
|
300
|
+
|
|
301
|
+
"""
|
|
302
|
+
if not self.exists:
|
|
303
|
+
return None
|
|
304
|
+
return self.get_last_match()
|
|
305
|
+
|
|
306
|
+
def get_last_match(self) -> "u2.xpath.XMLElement":
|
|
307
|
+
return self.selector.all(self.selector._last_source)[0]
|
|
308
|
+
|
|
309
|
+
def parent_exists(self, xpath: Optional[str] = None):
|
|
310
|
+
el = self.get()
|
|
311
|
+
if el is None:
|
|
312
|
+
return False
|
|
313
|
+
element = el.parent(xpath) if hasattr(el, 'parent') else None
|
|
314
|
+
return True if element is not None else False
|
|
315
|
+
|
|
316
|
+
def __getattr__(self, key: str):
|
|
317
|
+
"""
|
|
318
|
+
In IPython console, attr:_ipython_canary_method_should_not_exist_ will be called
|
|
319
|
+
So here ignore all attr startswith _
|
|
320
|
+
"""
|
|
321
|
+
if key.startswith("_"):
|
|
322
|
+
raise AttributeError("Invalid attr", key)
|
|
323
|
+
if not hasattr(u2.xpath.XMLElement, key):
|
|
324
|
+
raise AttributeError("Invalid attr", key)
|
|
325
|
+
return getattr(super(), key)
|
|
208
326
|
|
|
209
327
|
def _get_bounds(raw_bounds):
|
|
210
328
|
pattern = re.compile(r"\[(-?\d+),(-?\d+)\]\[(-?\d+),(-?\d+)\]")
|
|
@@ -299,7 +417,8 @@ class U2StaticDevice(u2.Device):
|
|
|
299
417
|
def xpath(self) -> u2.xpath.XPathEntry:
|
|
300
418
|
def get_page_source(self):
|
|
301
419
|
# print("[Debug] Using static get_page_source method")
|
|
302
|
-
|
|
420
|
+
xml_raw = etree.tostring(self._d.xml, encoding='unicode')
|
|
421
|
+
return u2.xpath.PageSource.parse(xml_raw)
|
|
303
422
|
xpathEntry = _XPathEntry(self)
|
|
304
423
|
xpathEntry.get_page_source = types.MethodType(
|
|
305
424
|
get_page_source, xpathEntry
|
|
@@ -316,10 +435,14 @@ class _XPathEntry(u2.xpath.XPathEntry):
|
|
|
316
435
|
self.xpath = None
|
|
317
436
|
super().__init__(d)
|
|
318
437
|
|
|
319
|
-
def __call__(self, xpath, source = None):
|
|
438
|
+
# def __call__(self, xpath, source = None):
|
|
320
439
|
# TODO fully support xpath in widget.block.py
|
|
321
|
-
self.xpath = xpath
|
|
322
|
-
return super().__call__(xpath, source)
|
|
440
|
+
# self.xpath = xpath
|
|
441
|
+
# return super().__call__(xpath, source)
|
|
442
|
+
def __call__(self, xpath, source=None):
|
|
443
|
+
ui = StaticXpathUiObject(session=self, selector=u2.xpath.XPathSelector(xpath, source=source))
|
|
444
|
+
return ui
|
|
445
|
+
|
|
323
446
|
|
|
324
447
|
|
|
325
448
|
class U2StaticChecker(AbstractStaticChecker):
|
kea2/utils.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import os
|
|
3
3
|
from pathlib import Path
|
|
4
|
+
import traceback
|
|
4
5
|
from typing import TYPE_CHECKING
|
|
5
6
|
|
|
6
7
|
import time
|
|
@@ -26,6 +27,9 @@ def getLogger(name: str) -> logging.Logger:
|
|
|
26
27
|
return logger
|
|
27
28
|
|
|
28
29
|
|
|
30
|
+
logger = getLogger(__name__)
|
|
31
|
+
|
|
32
|
+
|
|
29
33
|
def singleton(cls):
|
|
30
34
|
_instance = {}
|
|
31
35
|
|
|
@@ -60,12 +64,49 @@ def getProjectRoot():
|
|
|
60
64
|
return cur_dir
|
|
61
65
|
|
|
62
66
|
|
|
63
|
-
def timer(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
67
|
+
def timer(log_info: str=None):
|
|
68
|
+
""" ### Decorator to measure the execution time of a function.
|
|
69
|
+
|
|
70
|
+
This decorator can be used to wrap functions where you want to log the time taken for execution
|
|
71
|
+
|
|
72
|
+
### Usage:
|
|
73
|
+
- @timer("Function execution took %cost_time seconds.")
|
|
74
|
+
- @timer() # If no log_info is provided, it will print the function name and execution time.
|
|
75
|
+
|
|
76
|
+
`%cost_time` will be replaced with the actual time taken for execution.
|
|
77
|
+
"""
|
|
78
|
+
def accept(func):
|
|
79
|
+
@wraps(func)
|
|
80
|
+
def wrapper(*args, **kwargs):
|
|
81
|
+
start_time = time.time()
|
|
82
|
+
result = func(*args, **kwargs)
|
|
83
|
+
end_time = time.time()
|
|
84
|
+
if log_info:
|
|
85
|
+
logger.info(log_info.replace(r"%cost_time", f"{end_time - start_time:.4f}"))
|
|
86
|
+
else:
|
|
87
|
+
logger.info(f"Function '{func.__name__}' executed in {(end_time - start_time):.4f} seconds.")
|
|
88
|
+
return result
|
|
89
|
+
return wrapper
|
|
90
|
+
return accept
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def catchException(log_info: str):
|
|
94
|
+
""" ### Decorator to catch exceptions and print log info.
|
|
95
|
+
|
|
96
|
+
This decorator can be used to wrap functions that may raise exceptions,
|
|
97
|
+
allowing you to log a message when the exception is raised.
|
|
98
|
+
|
|
99
|
+
### Usage:
|
|
100
|
+
- @catchException("An error occurred in the function ****.")
|
|
101
|
+
"""
|
|
102
|
+
def accept(func):
|
|
103
|
+
@wraps(func)
|
|
104
|
+
def wrapper(*args, **kwargs):
|
|
105
|
+
try:
|
|
106
|
+
return func(*args, **kwargs)
|
|
107
|
+
except Exception as e:
|
|
108
|
+
logger.info(log_info)
|
|
109
|
+
tb = traceback.format_exception(type(e), e, e.__traceback__.tb_next)
|
|
110
|
+
print(''.join(tb), end='', flush=True)
|
|
111
|
+
return wrapper
|
|
112
|
+
return accept
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: Kea2-python
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
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
|
|
@@ -10,6 +10,7 @@ Requires-Dist: rtree>=1.3.0
|
|
|
10
10
|
Requires-Dist: jinja2>=3.0.0
|
|
11
11
|
Requires-Dist: uiautomator2>=3.3.3
|
|
12
12
|
Requires-Dist: adbutils>=2.9.3
|
|
13
|
+
Requires-Dist: setuptools>=75.3.2
|
|
13
14
|
Dynamic: license-file
|
|
14
15
|
|
|
15
16
|
|
|
@@ -17,6 +18,7 @@ Dynamic: license-file
|
|
|
17
18
|
[](https://pypi.python.org/pypi/kea2-python)
|
|
18
19
|
[](https://pepy.tech/projects/kea2-python)
|
|
19
20
|

|
|
21
|
+
[](https://deepwiki.com/ecnusse/Kea2)
|
|
20
22
|
|
|
21
23
|
<div>
|
|
22
24
|
<img src="https://github.com/user-attachments/assets/84e47b87-2dd2-4d7e-91d1-e8c1d1db0cf4" style="border-radius: 14px; width: 20%; height: 20%;"/>
|
|
@@ -31,6 +33,13 @@ The group has reached its capacity. Please contact Xixian Liang at [xixian@stu.e
|
|
|
31
33
|
|
|
32
34
|
## About
|
|
33
35
|
|
|
36
|
+
<div align="center">
|
|
37
|
+
<img src="docs/images/kea2_logo.png" alt="kea_logo" style="border-radius: 14px; width: 20%; height: 20%;"/>
|
|
38
|
+
</div>
|
|
39
|
+
<div align="center">
|
|
40
|
+
<a href="https://en.wikipedia.org/wiki/Kea">Kea2's logo: A large parrot skilled in finding "bugs"</a>
|
|
41
|
+
</div>
|
|
42
|
+
|
|
34
43
|
Kea2 is an easy-to-use tool for fuzzing mobile apps. Its key *novelty* is able to fuse automated UI testing with scripts (usually written by human), thus empowering automated UI testing with human intelligence for effectively finding *crashing bugs* as well as *non-crashing functional (logic) bugs*.
|
|
35
44
|
|
|
36
45
|
Kea2 is currently built on top of [Fastbot](https://github.com/bytedance/Fastbot_Android), *an industrial-strength automated UI testing tool*, and [uiautomator2](https://github.com/openatx/uiautomator2), *an easy-to-use and stable Android automation library*.
|
|
@@ -40,7 +49,7 @@ Kea2 currently targets [Android](https://en.wikipedia.org/wiki/Android_(operatin
|
|
|
40
49
|
|
|
41
50
|
<div align="center">
|
|
42
51
|
<div style="max-width:80%; max-height:80%">
|
|
43
|
-
<img src="docs/intro.png" style="border-radius: 14px; width: 80%; height: 80%;"/>
|
|
52
|
+
<img src="docs/images/intro.png" style="border-radius: 14px; width: 80%; height: 80%;"/>
|
|
44
53
|
</div>
|
|
45
54
|
</div>
|
|
46
55
|
|
|
@@ -60,11 +69,17 @@ Kea2 currently targets [Android](https://en.wikipedia.org/wiki/Android_(operatin
|
|
|
60
69
|
| **Finding crashes in deep states** | | :+1: | :+1: |
|
|
61
70
|
| **Finding non-crashing functional (logic) bugs** | | | :+1: |
|
|
62
71
|
|
|
63
|
-
## Kea2's
|
|
72
|
+
## Kea2's Users
|
|
73
|
+
|
|
74
|
+
Kea2 (and its idea) has been used/integrated by
|
|
64
75
|
|
|
65
|
-
[OPay Business](https://play.google.com/store/apps/details?id=team.opay.pay.merchant.service) --- a financial & payment app
|
|
76
|
+
- [OPay Business](https://play.google.com/store/apps/details?id=team.opay.pay.merchant.service) --- a financial & payment app. OPay uses Kea2 for regression testing on POS machines and mobile devices.
|
|
66
77
|
|
|
67
|
-
|
|
78
|
+
- [WeChat's iExplorer]() --- WeChat's in-house testing platform
|
|
79
|
+
|
|
80
|
+
- [ByteDance's Fastbot](https://github.com/bytedance/Fastbot_Android)
|
|
81
|
+
|
|
82
|
+
Please let us know and willing to hear your feedback/questions if you are also using Kea2.
|
|
68
83
|
|
|
69
84
|
## Design & Roadmap
|
|
70
85
|
Kea2 currently works with:
|
|
@@ -82,7 +97,7 @@ In the future, Kea2 will be extended to support
|
|
|
82
97
|
|
|
83
98
|
Running environment:
|
|
84
99
|
- support Windows, MacOS and Linux
|
|
85
|
-
- python 3.8+, Android 5.0
|
|
100
|
+
- python 3.8+, Android 5.0~16.0 (Android SDK installed)
|
|
86
101
|
- **VPN closed** (Features 2 and 3 required)
|
|
87
102
|
|
|
88
103
|
Install Kea2 by `pip`:
|
|
@@ -193,7 +208,7 @@ In Feature 3, a script is composed of three elements:
|
|
|
193
208
|
In a social media app, message sending is a common feature. On the message sending page, the `send` button should always appears when the input box is not empty (i.e., has some message).
|
|
194
209
|
|
|
195
210
|
<div align="center">
|
|
196
|
-
<img src="docs/socialAppBug.png" style="border-radius: 14px; width:30%; height:40%;"/>
|
|
211
|
+
<img src="docs/images/socialAppBug.png" style="border-radius: 14px; width:30%; height:40%;"/>
|
|
197
212
|
</div>
|
|
198
213
|
|
|
199
214
|
<div align="center">
|
|
@@ -230,7 +245,55 @@ You can find the [user manual](docs/manual_en.md), which includes:
|
|
|
230
245
|
- How to run Kea2 and Kea2's command line options
|
|
231
246
|
- How to find and understand Kea2's testing results
|
|
232
247
|
- How to [whitelist or blacklist](docs/blacklisting.md) specific activities, UI widgets and UI regions during fuzzing
|
|
233
|
-
- [
|
|
248
|
+
- [Q&A for Kea2 and PBT (对Kea2和PBT技术的常见问题和回答)](https://sy8pzmhmun.feishu.cn/wiki/SLGwwqgzIiEuC3kwmV8cSZY0nTg?from=from_copylink)
|
|
249
|
+
|
|
250
|
+
Some blogs on Kea/Kea2 (in Chinese):
|
|
251
|
+
- [别再苦哈哈写测试脚本了,生成它们吧!(一)](https://mp.weixin.qq.com/s/R2kLCkXpDjpa8wCX4Eidtg)
|
|
252
|
+
- [别再苦哈哈写测试脚本了,生成它们吧!(二)](https://mp.weixin.qq.com/s/s4WkdstNcKupu9OP8jeOXw)
|
|
253
|
+
- [别再苦哈哈写测试脚本了,生成它们吧!(三)](https://mp.weixin.qq.com/s/BjXyo-xJRmPB_sCc4pmh8g)
|
|
254
|
+
- [2025 Let’s GoSSIP 软件安全暑期学校预告第一弹——Kea2](https://mp.weixin.qq.com/s/8_0_GNNin8E5BqTbJU33wg)
|
|
255
|
+
- [功能性质驱动的测试技术:下一代GUI自动化测试技术](https://appw8oh6ysg4044.xet.citv.cn/p/course/video/v_6882fa14e4b0694ca0ec0a1b) --- 视频回放&PPT@MTSC 2025
|
|
256
|
+
|
|
257
|
+
工业界对Kea2的理解和评价(点击箭头查看详情):
|
|
258
|
+
|
|
259
|
+
<details>
|
|
260
|
+
<summary>Kea2的性质是什么含义?Kea2意义和价值是什么?</summary>
|
|
261
|
+
|
|
262
|
+
kea2 其实是一个工具,它是python+u2+fastbot的集合体。 它本身更像是一台装好了发动机和轮子的汽车底盘。
|
|
263
|
+
|
|
264
|
+
性质是苏老师他们团队提出的一个概念, 转换到测试领域的实际工作中,性质对应的是最小单位的功能(原子级功能),性质的依赖条件很少或没有,它可以自身运行。一个典型的性质就是登录,它仅仅具有输入用户名,输入密码,提交。再举个例子,给视频点个赞,也就是简单的两三步。就是一个性质。
|
|
265
|
+
|
|
266
|
+
性质与kea2结合的意义是在于解决过去使用appium过重的问题。用appium去测试一个性质通常要写很多行的代码,引导界面到达性质的位置。但使用kea2,就只需要编写性质,如何到其所在的位置是交给fastbot和它的学习算法来搞定的。
|
|
267
|
+
|
|
268
|
+
kea2另个重大的价值是,它解决了上述思想所需要的技术支撑,比appium更轻量的UI编写方式,fastbot编写性质的能力不足,以及无法编写逻辑和断言。整体上是保留了fastbot以往的优秀品质,完善了其不足和短板。
|
|
269
|
+
|
|
270
|
+
简而言之,需要做传统的编排型的功能测试,仍然使用appium,使用kea2也行,但你感觉不到它的价值。本身有需要做混沌测试,模糊测试,兼容性测试。那么强烈,强烈推荐kea2。kea2更偏探索性测试而非编排型。
|
|
271
|
+
</details>
|
|
272
|
+
|
|
273
|
+
<details>
|
|
274
|
+
<summary>kea2组成是什么?kea2的核心作用?kea2做了什么?</summary>
|
|
275
|
+
|
|
276
|
+
kea2 组成:
|
|
277
|
+
|
|
278
|
+
fastbot -- fuzz测试引擎,负责跑路。
|
|
279
|
+
u2 -- 负责进行业务空间的操作。与使用selenium,appium,没什么区别。
|
|
280
|
+
python -- u2的操作,逻辑的编写,定制化的实现。
|
|
281
|
+
|
|
282
|
+
kea2的核心作用:
|
|
283
|
+
|
|
284
|
+
提供了条件触发器。 在FB跑路的时候,会不停遍历条件触发器,一旦触发,挂起FB,开始执行触发器指定的 ui test 及 assert。执行完毕,继续切回FB跑路。
|
|
285
|
+
|
|
286
|
+
hea2做了什么:
|
|
287
|
+
|
|
288
|
+
替换了FB的条件触发功能。
|
|
289
|
+
替换了FB的黑名单,黑控件功能。
|
|
290
|
+
替换了FB剪枝功能。
|
|
291
|
+
增加了多元化的元素空间操作能力。
|
|
292
|
+
增加了fuzz测试中的 逻辑设定。
|
|
293
|
+
增加了断言能力。
|
|
294
|
+
增加了元素操作能力。
|
|
295
|
+
</details>
|
|
296
|
+
|
|
234
297
|
|
|
235
298
|
## Open-source projects used by Kea2
|
|
236
299
|
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
kea2/__init__.py,sha256=JFJjqgf5KB4bXUFQ3upkEug0cFMFIk9p3OHV9vzulHw,75
|
|
2
2
|
kea2/absDriver.py,sha256=NzmsLs1Ojz-yEXctGAqj7aKBwAQW19zd83l65RABCe8,1288
|
|
3
3
|
kea2/adbUtils.py,sha256=zi0T0_g44xZQZe3XYzBsuh7VTHpdZ4dd6yKi-p7BTYI,19939
|
|
4
|
-
kea2/bug_report_generator.py,sha256=
|
|
4
|
+
kea2/bug_report_generator.py,sha256=qHwHupANp5-IZXlpSnYy5rkf07BXu2QvvfWZzJWtc6k,42590
|
|
5
5
|
kea2/cli.py,sha256=MccJhY8VPZa1rMAbirm3dmbzDx1lf2w3zrpF1ZUq2m0,6481
|
|
6
|
-
kea2/fastbotManager.py,sha256=
|
|
7
|
-
kea2/keaUtils.py,sha256=
|
|
6
|
+
kea2/fastbotManager.py,sha256=pGuAH-X26nOy2Qj6Hg5aoMxJx4KfsRk6bj6nhcPENGc,8158
|
|
7
|
+
kea2/keaUtils.py,sha256=KRBYI6Vn36liKj8jFSH0W-ktGgHr-0VdC3xiX_mCF5E,25617
|
|
8
8
|
kea2/kea_launcher.py,sha256=M9TMCdgkteCWO5iBxJRDRvb7dikanoPf3jdicCEurU8,6268
|
|
9
9
|
kea2/logWatcher.py,sha256=Dp6OzvLSuWYw0AqdcPDqfotaRZQgpF8S49LInGsAWp8,2599
|
|
10
|
-
kea2/report_merger.py,sha256=
|
|
10
|
+
kea2/report_merger.py,sha256=0b-g59pdrsJDwVNek02ouu1utuu_Sd_1oEMQa4e23xI,24884
|
|
11
11
|
kea2/resultSyncer.py,sha256=9kb3H0Innwj7oPboDDTf97nbjam7EP6HYxywR9B8SvM,2437
|
|
12
|
-
kea2/u2Driver.py,sha256=
|
|
13
|
-
kea2/utils.py,sha256=
|
|
12
|
+
kea2/u2Driver.py,sha256=SfHkUAp6uHHSllPZmKs7C8JaEGGuX9DPWgshiqyWI5k,19775
|
|
13
|
+
kea2/utils.py,sha256=x0VTGweW-XShG9MuwZDMP13SBg8jQXYa7e0AXdwYX38,3270
|
|
14
14
|
kea2/assets/fastbot-thirdpart.jar,sha256=0SZ_OoZFWDGMnazgXKceHgKvXdUDoIa3Gb2bcifaikk,85664
|
|
15
15
|
kea2/assets/framework.jar,sha256=rTluOJJKj2DFwh7ascXso1udYdWv00BxBwSQ3Vmv-fw,1149240
|
|
16
16
|
kea2/assets/kea2-thirdpart.jar,sha256=HYdtG2gqDLuLb72dpK3lX-Y6QUNTrJ-bfQopU5aWpfo,359346
|
|
@@ -28,11 +28,11 @@ kea2/assets/fastbot_libs/arm64-v8a/libfastbot_native.so,sha256=tAFrG73pJi7XakRxS
|
|
|
28
28
|
kea2/assets/fastbot_libs/armeabi-v7a/libfastbot_native.so,sha256=UV8bhaiPoPKdd3q0vj3kSZqPR9anllai_tz_2QkMMbQ,1335372
|
|
29
29
|
kea2/assets/fastbot_libs/x86/libfastbot_native.so,sha256=k-aw1gEXRWMKZRNHIggKNuZy0wC1y2BnveJGEIO6rbo,2036856
|
|
30
30
|
kea2/assets/fastbot_libs/x86_64/libfastbot_native.so,sha256=tiofhlf4uMQcU5WAvrdLgTBME0lb83hVUoGtTwxmE8A,2121416
|
|
31
|
-
kea2/templates/bug_report_template.html,sha256=
|
|
32
|
-
kea2/templates/merged_bug_report_template.html,sha256=
|
|
33
|
-
kea2_python-0.3.
|
|
34
|
-
kea2_python-0.3.
|
|
35
|
-
kea2_python-0.3.
|
|
36
|
-
kea2_python-0.3.
|
|
37
|
-
kea2_python-0.3.
|
|
38
|
-
kea2_python-0.3.
|
|
31
|
+
kea2/templates/bug_report_template.html,sha256=XoLAqiPfk5asvSRhhI5nCity8Z77rxMBGT2_8rFrJP4,151729
|
|
32
|
+
kea2/templates/merged_bug_report_template.html,sha256=awhMSURsP6Gpw0YHTs3xWZMQO7dhi0yM3H2JYHQ5_zA,135668
|
|
33
|
+
kea2_python-0.3.2.dist-info/licenses/LICENSE,sha256=nM9PPjcsXVo5SzNsjRqWgA-gdJlwqZZcRDSC6Qf6bVE,2034
|
|
34
|
+
kea2_python-0.3.2.dist-info/METADATA,sha256=dD3gescsC5Q-R8OZYFfvbiYBDhvJefFXzopffB2EPVI,18498
|
|
35
|
+
kea2_python-0.3.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
36
|
+
kea2_python-0.3.2.dist-info/entry_points.txt,sha256=mFX06TyxXiUAJQ6JZn8QHzfn8n5R8_KJ5W-pTm_fRCA,39
|
|
37
|
+
kea2_python-0.3.2.dist-info/top_level.txt,sha256=TsgNH4PQoNOVhegpO7AcjutMVWp6Z4KDL1pBH9FnMmk,5
|
|
38
|
+
kea2_python-0.3.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|