Kea2-python 0.0.1a0__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/__init__.py +4 -0
- kea2/absDriver.py +34 -0
- kea2/adbUtils.py +258 -0
- kea2/assets/fastbot-thirdpart.jar +0 -0
- kea2/assets/fastbot_configs/ADBKeyBoard.apk +0 -0
- kea2/assets/fastbot_configs/abl.strings +2 -0
- kea2/assets/fastbot_configs/awl.strings +3 -0
- kea2/assets/fastbot_configs/max.config +7 -0
- kea2/assets/fastbot_configs/max.fuzzing.strings +699 -0
- kea2/assets/fastbot_configs/max.schema.strings +1 -0
- kea2/assets/fastbot_configs/max.strings +3 -0
- kea2/assets/fastbot_configs/max.tree.pruning +27 -0
- kea2/assets/fastbot_configs/widget.block.py +22 -0
- kea2/assets/fastbot_libs/arm64-v8a/libfastbot_native.so +0 -0
- kea2/assets/fastbot_libs/armeabi-v7a/libfastbot_native.so +0 -0
- kea2/assets/fastbot_libs/x86/libfastbot_native.so +0 -0
- kea2/assets/fastbot_libs/x86_64/libfastbot_native.so +0 -0
- kea2/assets/framework.jar +0 -0
- kea2/assets/monkeyq.jar +0 -0
- kea2/assets/quickstart.py +90 -0
- kea2/assets/u2.jar +0 -0
- kea2/cli.py +176 -0
- kea2/keaUtils.py +535 -0
- kea2/kea_launcher.py +135 -0
- kea2/logWatcher.py +71 -0
- kea2/u2Driver.py +316 -0
- kea2/utils.py +53 -0
- kea2_python-0.0.1a0.dist-info/METADATA +433 -0
- kea2_python-0.0.1a0.dist-info/RECORD +33 -0
- kea2_python-0.0.1a0.dist-info/WHEEL +5 -0
- kea2_python-0.0.1a0.dist-info/entry_points.txt +2 -0
- kea2_python-0.0.1a0.dist-info/licenses/LICENSE +16 -0
- kea2_python-0.0.1a0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
snssdk1128://webcast_feed?gd_label=88888
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"activity":"com.ss.android.xxx.NewActivity",
|
|
4
|
+
"xpath": "//*[@resource-id='com.xxx.go:id/aaa']",
|
|
5
|
+
"resourceid": "",
|
|
6
|
+
"contentdesc":"",
|
|
7
|
+
"text":"",
|
|
8
|
+
"classname":""
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"activity":"com.ss.android.xxx.MainActivity",
|
|
12
|
+
"xpath": "//*[@resource-id='com.xxx.go:id/bbb' and @text='other']",
|
|
13
|
+
"resourceid": "",
|
|
14
|
+
"contentdesc":"",
|
|
15
|
+
"text":"",
|
|
16
|
+
"classname":""
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"activity":"com.ss.android.xxx.SplashActivity",
|
|
20
|
+
"xpath": "//*[@resource-id='com.com.xxx.go:id/ccc' and @text='other']",
|
|
21
|
+
"resourceid": "",
|
|
22
|
+
"contentdesc":"",
|
|
23
|
+
"text":"",
|
|
24
|
+
"classname":"",
|
|
25
|
+
"clickable":"false"
|
|
26
|
+
}
|
|
27
|
+
]
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from kea2.utils import precondition
|
|
2
|
+
from uiautomator2 import Device
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@precondition(lambda d:
|
|
6
|
+
d(text="Setting")
|
|
7
|
+
)
|
|
8
|
+
def sample_block_list(d: "Device"):
|
|
9
|
+
return d(text="Omni Notes Alpha").exists
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
if __name__ == "__main__":
|
|
13
|
+
from kea2.utils import BLOCK_WIDGET
|
|
14
|
+
func = getattr(sample_block_list, BLOCK_WIDGET)
|
|
15
|
+
import uiautomator2 as u2
|
|
16
|
+
d = u2.connect()
|
|
17
|
+
blocked_widgets = func(d)
|
|
18
|
+
if isinstance(blocked_widgets, u2.UiObject):
|
|
19
|
+
blocked_widgets = [blocked_widgets]
|
|
20
|
+
if not all([isinstance(w, u2.UiObject) for w in blocked_widgets]):
|
|
21
|
+
raise TypeError(f"Invalid widgets block list in {sample_block_list}")
|
|
22
|
+
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
kea2/assets/monkeyq.jar
ADDED
|
Binary file
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
import uiautomator2 as u2
|
|
3
|
+
|
|
4
|
+
from time import sleep
|
|
5
|
+
from kea2 import precondition, prob, KeaTestRunner, Options
|
|
6
|
+
from kea2.u2Driver import U2Driver
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Omni_Notes_Sample(unittest.TestCase):
|
|
10
|
+
|
|
11
|
+
def setUp(self):
|
|
12
|
+
self.d = u2.connect()
|
|
13
|
+
|
|
14
|
+
@prob(0.7) # The probability of executing the function when precondition is satisfied.
|
|
15
|
+
@precondition(
|
|
16
|
+
lambda self: self.d(text="Omni Notes Alpha").exists
|
|
17
|
+
and self.d(text="Settings").exists
|
|
18
|
+
)
|
|
19
|
+
def test_goToPrivacy(self):
|
|
20
|
+
"""
|
|
21
|
+
The ability to jump out of the UI tarpits
|
|
22
|
+
|
|
23
|
+
precond:
|
|
24
|
+
The drawer was opened
|
|
25
|
+
action:
|
|
26
|
+
go to settings -> privacy
|
|
27
|
+
"""
|
|
28
|
+
print("trying to click Settings")
|
|
29
|
+
self.d(text="Settings").click()
|
|
30
|
+
sleep(0.5)
|
|
31
|
+
print("trying to click Privacy")
|
|
32
|
+
self.d(text="Privacy").click()
|
|
33
|
+
|
|
34
|
+
@precondition(
|
|
35
|
+
lambda self: self.d(resourceId="it.feio.android.omninotes.alpha:id/search_src_text").exists
|
|
36
|
+
)
|
|
37
|
+
def test_rotation(self):
|
|
38
|
+
"""
|
|
39
|
+
The ability to make assertion to find functional bug
|
|
40
|
+
|
|
41
|
+
precond:
|
|
42
|
+
The search input box is opened
|
|
43
|
+
action:
|
|
44
|
+
rotate the device (set it to landscape, then back to natural)
|
|
45
|
+
assertion:
|
|
46
|
+
The search input box is still being opened
|
|
47
|
+
"""
|
|
48
|
+
self.d.set_orientation("l")
|
|
49
|
+
sleep(2)
|
|
50
|
+
self.d.set_orientation("n")
|
|
51
|
+
sleep(2)
|
|
52
|
+
assert self.d(resourceId="it.feio.android.omninotes.alpha:id/search_src_text").exists()
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
URL = "https://raw.githubusercontent.com/ecnusse/Kea2/refs/heads/dev_test_hidden_algorithm/omninotes.apk"
|
|
56
|
+
PACKAGE_NAME = "it.feio.android.omninotes.alpha"
|
|
57
|
+
FILE_NAME = "omninotes.apk"
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def check_installation():
|
|
61
|
+
import os
|
|
62
|
+
from pathlib import Path
|
|
63
|
+
if not os.path.exists(Path(".") / FILE_NAME):
|
|
64
|
+
print(f"[INFO] omninote.apk not exists. Downloading from {URL}", flush=True)
|
|
65
|
+
import urllib.request
|
|
66
|
+
urllib.request.urlretrieve(URL, FILE_NAME)
|
|
67
|
+
|
|
68
|
+
d = u2.connect()
|
|
69
|
+
# automatically install omni-notes
|
|
70
|
+
if PACKAGE_NAME not in d.app_list():
|
|
71
|
+
print("[INFO] Installing omninotes.", flush=True)
|
|
72
|
+
d.app_install(FILE_NAME)
|
|
73
|
+
d.stop_uiautomator()
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
if __name__ == "__main__":
|
|
77
|
+
check_installation()
|
|
78
|
+
KeaTestRunner.setOptions(
|
|
79
|
+
Options(
|
|
80
|
+
driverName="d",
|
|
81
|
+
Driver=U2Driver,
|
|
82
|
+
packageNames=[PACKAGE_NAME],
|
|
83
|
+
# serial="emulator-5554", # specify the serial
|
|
84
|
+
maxStep=5000,
|
|
85
|
+
# running_mins=10, # specify the maximal running time in minutes, default value is 10m
|
|
86
|
+
# throttle=200, # specify the throttle in milliseconds, default value is 200ms
|
|
87
|
+
# agent='native' # 'native' for running the vanilla Fastbot, 'u2' for running Kea2
|
|
88
|
+
)
|
|
89
|
+
)
|
|
90
|
+
unittest.main(testRunner=KeaTestRunner)
|
kea2/assets/u2.jar
ADDED
|
Binary file
|
kea2/cli.py
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
# cli.py
|
|
3
|
+
|
|
4
|
+
from __future__ import absolute_import, print_function
|
|
5
|
+
from kea2.utils import getProjectRoot, getLogger
|
|
6
|
+
from .kea_launcher import run
|
|
7
|
+
import argparse
|
|
8
|
+
|
|
9
|
+
import os
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
logger = getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
def cmd_init(args):
|
|
16
|
+
cwd = Path(os.getcwd())
|
|
17
|
+
configs_dir = cwd / "configs"
|
|
18
|
+
if os.path.isdir(configs_dir):
|
|
19
|
+
logger.warning("Kea2 project already initialized")
|
|
20
|
+
return
|
|
21
|
+
|
|
22
|
+
import shutil
|
|
23
|
+
def copy_configs():
|
|
24
|
+
src = Path(__file__).parent / "assets" / "fastbot_configs"
|
|
25
|
+
dst = configs_dir
|
|
26
|
+
shutil.copytree(src, dst)
|
|
27
|
+
|
|
28
|
+
def copy_samples():
|
|
29
|
+
src = Path(__file__).parent / "assets" / "quickstart.py"
|
|
30
|
+
dst = cwd / "quickstart.py"
|
|
31
|
+
shutil.copyfile(src, dst)
|
|
32
|
+
|
|
33
|
+
copy_configs()
|
|
34
|
+
copy_samples()
|
|
35
|
+
logger.info("Kea2 project initialized.")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def cmd_load_configs(args):
|
|
39
|
+
pass
|
|
40
|
+
|
|
41
|
+
def cmd_run(args):
|
|
42
|
+
base_dir = getProjectRoot()
|
|
43
|
+
if base_dir is None:
|
|
44
|
+
logger.error("kea2 project not initialized. Use `kea2 init`.")
|
|
45
|
+
return
|
|
46
|
+
argv = [__file__]
|
|
47
|
+
argv.extend(args.args)
|
|
48
|
+
run(argv)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def cmd_install(args):
|
|
52
|
+
pass
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def cmd_uninstall(args):
|
|
56
|
+
pass
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def cmd_start(args):
|
|
60
|
+
pass
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def cmd_stop(args):
|
|
64
|
+
pass
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def cmd_current(args):
|
|
68
|
+
pass
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def cmd_doctor(args):
|
|
72
|
+
pass
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
# def cmd_version(args):
|
|
76
|
+
# print(__version__)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
_commands = [
|
|
80
|
+
# dict(action=cmd_version, command="version", help="show version"),
|
|
81
|
+
dict(
|
|
82
|
+
action=cmd_init,
|
|
83
|
+
command="init",
|
|
84
|
+
help="init the Kea2 project in current directory",
|
|
85
|
+
),
|
|
86
|
+
dict(
|
|
87
|
+
action=cmd_run,
|
|
88
|
+
command="run",
|
|
89
|
+
help="run kea2",
|
|
90
|
+
flags=[
|
|
91
|
+
dict(args=["args"], nargs=argparse.REMAINDER, help="args for kea2 run"),
|
|
92
|
+
],
|
|
93
|
+
),
|
|
94
|
+
# dict(
|
|
95
|
+
# action=cmd_install,
|
|
96
|
+
# command="",
|
|
97
|
+
# help="install packages",
|
|
98
|
+
# flags=[
|
|
99
|
+
# dict(args=["url"], help="package url"),
|
|
100
|
+
# ],
|
|
101
|
+
# ),
|
|
102
|
+
# dict(
|
|
103
|
+
# action=cmd_uninstall,
|
|
104
|
+
# command="uninstall",
|
|
105
|
+
# help="uninstall packages",
|
|
106
|
+
# flags=[
|
|
107
|
+
# dict(args=["--all"], action="store_true", help="uninstall all packages"),
|
|
108
|
+
# dict(args=["package_name"], nargs="*", help="package name"),
|
|
109
|
+
# ],
|
|
110
|
+
# ),
|
|
111
|
+
# dict(
|
|
112
|
+
# action=cmd_start,
|
|
113
|
+
# command="start",
|
|
114
|
+
# help="start application",
|
|
115
|
+
# flags=[dict(args=["package_name"], type=str, nargs=None, help="package name")],
|
|
116
|
+
# ),
|
|
117
|
+
# dict(
|
|
118
|
+
# action=cmd_stop,
|
|
119
|
+
# command="stop",
|
|
120
|
+
# help="stop application",
|
|
121
|
+
# flags=[
|
|
122
|
+
# dict(args=["--all"], action="store_true", help="stop all"),
|
|
123
|
+
# dict(args=["package_name"], nargs="*", help="package name"),
|
|
124
|
+
# ],
|
|
125
|
+
# ),
|
|
126
|
+
# dict(action=cmd_current, command="current", help="show current application"),
|
|
127
|
+
# dict(action=cmd_doctor, command="doctor", help="detect connect problem"),
|
|
128
|
+
]
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def main():
|
|
132
|
+
parser = argparse.ArgumentParser(
|
|
133
|
+
formatter_class=argparse.ArgumentDefaultsHelpFormatter
|
|
134
|
+
)
|
|
135
|
+
parser.add_argument("-d", "--debug", action="store_true",
|
|
136
|
+
help="show log")
|
|
137
|
+
parser.add_argument('-s', '--serial', type=str,
|
|
138
|
+
help='device serial number')
|
|
139
|
+
|
|
140
|
+
subparser = parser.add_subparsers(dest='subparser')
|
|
141
|
+
|
|
142
|
+
actions = {}
|
|
143
|
+
for c in _commands:
|
|
144
|
+
cmd_name = c['command']
|
|
145
|
+
actions[cmd_name] = c['action']
|
|
146
|
+
sp = subparser.add_parser(
|
|
147
|
+
cmd_name,
|
|
148
|
+
help=c.get('help'),
|
|
149
|
+
formatter_class=argparse.ArgumentDefaultsHelpFormatter
|
|
150
|
+
)
|
|
151
|
+
for f in c.get('flags', []):
|
|
152
|
+
args = f.get('args')
|
|
153
|
+
if not args:
|
|
154
|
+
args = ['-'*min(2, len(n)) + n for n in f['name']]
|
|
155
|
+
kwargs = f.copy()
|
|
156
|
+
kwargs.pop('name', None)
|
|
157
|
+
kwargs.pop('args', None)
|
|
158
|
+
sp.add_argument(*args, **kwargs)
|
|
159
|
+
|
|
160
|
+
args = parser.parse_args()
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
if args.debug:
|
|
164
|
+
import logging
|
|
165
|
+
logging.basicConfig(level=logging.DEBUG)
|
|
166
|
+
logger.debug("args: %s", args)
|
|
167
|
+
|
|
168
|
+
if args.subparser:
|
|
169
|
+
actions[args.subparser](args)
|
|
170
|
+
return
|
|
171
|
+
|
|
172
|
+
parser.print_help()
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
if __name__ == "__main__":
|
|
176
|
+
main()
|