Kea2-python 1.2.0__py3-none-any.whl → 1.2.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.
kea2/assets/monkeyq.jar CHANGED
Binary file
kea2/assets/quicktest.py CHANGED
@@ -1,8 +1,7 @@
1
1
  import unittest
2
2
  import uiautomator2 as u2
3
3
 
4
- from time import sleep
5
- from kea2 import precondition, prob, KeaTestRunner, Options, keaTestLoader, invariant
4
+ from kea2 import precondition, prob, invariant
6
5
 
7
6
 
8
7
  import unittest
@@ -132,17 +131,24 @@ def check_installation(serial=None):
132
131
 
133
132
  if __name__ == "__main__":
134
133
  check_installation(serial=None)
135
- KeaTestRunner.setOptions(
136
- Options(
137
- driverName="d",
138
- packageNames=[PACKAGE_NAME],
139
- # serial="emulator-5554", # specify the serial
140
- maxStep=50,
141
- profile_period=10,
142
- take_screenshots=True, # whether to take screenshots, default is False
143
- # running_mins=10, # specify the maximal running time in minutes, default value is 10m
144
- # throttle=200, # specify the throttle in milliseconds, default value is 200ms
145
- agent="u2" # 'native' for running the vanilla Fastbot, 'u2' for running Kea2
146
- )
147
- )
148
- unittest.main(testRunner=KeaTestRunner, testLoader=keaTestLoader)
134
+ import signal
135
+ import subprocess
136
+ import sys
137
+ from pathlib import Path
138
+ start_dir = str(Path(__file__).parent)
139
+ file_name = str(Path(__file__).name)
140
+ CMD = [
141
+ "kea2", "run",
142
+ "-p", PACKAGE_NAME,
143
+ "--max-step", "50",
144
+ "--profile-period", "10",
145
+ "--take-screenshots",
146
+ "propertytest", "discover", "-s", start_dir, "-p", file_name
147
+ ]
148
+ try:
149
+ p = subprocess.Popen(CMD, stdout=sys.stdout, stderr=sys.stderr)
150
+ p.wait()
151
+ except KeyboardInterrupt:
152
+ p.wait()
153
+ finally:
154
+ sys.exit(p.returncode)
kea2/cli.py CHANGED
@@ -108,89 +108,6 @@ def cmd_merge(args):
108
108
  logger.error(f"Error during merge operation: {e}")
109
109
 
110
110
 
111
- def cmd_mergefbm(args):
112
- """Merge all FBM files in the specified folder and its subfolders using sum mode"""
113
- from .fbm_parser import FBMMerger
114
- import glob
115
- import shutil
116
-
117
- try:
118
- # Validate input path
119
- input_path = Path(args.path).resolve()
120
- if not input_path.exists():
121
- logger.error(f"Input directory does not exist: {input_path}")
122
- return
123
- if not input_path.is_dir():
124
- logger.error(f"Input path is not a directory: {input_path}")
125
- return
126
-
127
- # Find all FBM files in the directory and its subdirectories
128
- fbm_files = glob.glob(str(input_path / "**" / "*.fbm"), recursive=True)
129
-
130
- if not fbm_files:
131
- logger.error(f"No FBM files found in {input_path} or its subdirectories")
132
- return
133
-
134
- logger.debug(f"Found {len(fbm_files)} FBM files to merge:")
135
- for fbm_file in fbm_files:
136
- logger.debug(f" - {fbm_file}")
137
-
138
- # Set default output file if not provided
139
- if not args.output:
140
- output_file = input_path / "merged.fbm"
141
- else:
142
- output_file = Path(args.output).resolve()
143
-
144
- # Initialize merger
145
- merger = FBMMerger()
146
-
147
- # Handle different cases
148
- if len(fbm_files) == 1:
149
- # Only one file, just copy it to output
150
- shutil.copyfile(fbm_files[0], output_file)
151
- logger.info(f"Only one FBM file found, copied to {output_file}")
152
- else:
153
- # Merge files iteratively: start with the first file and merge with each subsequent file
154
- # Create a temporary file for the intermediate merged result
155
- temp_output = input_path / f".tmp_merged.fbm"
156
-
157
- # Start with the first file as the initial merged result
158
- shutil.copyfile(fbm_files[0], temp_output)
159
-
160
- # Iterate through the remaining files and merge them one by one
161
- for i in range(1, len(fbm_files)):
162
- current_file = fbm_files[i]
163
- next_temp = input_path / f".tmp_merged_{i}.fbm"
164
-
165
- logger.debug(f"Merging {temp_output} and {current_file} into {next_temp}")
166
- success = merger.merge(str(temp_output), str(current_file), str(next_temp), merge_mode='sum')
167
-
168
- if not success:
169
- logger.error(f"Failed to merge {temp_output} and {current_file}")
170
- # Clean up temporary files
171
- for f in [temp_output, next_temp]:
172
- if f.exists() and f.name.startswith(".tmp_"):
173
- f.unlink()
174
- return
175
-
176
- # Remove the previous temporary file and update to the new one
177
- temp_output.unlink()
178
- temp_output = next_temp
179
-
180
- # Move the final merged file to the output location
181
- if temp_output != output_file:
182
- temp_output.replace(output_file)
183
-
184
- print(f"✅ All FBM files merged successfully!", flush=True)
185
- print(f"📊 Merged FBM file: {output_file}", flush=True)
186
- print(f"📈 Merged {len(fbm_files)} FBM files", flush=True)
187
-
188
- except Exception as e:
189
- logger.error(f"Error during FBM merge operation: {e}")
190
- import traceback
191
- logger.debug(traceback.format_exc())
192
-
193
-
194
111
  def cmd_run(args):
195
112
  base_dir = getProjectRoot()
196
113
  if base_dir is None:
@@ -251,28 +168,7 @@ _commands = [
251
168
  help="Output directory for merged report (optional)"
252
169
  )
253
170
  ]
254
- ),
255
- dict(
256
- action=cmd_mergefbm,
257
- command="mergefbm",
258
- help="merge all FBM files in the specified folder and its subfolders using sum mode",
259
- flags=[
260
- dict(
261
- name=["path"],
262
- args=["-p", "--path"],
263
- type=str,
264
- required=True,
265
- help="Path to the folder containing FBM files to merge"
266
- ),
267
- dict(
268
- name=["output"],
269
- args=["-o", "--output"],
270
- type=str,
271
- required=False,
272
- help="Output file path for merged FBM file (optional, default: merged.fbm in the input folder)"
273
- )
274
- ]
275
- )
171
+ )
276
172
  ]
277
173
 
278
174
 
kea2/fastbotManager.py CHANGED
@@ -189,7 +189,7 @@ class FastbotManager:
189
189
  "exec", "app_process",
190
190
  "/system/bin", "com.android.commands.monkey.Monkey",
191
191
  "--agent-u2",
192
- "reuseq",
192
+ self.options.fastbot_agent,
193
193
  "--running-minutes", f"{self.options.running_mins}",
194
194
  "--throttle", f"{self.options.throttle}",
195
195
  "--output-directory", f"{self.options.device_output_root}/output_{self.options.log_stamp}",
kea2/keaUtils.py CHANGED
@@ -141,6 +141,8 @@ class Options:
141
141
  act_whitelist_file: str = None
142
142
  # Activity BlackList File
143
143
  act_blacklist_file: str = None
144
+ # Fastbot Agent
145
+ fastbot_agent: Literal["double-sarsa", "sarsa"] = "double-sarsa"
144
146
  # propertytest sub-commands args (eg. discover -s xxx -p xxx)
145
147
  propertytest_args: List[str] = None
146
148
  # period (N steps) to restart the app under test
kea2/kea_launcher.py CHANGED
@@ -162,6 +162,16 @@ def _set_runner_parser(subparsers: "argparse._SubParsersAction[argparse.Argument
162
162
  help="(Experimental) FBM merge at startup. When enabled, pull FBM(s) from the device at startup, merge them with local PC FBM data.",
163
163
  )
164
164
 
165
+ parser.add_argument(
166
+ "--fastbot-agent",
167
+ dest="fastbot_agent",
168
+ type=str,
169
+ choices=["double-sarsa", "sarsa"],
170
+ required=False,
171
+ default="double-sarsa",
172
+ help="Fastbot agent strategy.",
173
+ )
174
+
165
175
 
166
176
  parser.add_argument(
167
177
  "--act-whitelist-file",
@@ -301,6 +311,7 @@ def run(args=None) -> ReturnCode:
301
311
  unittest_args=args.unittest_args,
302
312
  extra_args=args.extra,
303
313
  merge_fbm=args.merge_fbm,
314
+ fastbot_agent=args.fastbot_agent,
304
315
  )
305
316
 
306
317
 
@@ -50,7 +50,7 @@ class ReportData(TypedDict):
50
50
  bugs_found: int
51
51
  invariant_violations_count: int
52
52
  executed_events: int
53
- total_testing_time: float
53
+ total_testing_time: str
54
54
  coverage: float
55
55
  widget_coverage_count: int
56
56
  total_activities_count: int
@@ -279,7 +279,7 @@ class BugReportGenerator(CrashAnrMixin, PathParserMixin, ScreenshotsMixin):
279
279
  "bugs_found": 0,
280
280
  "invariant_violations_count": 0,
281
281
  "executed_events": 0,
282
- "total_testing_time": 0,
282
+ "total_testing_time": "00:00:00",
283
283
  "coverage": 0,
284
284
  "widget_coverage_count": 0,
285
285
  "total_activities": [],
@@ -318,7 +318,8 @@ class BugReportGenerator(CrashAnrMixin, PathParserMixin, ScreenshotsMixin):
318
318
 
319
319
  current_property = None
320
320
  current_test = {}
321
- first_step_time = last_step_time = ""
321
+ first_step_time: Optional[str] = None
322
+ last_step_time: Optional[str] = None
322
323
  step_index = 0
323
324
  monkey_events_count = 0 # Track monkey events separately
324
325
  last_monkey_step_count = 0
@@ -411,20 +412,23 @@ class BugReportGenerator(CrashAnrMixin, PathParserMixin, ScreenshotsMixin):
411
412
  current_property, current_test, property_violations
412
413
  )
413
414
 
414
- # Store first and last step for time calculation
415
- if int(monkey_steps_count) == 1 and not first_step_time:
416
- first_step_time = step_data["Time"]
417
- last_step_time = step_data["Time"]
415
+ # Store first and last valid timestamps for testing duration calculation.
416
+ step_time = step_data.get("Time")
417
+ if step_time:
418
+ if first_step_time is None:
419
+ first_step_time = step_time
420
+ last_step_time = step_time
418
421
 
419
422
 
420
423
  # Calculate test time
421
424
  if first_step_time and last_step_time:
422
- def _get_datetime(raw_datetime) -> datetime:
423
- return datetime.strptime(raw_datetime, r"%Y-%m-%d %H:%M:%S.%f")
425
+ def _get_datetime(raw_datetime: str) -> datetime:
426
+ # Use fromisoformat for compatibility with/without microseconds.
427
+ return datetime.fromisoformat(raw_datetime)
424
428
 
425
429
  test_time = _get_datetime(last_step_time) - _get_datetime(first_step_time)
426
-
427
- total_seconds = int(test_time.total_seconds())
430
+
431
+ total_seconds = max(0, int(test_time.total_seconds()))
428
432
  hours, remainder = divmod(total_seconds, 3600)
429
433
  minutes, seconds = divmod(remainder, 60)
430
434
  data["total_testing_time"] = f"{hours:02d}:{minutes:02d}:{seconds:02d}"
@@ -20,6 +20,7 @@ class WidgetCoverage:
20
20
  AUTO_RESOURCE_ID = "<AUTO>"
21
21
  _profile_period: int
22
22
  _options: "Options"
23
+ _all_activities: Set[str] = None
23
24
 
24
25
  def __init__(self, output_dir, options:"Options"=None, profile_period:int=None):
25
26
  self.output_dir = Path(output_dir)
@@ -43,6 +44,16 @@ class WidgetCoverage:
43
44
  if options_data:
44
45
  self._options = Options.from_dict(options_data)
45
46
  return self._options
47
+
48
+ @property
49
+ def all_activities(self) -> Set[str]:
50
+ if self._all_activities is None:
51
+ with open(self.output_dir / "coverage.log") as f:
52
+ line = f.readline()
53
+ data = json.loads(line)
54
+ self._all_activities = set(data["totalActivities"])
55
+ return self._all_activities
56
+
46
57
 
47
58
  def generate_coverage_report(self):
48
59
  logger.info(
@@ -103,24 +114,28 @@ class WidgetCoverage:
103
114
  __record_coverage(final_steps_count)
104
115
 
105
116
  return triggered_widgets, coverage_records
106
-
107
- @catchException("Error getting widget representation")
108
- def __get_widget_repr(self, data):
109
- activity: str = data.get("Activity", "")
110
- if not activity:
111
- return ""
112
-
117
+
118
+ def is_activity_in_target_packages(self, activity: str) -> bool:
119
+ if self.all_activities:
120
+ return activity in self.all_activities
121
+ # Fallback
113
122
  # Check if activity matches any of the specified package names
114
123
  # filter out irrelevant widgets (not in the target packages)
115
124
  for pkg in self.options.packageNames:
116
125
  if pkg in activity:
117
- break
118
- # Handling the case where the activity string may not contain the full package name but can be inferred from the activity name itself
119
- # Example: com.example.app.MainActivity & com.example.app.alpha
126
+ return True
120
127
  pkg_name_from_activity = ".".join(_ for _ in activity.split(".") if "activity" not in _.lower())
121
128
  if pkg_name_from_activity in pkg:
122
- break
123
- else:
129
+ return True
130
+ return False
131
+
132
+ @catchException("Error getting widget representation")
133
+ def __get_widget_repr(self, data):
134
+ activity: str = data.get("Activity", "")
135
+ if not activity:
136
+ return ""
137
+
138
+ if not self.is_activity_in_target_packages(activity):
124
139
  return ""
125
140
 
126
141
  info_str = data.get("Info", "")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Kea2-python
3
- Version: 1.2.0
3
+ Version: 1.2.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
@@ -14,7 +14,7 @@ Requires-Dist: flatbuffers>=25.9.23
14
14
  Requires-Dist: packaging>=25.0
15
15
  Dynamic: license-file
16
16
 
17
-
17
+ <div align="center">
18
18
 
19
19
  [![PyPI](https://img.shields.io/pypi/v/kea2-python.svg)](https://pypi.python.org/pypi/kea2-python)
20
20
  [![PyPI Downloads](https://static.pepy.tech/badge/kea2-python)](https://pepy.tech/projects/kea2-python)
@@ -22,15 +22,16 @@ Dynamic: license-file
22
22
  [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/ecnusse/Kea2)
23
23
 
24
24
  [<img src="https://img.shields.io/badge/GitHub-181717?style=for-the-badge&logo=github&logoColor=white" />](https://github.com/ecnusse/Kea2)
25
- [<img src="https://img.shields.io/badge/Gitee-Mirror-333333?style=for-the-badge&logo=gitee&logoColor=white" />](https://gitee.com/XixianLiang/Kea2)
25
+ [<img src="https://img.shields.io/badge/Gitee-333333?style=for-the-badge&logo=gitee&logoColor=white" />](https://gitee.com/XixianLiang/Kea2)
26
26
 
27
- ### English | [简体中文](/README_cn.md)
27
+ **English | [简体中文](/README_cn.md)**
28
+
29
+ </br>
30
+
31
+ <img src="docs/images/kea2_logo.png" alt="kea_logo" style="border-radius: 14px; width: 20%; height: 20%;"/>
32
+
33
+ <a href="https://en.wikipedia.org/wiki/Kea">Kea2's logo: A large parrot skilled in finding "bugs"</a>
28
34
 
29
- <div align="center">
30
- <img src="docs/images/kea2_logo.png" alt="kea_logo" style="border-radius: 14px; width: 20%; height: 20%;"/>
31
- </div>
32
- <div align="center">
33
- <a href="https://en.wikipedia.org/wiki/Kea">Kea2's logo: A large parrot skilled in finding "bugs"</a>
34
35
  </div>
35
36
  </br>
36
37
 
@@ -1,13 +1,13 @@
1
1
  kea2/__init__.py,sha256=31JQuidfvcTzczGSWgFI6E3LH1Qfyzl7JiHY6IDO9_M,328
2
2
  kea2/adbUtils.py,sha256=6IQKwlE4tsI5tbDpbAnVM7RQK20pw_QxwZDAiuNnukg,8984
3
- kea2/cli.py,sha256=T7wXjCp4AnVS58F0PkE_XRz_rWY0gY33D1z9WNfxiWw,10660
4
- kea2/fastbotManager.py,sha256=oICrZBemIMr0fKt2envzIePgiJ8pRif7ZmmTuK5JA6A,9022
3
+ kea2/cli.py,sha256=Dw00I_kR3geVxBv7KCjgBcRlGuSYrHKqzGxkU4EZ_Fo,6506
4
+ kea2/fastbotManager.py,sha256=WR7E9WgBHkbDk7ngun2N5FkOj2FacPFwU7i5Sgjbhmw,9040
5
5
  kea2/fbm_parser.py,sha256=dpE78-kOuSSyH02MeecWFVQenZH8uvHDNN9HKSemg1Q,35996
6
6
  kea2/fbm_plugin.py,sha256=lTKVWVR01XNe8uCoPM65QifXzXAdUGZRyavYVnOG-xI,3239
7
7
  kea2/fs_lock.py,sha256=CZQ26Ap5xuqe3-SDiZqtafelO9QTOHX7S6JAn-wwR88,5036
8
8
  kea2/kea2_api.py,sha256=sf51PA-GNRnWa0Uj-n2ZI0t7Rxl4EpvQtPpY_nsXg-M,6504
9
- kea2/keaUtils.py,sha256=6CffT7QvnHSE0kJwlBATQQccPwBmxhpFu_-7SoYY1Xs,38844
10
- kea2/kea_launcher.py,sha256=7SZeVkdZdp4rhKrThG1-JfIf9V73sDF0Qc4bxolaUAw,10996
9
+ kea2/keaUtils.py,sha256=ppjgIsp-Bd-ZmilPbn4PMZfKvtEwhA4w6hwRhuDgVP0,38933
10
+ kea2/kea_launcher.py,sha256=7IxZ1B3cq6zy1jGkyOCIasc_OiDrtJWbUCyUb6I6XAA,11284
11
11
  kea2/logWatcher.py,sha256=xQAvaFJR4vNSuAKRxhqOr_L-ss2lemp8id4z5yKMnrs,5140
12
12
  kea2/mixin.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  kea2/result.py,sha256=ja8Y3u2EW-q4BS8B1JxdfDAibqRVtOJurSN-5HNvXoc,9828
@@ -21,8 +21,8 @@ kea2/assets/config_version.json,sha256=dYZRNo17hQq2SV45xxRCwDmykhsWWYI__w7vZXMHv
21
21
  kea2/assets/fastbot-thirdpart.jar,sha256=0SZ_OoZFWDGMnazgXKceHgKvXdUDoIa3Gb2bcifaikk,85664
22
22
  kea2/assets/framework.jar,sha256=rTluOJJKj2DFwh7ascXso1udYdWv00BxBwSQ3Vmv-fw,1149240
23
23
  kea2/assets/kea2-thirdpart.jar,sha256=HYdtG2gqDLuLb72dpK3lX-Y6QUNTrJ-bfQopU5aWpfo,359346
24
- kea2/assets/monkeyq.jar,sha256=Khr_GDur-jA2YGkDZCcDXMIJeVctlrLDDjV2WXiLonc,118773
25
- kea2/assets/quicktest.py,sha256=pw5fv4N0etKSzsfQoo8K-fY2O5yHsGenk3N88Mts3jA,5942
24
+ kea2/assets/monkeyq.jar,sha256=7eDqSbpC7XXf8Sm2hyIaywNXmISWbhRvTjJ9Bg5U2sE,138474
25
+ kea2/assets/quicktest.py,sha256=11VgSAHYHgTAhBGqwyQkhTecmIAIrOSQgu1y4DkEuCU,5782
26
26
  kea2/assets/fastbot_configs/abl.strings,sha256=Rn8_YEbVGOJqndIY_-kWnR5NaoFI-cuB-ij10Ddhl90,75
27
27
  kea2/assets/fastbot_configs/awl.strings,sha256=-j4980GoWQxGOM9ijAwXPQmziCwFBZJFmuiv2tOEaYI,101
28
28
  kea2/assets/fastbot_configs/max.config,sha256=rBgR4mdgBzqVPQ2lZaXqx2WN6tDzhe-FNizm4Y7tyA8,226
@@ -32,25 +32,25 @@ kea2/assets/fastbot_configs/max.strings,sha256=k82GAAZZG7KbDI7bk7DUklp41WJJO7j-j
32
32
  kea2/assets/fastbot_configs/max.tree.pruning,sha256=dm0oesN75FFbVSkV7STDUmrNMpQUBEuO7Uymt6nEkBc,629
33
33
  kea2/assets/fastbot_configs/teardown.py,sha256=dW6xHzozh2vXTB1qfCxAlT0xcv5kFwzX7kW1FmLfNA0,363
34
34
  kea2/assets/fastbot_configs/widget.block.py,sha256=lxWLca9Az0Ba3EBe8jcYmuEa1WSIhIDDgEG_r7b32R8,1160
35
- kea2/assets/fastbot_libs/arm64-v8a/libfastbot_native.so,sha256=WMRwqCOy5MrflaqSKUSljq2Vi-zWdgqgMiJpwaf3AyI,2058952
36
- kea2/assets/fastbot_libs/armeabi-v7a/libfastbot_native.so,sha256=K6PXqabGfx-hPFOgoaYPJALXYGL3b0o_EYhEEEiO6bE,1407540
37
- kea2/assets/fastbot_libs/x86/libfastbot_native.so,sha256=Oc0dCJSAQT7IhTJmIARt_otSMl0PcKuodScjXrsmWWY,2156540
38
- kea2/assets/fastbot_libs/x86_64/libfastbot_native.so,sha256=SOQcU3vRnwaIRYbtXEXKHy7U6CY3HFfbvFZxj1uQvxU,2187928
35
+ kea2/assets/fastbot_libs/arm64-v8a/libfastbot_native.so,sha256=UPZ8O5sGs_4rCQy0YDlJ9JUJvoLCi65IxjaLuM1VhYU,2492920
36
+ kea2/assets/fastbot_libs/armeabi-v7a/libfastbot_native.so,sha256=d3IIGlWNrOed1BvVNGEqBMgJ2dWos-L89odZnWrdL9s,1746460
37
+ kea2/assets/fastbot_libs/x86/libfastbot_native.so,sha256=A6SVgtWF2J3CkZdY0pghQRKdNg7JQy9TE2ndI7Z2Yig,2617404
38
+ kea2/assets/fastbot_libs/x86_64/libfastbot_native.so,sha256=0deNxr1ztTRiFmMOUU_6Cbv945xYG4YGvzjul3qL-Us,2678424
39
39
  kea2/fastbotx/ActivityTimes.py,sha256=TdDf-R6rD6Ts8yGTynD9PQ35HXxIBoetPnWRt9SO85U,1926
40
40
  kea2/fastbotx/ReuseEntry.py,sha256=qndFBv2EoJbQUz1iIghJbn-Vb1RPJBpDdJbqYQGs1OE,2745
41
41
  kea2/fastbotx/ReuseModel.py,sha256=n2uLO1_wJrKaFaMh-pHE_BiW3Wm4_wmkdFeTkIIxlWI,2245
42
42
  kea2/fastbotx/__init__.py,sha256=xAY10rHxVVcwpqkJ0AyYlAq5A5CDG6ZQhCDQNBiAUSE,170
43
43
  kea2/report/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
44
- kea2/report/bug_report_generator.py,sha256=-qW87qVIgqP95SxM_pg6XVPPzbGBUivQ2aVkkuHcmt0,39032
44
+ kea2/report/bug_report_generator.py,sha256=Y9MxH29_1V0iqdXIwxyjEN7iOPmKFG_CHJSnwQwGEC8,39218
45
45
  kea2/report/mixin.py,sha256=hlyNx-1QyYmZ4uATMbG83VW_Wou7dC0wpwmBur4gjiM,19372
46
46
  kea2/report/report_merger.py,sha256=XqSivdvQAz-MF8pYrfIq7VGAhCJzTsSoRhDRaj9BAUc,43062
47
47
  kea2/report/utils.py,sha256=r-oPtqbSDo8X0-V7zoIrz49TJ2-w-W444DS0de67mtk,344
48
- kea2/report/widget_coverage.py,sha256=tpxYNWQeWOeJ7cyDEff_n410YPZ2Ttm1MQjm48PNefg,5979
48
+ kea2/report/widget_coverage.py,sha256=cKftBeirNNdn2deGAqQ5ZZm24wF4hNv5uqMdypeoMf4,6413
49
49
  kea2/report/templates/bug_report_template.html,sha256=PVhQ1gkXIvS-1gYrvHGSxLSXK2ryK_zhPHyuCDj1JX4,190851
50
50
  kea2/report/templates/merged_bug_report_template.html,sha256=hu2ZXl1ktCcteG3UKdYwPhMKj1nyRXQrAW1ipAX-UjM,166488
51
- kea2_python-1.2.0.dist-info/licenses/LICENSE,sha256=nM9PPjcsXVo5SzNsjRqWgA-gdJlwqZZcRDSC6Qf6bVE,2034
52
- kea2_python-1.2.0.dist-info/METADATA,sha256=Altj3WXpFktBBVYTZR4lbeKaLodMm5DLWiuSs8h9FCI,22086
53
- kea2_python-1.2.0.dist-info/WHEEL,sha256=YCfwYGOYMi5Jhw2fU4yNgwErybb2IX5PEwBKV4ZbdBo,91
54
- kea2_python-1.2.0.dist-info/entry_points.txt,sha256=mFX06TyxXiUAJQ6JZn8QHzfn8n5R8_KJ5W-pTm_fRCA,39
55
- kea2_python-1.2.0.dist-info/top_level.txt,sha256=TsgNH4PQoNOVhegpO7AcjutMVWp6Z4KDL1pBH9FnMmk,5
56
- kea2_python-1.2.0.dist-info/RECORD,,
51
+ kea2_python-1.2.2.dist-info/licenses/LICENSE,sha256=nM9PPjcsXVo5SzNsjRqWgA-gdJlwqZZcRDSC6Qf6bVE,2034
52
+ kea2_python-1.2.2.dist-info/METADATA,sha256=2S8jgRV5ATAIRz8Z5rijoGbE3NbyrNFvj0GcpiccJZs,22051
53
+ kea2_python-1.2.2.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
54
+ kea2_python-1.2.2.dist-info/entry_points.txt,sha256=mFX06TyxXiUAJQ6JZn8QHzfn8n5R8_KJ5W-pTm_fRCA,39
55
+ kea2_python-1.2.2.dist-info/top_level.txt,sha256=TsgNH4PQoNOVhegpO7AcjutMVWp6Z4KDL1pBH9FnMmk,5
56
+ kea2_python-1.2.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (82.0.0)
2
+ Generator: setuptools (82.0.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5