AltTester-Driver 2.2.2__tar.gz → 2.2.4__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.
Files changed (111) hide show
  1. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/AltTester_Driver.egg-info/PKG-INFO +2 -2
  2. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/AltTester_Driver.egg-info/SOURCES.txt +1 -0
  3. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/PKG-INFO +2 -2
  4. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/__version__.py +1 -1
  5. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/_websocket.py +10 -1
  6. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/altdriver.py +23 -5
  7. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/altobject.py +30 -1
  8. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/FindObjects/__init__.py +1 -0
  9. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/FindObjects/wait_for_component_property.py +8 -2
  10. alttester_driver-2.2.4/alttester/commands/FindObjects/wait_for_visual_element_property.py +79 -0
  11. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/base_command.py +0 -1
  12. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/tests/integration/conftest.py +4 -0
  13. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/tests/integration/test_scene01_part1.py +20 -0
  14. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/tests/integration/test_scene01_part2.py +4 -1
  15. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/tests/integration/test_scene02.py +2 -0
  16. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/tests/integration/test_scene03.py +11 -3
  17. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/tests/integration/test_scene05.py +7 -3
  18. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/tests/integration/test_scene07.py +3 -1
  19. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/tests/integration/test_scene09.py +2 -0
  20. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/tests/integration/test_scene10.py +2 -0
  21. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/AltTester_Driver.egg-info/dependency_links.txt +0 -0
  22. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/AltTester_Driver.egg-info/not-zip-safe +0 -0
  23. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/AltTester_Driver.egg-info/requires.txt +0 -0
  24. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/AltTester_Driver.egg-info/top_level.txt +0 -0
  25. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/MANIFEST.in +0 -0
  26. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/README.md +0 -0
  27. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/__init__.py +0 -0
  28. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/by.py +0 -0
  29. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/AltTesterCommands/__init__.py +0 -0
  30. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/AltTesterCommands/add_notification_listener.py +0 -0
  31. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/AltTesterCommands/remove_notification_listener.py +0 -0
  32. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/AltTesterCommands/reset_input.py +0 -0
  33. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/AltTesterCommands/set_server_logging.py +0 -0
  34. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/FindObjects/find_object.py +0 -0
  35. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/FindObjects/find_object_at_coordinates.py +0 -0
  36. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/FindObjects/find_object_which_contains.py +0 -0
  37. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/FindObjects/find_objects.py +0 -0
  38. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/FindObjects/find_objects_which_contains.py +0 -0
  39. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/FindObjects/wait_for_object.py +0 -0
  40. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/FindObjects/wait_for_object_to_not_be_present.py +0 -0
  41. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/FindObjects/wait_for_object_which_contains.py +0 -0
  42. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/InputActions/__init__.py +0 -0
  43. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/InputActions/begin_touch.py +0 -0
  44. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/InputActions/click_coordinates.py +0 -0
  45. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/InputActions/end_touch.py +0 -0
  46. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/InputActions/keys_down.py +0 -0
  47. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/InputActions/keys_up.py +0 -0
  48. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/InputActions/move_mouse.py +0 -0
  49. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/InputActions/move_touch.py +0 -0
  50. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/InputActions/multi_point_swipe.py +0 -0
  51. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/InputActions/press_keys.py +0 -0
  52. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/InputActions/scroll_mouse.py +0 -0
  53. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/InputActions/swipe.py +0 -0
  54. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/InputActions/tap_coordinates.py +0 -0
  55. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/InputActions/tilt.py +0 -0
  56. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/Notifications/__init__.py +0 -0
  57. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/Notifications/base_notification_callbacks.py +0 -0
  58. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/Notifications/load_scene_mode.py +0 -0
  59. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/Notifications/load_scene_notification_result.py +0 -0
  60. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/Notifications/log_notification_result.py +0 -0
  61. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/Notifications/notification_type.py +0 -0
  62. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/ObjectCommands/__init__.py +0 -0
  63. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/ObjectCommands/call_method.py +0 -0
  64. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/ObjectCommands/click_element.py +0 -0
  65. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/ObjectCommands/find_object_from_object.py +0 -0
  66. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/ObjectCommands/get_all_components.py +0 -0
  67. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/ObjectCommands/get_component_property.py +0 -0
  68. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/ObjectCommands/get_text.py +0 -0
  69. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/ObjectCommands/pointer_down.py +0 -0
  70. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/ObjectCommands/pointer_enter.py +0 -0
  71. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/ObjectCommands/pointer_exit.py +0 -0
  72. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/ObjectCommands/pointer_up.py +0 -0
  73. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/ObjectCommands/set_component_property.py +0 -0
  74. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/ObjectCommands/set_text.py +0 -0
  75. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/ObjectCommands/tap_element.py +0 -0
  76. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/UnityCommands/__init__.py +0 -0
  77. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/UnityCommands/delete_player_pref.py +0 -0
  78. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/UnityCommands/delete_player_pref_key.py +0 -0
  79. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/UnityCommands/get_all_loaded_scenes.py +0 -0
  80. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/UnityCommands/get_current_scene.py +0 -0
  81. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/UnityCommands/get_player_pref_key.py +0 -0
  82. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/UnityCommands/get_time_scale.py +0 -0
  83. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/UnityCommands/get_visual_element_property.py +0 -0
  84. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/UnityCommands/load_scene.py +0 -0
  85. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/UnityCommands/set_player_pref_key.py +0 -0
  86. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/UnityCommands/set_time_scale.py +0 -0
  87. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/UnityCommands/unload_scene.py +0 -0
  88. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/UnityCommands/wait_for_current_scene_to_be.py +0 -0
  89. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/__init__.py +0 -0
  90. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/get_png_screenshot.py +0 -0
  91. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/get_server_version.py +0 -0
  92. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/get_static_property.py +0 -0
  93. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/commands/set_static_property.py +0 -0
  94. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/exceptions.py +0 -0
  95. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/keycode.py +0 -0
  96. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/logging.py +0 -0
  97. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/playerpref.py +0 -0
  98. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/alttester/reverse_port_forwarding.py +0 -0
  99. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/requirements-dev.txt +0 -0
  100. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/requirements.txt +0 -0
  101. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/setup.cfg +0 -0
  102. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/setup.py +0 -0
  103. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/tests/integration/__init__.py +0 -0
  104. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/tests/integration/test_driver.py +0 -0
  105. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/tests/integration/test_notifications.py +0 -0
  106. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/tests/integration/test_reverse_port_forwarding.py +0 -0
  107. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/tests/integration/utils.py +0 -0
  108. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/tests/unit/__init__.py +0 -0
  109. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/tests/unit/test_altobject.py +0 -0
  110. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/tests/unit/test_commands.py +0 -0
  111. {alttester_driver-2.2.2 → alttester_driver-2.2.4}/tests/unit/test_websocket.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: AltTester-Driver
3
- Version: 2.2.2
3
+ Version: 2.2.4
4
4
  Summary: Python bindings for the AltTester® framework. AltTester® is an open-source UI driven test automation tool that helps you find objects in your game and interacts with them.
5
5
  Home-page: https://alttester.com/docs/sdk/latest/
6
6
  Author: Altom Consulting
@@ -41,6 +41,7 @@ alttester/commands/FindObjects/wait_for_component_property.py
41
41
  alttester/commands/FindObjects/wait_for_object.py
42
42
  alttester/commands/FindObjects/wait_for_object_to_not_be_present.py
43
43
  alttester/commands/FindObjects/wait_for_object_which_contains.py
44
+ alttester/commands/FindObjects/wait_for_visual_element_property.py
44
45
  alttester/commands/InputActions/__init__.py
45
46
  alttester/commands/InputActions/begin_touch.py
46
47
  alttester/commands/InputActions/click_coordinates.py
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: AltTester-Driver
3
- Version: 2.2.2
3
+ Version: 2.2.4
4
4
  Summary: Python bindings for the AltTester® framework. AltTester® is an open-source UI driven test automation tool that helps you find objects in your game and interacts with them.
5
5
  Home-page: https://alttester.com/docs/sdk/latest/
6
6
  Author: Altom Consulting
@@ -15,4 +15,4 @@
15
15
  along with this program. If not, see <https://www.gnu.org/licenses/>.
16
16
  """
17
17
 
18
- VERSION = "2.2.2"
18
+ VERSION = "2.2.4"
@@ -179,6 +179,7 @@ class WebsocketConnection:
179
179
  self._command_handler = command_handler
180
180
  self._notification_handler = notification_handler
181
181
  self._driver_registered_called = False
182
+ self._implicit_timeout = -1
182
183
 
183
184
  def __repr__(self):
184
185
  return "{}({!r}, {!r}, {!r}, {!r}, {!r})".format(
@@ -287,6 +288,14 @@ class WebsocketConnection:
287
288
  def get_command_timeout(self):
288
289
  return self.command_timeout
289
290
 
291
+ def set_implicit_timeout(self, timeout):
292
+ if timeout < 0:
293
+ raise ValueError("Timeout cannot be negative")
294
+ self._implicit_timeout = timeout
295
+
296
+ def get_implicit_timeout(self):
297
+ return self._implicit_timeout
298
+
290
299
  def connect(self):
291
300
  logger.info("Connecting to URL: '{}'.", self.url)
292
301
  last_close_message = None
@@ -330,7 +339,7 @@ class WebsocketConnection:
330
339
  def recv(self):
331
340
  self._ensure_connection_is_open()
332
341
  elapsed_time = 0
333
- delay = 0.1
342
+ delay = 0.01
334
343
 
335
344
  while elapsed_time <= self.command_timeout:
336
345
  if self._command_handler.has_response():
@@ -147,6 +147,8 @@ class AltDriver:
147
147
  if not is_supported:
148
148
  message = "Version mismatch. AltDriver version is {}. AltTester(R) version is {}.".format(
149
149
  VERSION, server_version)
150
+ if server_major == 1:
151
+ message += " Please update AltTester(R) to version 1.1."
150
152
  logger.warning(message)
151
153
 
152
154
  def _get_alt_object(self, data):
@@ -283,13 +285,13 @@ class AltDriver:
283
285
  scene_name, load_single
284
286
  )
285
287
 
286
- def wait_for_current_scene_to_be(self, scene_name, timeout=30, interval=1):
288
+ def wait_for_current_scene_to_be(self, scene_name, timeout=20, interval=1):
287
289
  """Waits for the scene to be loaded for a specified amount of time.
288
290
 
289
291
  Args:
290
292
  scene_name (:obj:`str`): The name of the scene to wait for.
291
293
  timeout (obj:`int`, :obj:`float`, optional): The time measured in seconds to wait for the specified scene.
292
- Defaults to ``30``.
294
+ Defaults to ``20``.
293
295
  interval (obj:`int`, :obj:`float`, optional): How often to check that the scene was loaded in the given
294
296
  timeout. Defaults to ``1``.
295
297
 
@@ -297,7 +299,8 @@ class AltDriver:
297
299
  str: The name of the loaded scene.
298
300
 
299
301
  """
300
-
302
+ if self._connection.get_implicit_timeout() != -1 and timeout == 20:
303
+ timeout = self._connection.get_implicit_timeout()
301
304
  return commands.WaitForCurrentSceneToBe.run(
302
305
  self._connection,
303
306
  scene_name, timeout, interval
@@ -518,6 +521,8 @@ class AltDriver:
518
521
 
519
522
  """
520
523
 
524
+ if self._connection.get_implicit_timeout() != -1 and timeout == 20:
525
+ timeout = self._connection.get_implicit_timeout()
521
526
  data = commands.WaitForObject.run(
522
527
  self._connection,
523
528
  by, value, camera_by, camera_value, timeout, interval, enabled
@@ -548,7 +553,8 @@ class AltDriver:
548
553
  AltObject: The object.
549
554
 
550
555
  """
551
-
556
+ if self._connection.get_implicit_timeout() != -1 and timeout == 20:
557
+ timeout = self._connection.get_implicit_timeout()
552
558
  data = commands.WaitForObjectWhichContains.run(
553
559
  self._connection,
554
560
  by, value, camera_by, camera_value, timeout, interval, enabled
@@ -577,7 +583,8 @@ class AltDriver:
577
583
  ``False`` will match all objects. Defaults to ``True``.
578
584
 
579
585
  """
580
-
586
+ if self._connection.get_implicit_timeout() != -1 and timeout == 20:
587
+ timeout = self._connection.get_implicit_timeout()
581
588
  commands.WaitForObjectToNotBePresent.run(
582
589
  self._connection,
583
590
  by, value, camera_by, camera_value, timeout, interval, enabled
@@ -933,3 +940,14 @@ class AltDriver:
933
940
  """Clear all active input actions simulated by AltTester."""
934
941
 
935
942
  commands.ResetInput.run(self._connection)
943
+
944
+ def set_implicit_timeout(self, timeout):
945
+ """Sets an implicit timeout from tests for the AltTester commands using a timeout.
946
+ Args:
947
+ timeout (:obj:`int`): the new value of the timeout.
948
+ """
949
+ self._connection.set_implicit_timeout(timeout)
950
+
951
+ def get_implicit_timeout(self):
952
+ """Returns the implicit timeout used by AltTester commands."""
953
+ return self._connection.get_implicit_timeout()
@@ -201,6 +201,8 @@ class AltObject:
201
201
  str: The property value is serialized to a JSON string.
202
202
 
203
203
  """
204
+ if self._connection.get_implicit_timeout() != -1 and timeout == 20:
205
+ timeout = self._connection.get_implicit_timeout()
204
206
  return commands.WaitForComponentProperty.run(
205
207
  component_name, property_name, property_value,
206
208
  assembly, self, timeout, interval, get_property_as_string, max_depth
@@ -398,4 +400,31 @@ class AltObject:
398
400
  if self.type != "UIToolkit":
399
401
  raise exceptions.WrongAltObjectTypeException(
400
402
  "This method is only available for VisualElement objects")
401
- return commands.GetVisualElementProperty.run(self._connection, property_name, self,)
403
+ return commands.GetVisualElementProperty.run(self._connection, property_name, self)
404
+
405
+ def wait_for_visual_element_property(self, property_name,
406
+ property_value, timeout=20, interval=0.5,
407
+ get_property_as_string=False):
408
+ """Waits until a property of the current object has a specific value.
409
+
410
+ Args:
411
+ property_name (str): The name of the property of which value you want to get.
412
+ property_value (str): The value of the property expected.
413
+ timeout (int, optional): The number of seconds that it will wait for property. Defaults to 20.
414
+ interval (int, optional): Time in seconds before retrying. Defaults to 0.5.
415
+ get_property_as_string (bool, optional): A boolean value that makes the property_value
416
+ to be compared as a string with the property from the instrumented app. Defaults to False.
417
+
418
+ Returns:
419
+ The property value is serialized to a JSON string.
420
+
421
+ Raises:
422
+ WrongAltObjectTypeException: The method is called on an object that is not a VisualElement.
423
+ """
424
+ if self.type != "UIToolkit":
425
+ raise exceptions.WrongAltObjectTypeException(
426
+ "This method is only available for VisualElement objects")
427
+ if self._connection.get_implicit_timeout() != -1 and timeout == 20:
428
+ timeout = self._connection.get_implicit_timeout()
429
+ return commands.WaitForVisualElementProperty.run(
430
+ property_name, property_value, self, timeout, interval, get_property_as_string)
@@ -24,3 +24,4 @@ from alttester.commands.FindObjects.wait_for_object_to_not_be_present import *
24
24
  from alttester.commands.FindObjects.wait_for_object_which_contains import *
25
25
  from alttester.commands.FindObjects.find_object_at_coordinates import *
26
26
  from alttester.commands.FindObjects.wait_for_component_property import *
27
+ from alttester.commands.FindObjects.wait_for_visual_element_property import *
@@ -16,6 +16,7 @@
16
16
  """
17
17
 
18
18
  import time
19
+ import json
19
20
  from loguru import logger
20
21
  from alttester.commands.base_command import Command
21
22
  from alttester.exceptions import WaitTimeOutException
@@ -55,8 +56,13 @@ class WaitForComponentProperty(Command):
55
56
  )
56
57
  if not self.get_property_as_string and property_found == self.property_value:
57
58
  return property_found
58
- if self.get_property_as_string and \
59
- str(property_found).replace(" ", "") == str(self.property_value).replace(" ", ""):
59
+ if (str(property_found) == "0.0" and str(self.property_value) == "0"):
60
+ return property_found
61
+ if self.get_property_as_string and (
62
+ str(property_found).replace(" ", "") == str(self.property_value).replace(" ", "") or
63
+ str(json.dumps(property_found)).replace(" ", "") == str(
64
+ self.property_value).replace(" ", "")
65
+ ):
60
66
  return property_found
61
67
  except Exception as ex:
62
68
  exception = ex
@@ -0,0 +1,79 @@
1
+ """
2
+ Copyright(C) 2025 Altom Consulting
3
+
4
+ This program is free software: you can redistribute it and/or modify
5
+ it under the terms of the GNU General Public License as published by
6
+ the Free Software Foundation, either version 3 of the License, or
7
+ (at your option) any later version.
8
+
9
+ This program is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ GNU General Public License for more details.
13
+
14
+ You should have received a copy of the GNU General Public License
15
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
16
+ """
17
+
18
+ import time
19
+ import json
20
+ from loguru import logger
21
+ from alttester.commands.base_command import Command
22
+ from alttester.exceptions import WaitTimeOutException
23
+
24
+
25
+ class WaitForVisualElementProperty(Command):
26
+ def __init__(
27
+ self,
28
+ property_name,
29
+ property_value,
30
+ altObject,
31
+ timeout=20,
32
+ interval=0.5,
33
+ get_property_as_string=False,
34
+ ):
35
+ self.property_name = property_name
36
+ self.property_value = property_value
37
+ self.timeout = timeout
38
+ self.interval = interval
39
+ self.get_property_as_string = get_property_as_string
40
+ self.altObject = altObject
41
+
42
+ def execute(self):
43
+ t = 0
44
+ exception = None
45
+ property_found = None
46
+ while t <= self.timeout:
47
+ try:
48
+ property_found = self.altObject.get_visual_element_property(
49
+ self.property_name
50
+ )
51
+ if not self.get_property_as_string and property_found == self.property_value:
52
+ return property_found
53
+ if (str(property_found) == "0.0" and str(self.property_value) == "0"):
54
+ return property_found
55
+ if self.get_property_as_string and \
56
+ (
57
+ str(property_found).replace(" ", "") == str(self.property_value).replace(" ", "") or
58
+ str(json.dumps(property_found)).replace(" ", "") == str(
59
+ self.property_value).replace(" ", "")
60
+ ):
61
+
62
+ return property_found
63
+ except Exception as ex:
64
+ exception = ex
65
+
66
+ logger.debug("Waiting for property {}...", self.property_name)
67
+ time.sleep(self.interval)
68
+ t += self.interval
69
+ if exception:
70
+ raise WaitTimeOutException(
71
+ "After {} seconds, exception was: {} for property {}".format(
72
+ self.timeout, exception, self.property_name
73
+ )
74
+ )
75
+ raise WaitTimeOutException(
76
+ "Property {} was {}, not {} as expected, after {} seconds".format(
77
+ self.property_name, property_found, self.property_value, self.timeout
78
+ )
79
+ )
@@ -238,7 +238,6 @@ class BaseCommand(Command):
238
238
  response = self.connection.recv()
239
239
  self.handle_response(response)
240
240
  data = response.get("data")
241
- time.sleep(0.1)
242
241
  if data is None:
243
242
  return data
244
243
  return json.loads(data)
@@ -32,6 +32,8 @@ sys.stdout = sys.stderr
32
32
  devices = [
33
33
  {"name": "Samsung Galaxy S23", "os": "android", "os_version": "13.0"},
34
34
  {"name": "Google Pixel 6 Pro", "os": "android", "os_version": "13.0"},
35
+ {"name": "iPhone 16", "os": "ios", "os_version": "18"},
36
+ {"name": "iPhone 15 Pro Max", "os": "ios", "os_version": "17"},
35
37
  {"name": "iPhone 14 Pro Max", "os": "ios", "os_version": "16"},
36
38
  {"name": "OnePlus 9", "os": "android", "os_version": "11.0"},
37
39
  {"name": "iPhone 13 Pro Max", "os": "ios", "os_version": "15"},
@@ -46,6 +48,8 @@ android_devices = [
46
48
  ]
47
49
 
48
50
  ios_devices = [
51
+ {"name": "iPhone 16", "os": "ios", "os_version": "18"},
52
+ {"name": "iPhone 15 Pro Max", "os": "ios", "os_version": "17"},
49
53
  {"name": "iPhone 14 Pro Max", "os": "ios", "os_version": "16"},
50
54
  {"name": "iPhone 13 Pro Max", "os": "ios", "os_version": "15"},
51
55
  {"name": "iPhone 12 Pro", "os": "ios", "os_version": "14"},
@@ -27,6 +27,8 @@ class TestScene01Part1:
27
27
 
28
28
  @pytest.fixture(autouse=True)
29
29
  def setup(self):
30
+ self.alt_driver.find_object(
31
+ By.PATH, "/AltTesterPrefab//CloseButton", enabled=False).tap()
30
32
  self.alt_driver.reset_input()
31
33
  self.alt_driver.load_scene(Scenes.Scene01)
32
34
 
@@ -540,3 +542,21 @@ class TestScene01Part1:
540
542
  capsule = self.alt_driver.find_object(By.NAME, "Capsule")
541
543
  final_position = [capsule.worldX, capsule.worldY, capsule.worldZ]
542
544
  assert initial_position != final_position
545
+
546
+ def test_implicit_timeout(self):
547
+ self.alt_driver.set_implicit_timeout(1)
548
+ assert self.alt_driver.get_implicit_timeout() == 1
549
+ start_time = time.time()
550
+ try:
551
+ self.alt_driver.wait_for_object(By.NAME, "Capsulee")
552
+ except Exception:
553
+ pass
554
+ end_time = time.time()
555
+ elapsed_time = end_time - start_time
556
+ assert elapsed_time <= 2
557
+ self.alt_driver.set_implicit_timeout(20)
558
+
559
+ def test_implicit_timeout_out_of_range(self):
560
+ with pytest.raises(ValueError) as exc_info:
561
+ self.alt_driver.set_implicit_timeout(-5)
562
+ assert str(exc_info.value) == "Timeout cannot be negative"
@@ -26,6 +26,8 @@ class TestScene01Part2:
26
26
 
27
27
  @pytest.fixture(autouse=True)
28
28
  def setup(self):
29
+ self.alt_driver.find_object(
30
+ By.PATH, "/AltTesterPrefab//CloseButton", enabled=False).tap()
29
31
  self.alt_driver.reset_input()
30
32
  self.alt_driver.load_scene(Scenes.Scene01)
31
33
 
@@ -502,7 +504,8 @@ class TestScene01Part2:
502
504
 
503
505
  def test_find_object_in_object_by_id(self):
504
506
  parent = self.alt_driver.find_object(By.NAME, "Canvas")
505
- child = parent.find_object_from_object(By.ID, "049eccc5-b072-468b-83bf-119d868ca311")
507
+ child = parent.find_object_from_object(
508
+ By.ID, "049eccc5-b072-468b-83bf-119d868ca311")
506
509
  assert child.name == "Button"
507
510
 
508
511
  def test_find_object_in_object_by_text(self):
@@ -25,6 +25,8 @@ class TestScene02:
25
25
 
26
26
  @pytest.fixture(autouse=True)
27
27
  def setup(self):
28
+ self.alt_driver.find_object(
29
+ By.PATH, "/AltTesterPrefab//CloseButton", enabled=False).tap()
28
30
  self.alt_driver.reset_input()
29
31
  self.alt_driver.load_scene(Scenes.Scene02)
30
32
 
@@ -26,6 +26,8 @@ class TestScene03:
26
26
 
27
27
  @pytest.fixture(autouse=True)
28
28
  def setup(self):
29
+ self.alt_driver.find_object(
30
+ By.PATH, "/AltTesterPrefab//CloseButton", enabled=False).tap()
29
31
  self.alt_driver.reset_input()
30
32
  self.alt_driver.load_scene(Scenes.Scene03)
31
33
 
@@ -50,8 +52,10 @@ class TestScene03:
50
52
  self.alt_driver.multipoint_swipe(positions, duration, wait)
51
53
 
52
54
  def drop_image(self, drag_location_name, drop_location_name, duration, wait):
53
- drag_location = self.alt_driver.find_object(By.NAME, drag_location_name)
54
- drop_location = self.alt_driver.find_object(By.NAME, drop_location_name)
55
+ drag_location = self.alt_driver.find_object(
56
+ By.NAME, drag_location_name)
57
+ drop_location = self.alt_driver.find_object(
58
+ By.NAME, drop_location_name)
55
59
 
56
60
  self.alt_driver.swipe(drag_location.get_screen_position(
57
61
  ), drop_location.get_screen_position(), duration, wait)
@@ -122,7 +126,7 @@ class TestScene03:
122
126
  self.drop_image_with_multipoint_swipe(
123
127
  ["Drag Image1", "Drop Box1"], 1, False)
124
128
  self.drop_image_with_multipoint_swipe(
125
- ["Drag Image2", "Drop Box1", "Drop Box2"], 1, False)
129
+ ["Drag Image2", "Drop Box1", "Drop Box2"], 1, True)
126
130
 
127
131
  image_source, image_source_drop_zone = self.get_sprite_name(
128
132
  "Drag Image1", "Drop Image")
@@ -148,6 +152,10 @@ class TestScene03:
148
152
  assert image_source == image_source_drop_zone
149
153
 
150
154
  def test_begin_move_end_touch(self):
155
+ green_pop_up = self.alt_driver.find_object(
156
+ By.PATH, "/AltTesterPrefab//CloseButton", enabled=False)
157
+ if (green_pop_up.enabled):
158
+ green_pop_up.click()
151
159
  alt_object1 = self.alt_driver.find_object(By.NAME, "Drag Image1")
152
160
  alt_object2 = self.alt_driver.find_object(By.NAME, "Drop Box1")
153
161
 
@@ -27,6 +27,8 @@ class TestScene05:
27
27
 
28
28
  @pytest.fixture(autouse=True)
29
29
  def setup(self):
30
+ self.alt_driver.find_object(
31
+ By.PATH, "/AltTesterPrefab//CloseButton", enabled=False).tap()
30
32
  self.alt_driver.reset_input()
31
33
  self.alt_driver.load_scene(Scenes.Scene05)
32
34
 
@@ -131,15 +133,17 @@ class TestScene05:
131
133
 
132
134
  def test_key_down_and_key_up(self):
133
135
  self.alt_driver.key_down(AltKeyCode.A)
134
-
135
- last_key_down = self.alt_driver.find_object(By.NAME, "LastKeyDownValue")
136
+ time.sleep(0.1)
137
+ self.alt_driver.key_up(AltKeyCode.A)
138
+ time.sleep(0.1)
139
+ last_key_down = self.alt_driver.find_object(
140
+ By.NAME, "LastKeyDownValue")
136
141
  last_key_press = self.alt_driver.find_object(
137
142
  By.NAME, "LastKeyPressedValue")
138
143
 
139
144
  assert last_key_down.get_text() == "97"
140
145
  assert last_key_press.get_text() == "97"
141
146
 
142
- self.alt_driver.key_up(AltKeyCode.A)
143
147
  last_key_up = self.alt_driver.find_object(By.NAME, "LastKeyUpValue")
144
148
 
145
149
  assert last_key_up.get_text() == "97"
@@ -25,6 +25,8 @@ class TestScene07A:
25
25
 
26
26
  @pytest.fixture(autouse=True)
27
27
  def setup(self):
28
+ self.alt_driver.find_object(
29
+ By.PATH, "/AltTesterPrefab//CloseButton", enabled=False).tap()
28
30
  self.alt_driver.reset_input()
29
31
  self.alt_driver.load_scene(Scenes.Scene07A)
30
32
 
@@ -114,7 +116,7 @@ class TestScene07B:
114
116
  self.drop_image_with_multipoint_swipe(
115
117
  ["Drag Image1", "Drop Box1"], 1, False)
116
118
  self.drop_image_with_multipoint_swipe(
117
- ["Drag Image2", "Drop Box1", "Drop Box2"], 1, False)
119
+ ["Drag Image2", "Drop Box1", "Drop Box2"], 1, True)
118
120
 
119
121
  image_source, image_source_drop_zone = self.get_sprite_name(
120
122
  "Drag Image1", "Drop Image")
@@ -25,6 +25,8 @@ class TestScene09:
25
25
 
26
26
  @pytest.fixture(autouse=True)
27
27
  def setup(self):
28
+ self.alt_driver.find_object(
29
+ By.PATH, "/AltTesterPrefab//CloseButton", enabled=False).tap()
28
30
  self.alt_driver.reset_input()
29
31
  self.alt_driver.load_scene(Scenes.Scene09)
30
32
 
@@ -25,6 +25,8 @@ class TestScene10:
25
25
 
26
26
  @pytest.fixture(autouse=True)
27
27
  def setup(self):
28
+ self.alt_driver.find_object(
29
+ By.PATH, "/AltTesterPrefab//CloseButton", enabled=False).tap()
28
30
  self.alt_driver.reset_input()
29
31
  self.alt_driver.load_scene(Scenes.Scene10)
30
32