diff options
author | Mikolaj Boc <[email protected]> | 2023-06-14 14:54:34 +0200 |
---|---|---|
committer | Mikolaj Boc <[email protected]> | 2023-06-15 09:41:06 +0200 |
commit | fc4fca6d9dc22839ca73898c362faff96c81214c (patch) | |
tree | a30fcc5804cf28f81631f970d54e2c6207549f9a /tests/manual/wasm/qwasmwindow/qwasmwindow.py | |
parent | eb92d52dc7190efefae0fae89c7c6eb9e16cdd9d (diff) |
Support child windows on WASM
Setting parents for WASM platform windows is now supported. This means
that windows now reside in a hierarchical window tree, with the screen
and individual windows being nodes (QWasmWindowTreeNode), each
maintaining their own child window stack.
The divs backing windows are properly reparented in response to Qt
window parent changes, so that the html structure reflects what is
happening in Qt.
Change-Id: I55c91d90caf58714342dcd747043967ebfdf96bb
Reviewed-by: Morten Johan Sørvig <[email protected]>
Diffstat (limited to 'tests/manual/wasm/qwasmwindow/qwasmwindow.py')
-rw-r--r-- | tests/manual/wasm/qwasmwindow/qwasmwindow.py | 418 |
1 files changed, 373 insertions, 45 deletions
diff --git a/tests/manual/wasm/qwasmwindow/qwasmwindow.py b/tests/manual/wasm/qwasmwindow/qwasmwindow.py index 04e16112209..5bcc39361b1 100644 --- a/tests/manual/wasm/qwasmwindow/qwasmwindow.py +++ b/tests/manual/wasm/qwasmwindow/qwasmwindow.py @@ -14,6 +14,8 @@ from selenium.webdriver.common.action_chains import ActionChains import unittest from enum import Enum, auto +import time + class WidgetTestCase(unittest.TestCase): def setUp(self): self._driver = Chrome() @@ -28,8 +30,7 @@ class WidgetTestCase(unittest.TestCase): defaultWindowMinSize = 100 screen = Screen(self._driver, ScreenPosition.FIXED, x=0, y=0, width=600, height=600) - window = Window(screen, x=100, y=100, width=200, height=200) - window.set_visible(True) + window = Window(parent=screen, rect=Rect(x=100, y=100, width=200, height=200)) self.assertEqual(window.rect, Rect(x=100, y=100, width=200, height=200)) window.drag(Handle.TOP_LEFT, direction=UP(10) + LEFT(10)) @@ -62,8 +63,7 @@ class WidgetTestCase(unittest.TestCase): def test_cannot_resize_over_screen_top_edge(self): screen = Screen(self._driver, ScreenPosition.FIXED, x=200, y=200, width=300, height=300) - window = Window(screen, x=300, y=300, width=100, height=100) - window.set_visible(True) + window = Window(parent=screen, rect=Rect(x=300, y=300, width=100, height=100)) self.assertEqual(window.rect, Rect(x=300, y=300, width=100, height=100)) frame_rect_before_resize = window.frame_rect @@ -77,8 +77,7 @@ class WidgetTestCase(unittest.TestCase): def test_window_move(self): screen = Screen(self._driver, ScreenPosition.FIXED, x=200, y=200, width=300, height=300) - window = Window(screen, x=300, y=300, width=100, height=100) - window.set_visible(True) + window = Window(parent=screen, rect=Rect(x=300, y=300, width=100, height=100)) self.assertEqual(window.rect, Rect(x=300, y=300, width=100, height=100)) window.drag(Handle.TOP_WINDOW_BAR, direction=UP(30)) @@ -93,8 +92,7 @@ class WidgetTestCase(unittest.TestCase): def test_screen_limits_window_moves(self): screen = Screen(self._driver, ScreenPosition.RELATIVE, x=200, y=200, width=300, height=300) - window = Window(screen, x=300, y=300, width=100, height=100) - window.set_visible(True) + window = Window(parent=screen, rect=Rect(x=300, y=300, width=100, height=100)) self.assertEqual(window.rect, Rect(x=300, y=300, width=100, height=100)) window.drag(Handle.TOP_WINDOW_BAR, direction=LEFT(300)) @@ -105,8 +103,7 @@ class WidgetTestCase(unittest.TestCase): x=200, y=2000, width=300, height=300, container_width=500, container_height=7000) screen.scroll_to() - window = Window(screen, x=300, y=2100, width=100, height=100) - window.set_visible(True) + window = Window(parent=screen, rect=Rect(x=300, y=2100, width=100, height=100)) self.assertEqual(window.rect, Rect(x=300, y=2100, width=100, height=100)) window.drag(Handle.TOP_WINDOW_BAR, direction=LEFT(300)) @@ -115,8 +112,7 @@ class WidgetTestCase(unittest.TestCase): def test_maximize(self): screen = Screen(self._driver, ScreenPosition.RELATIVE, x=200, y=200, width=300, height=300) - window = Window(screen, x=300, y=300, width=100, height=100, title='Maximize') - window.set_visible(True) + window = Window(parent=screen, rect=Rect(x=300, y=300, width=100, height=100), title='Maximize') self.assertEqual(window.rect, Rect(x=300, y=300, width=100, height=100)) window.maximize() @@ -125,11 +121,9 @@ class WidgetTestCase(unittest.TestCase): def test_multitouch_window_move(self): screen = Screen(self._driver, ScreenPosition.FIXED, x=0, y=0, width=800, height=800) - windows = [Window(screen, x=50, y=50, width=100, height=100, title='First'), - Window(screen, x=400, y=400, width=100, height=100, title='Second'), - Window(screen, x=50, y=400, width=100, height=100, title='Third')] - for window in windows: - window.set_visible(True) + windows = [Window(screen, rect=Rect(x=50, y=50, width=100, height=100), title='First'), + Window(screen, rect=Rect(x=400, y=400, width=100, height=100), title='Second'), + Window(screen, rect=Rect(x=50, y=400, width=100, height=100), title='Third')] self.assertEqual(windows[0].rect, Rect(x=50, y=50, width=100, height=100)) self.assertEqual(windows[1].rect, Rect(x=400, y=400, width=100, height=100)) @@ -146,11 +140,9 @@ class WidgetTestCase(unittest.TestCase): def test_multitouch_window_resize(self): screen = Screen(self._driver, ScreenPosition.FIXED, x=0, y=0, width=800, height=800) - windows = [Window(screen, x=50, y=50, width=150, height=150, title='First'), - Window(screen, x=400, y=400, width=150, height=150, title='Second'), - Window(screen, x=50, y=400, width=150, height=150, title='Third')] - for window in windows: - window.set_visible(True) + windows = [Window(screen, rect=Rect(x=50, y=50, width=150, height=150), title='First'), + Window(screen, rect=Rect(x=400, y=400, width=150, height=150), title='Second'), + Window(screen, rect=Rect(x=50, y=400, width=150, height=150), title='Third')] self.assertEqual(windows[0].rect, Rect(x=50, y=50, width=150, height=150)) self.assertEqual(windows[1].rect, Rect(x=400, y=400, width=150, height=150)) @@ -167,8 +159,7 @@ class WidgetTestCase(unittest.TestCase): def test_newly_created_window_gets_keyboard_focus(self): screen = Screen(self._driver, ScreenPosition.FIXED, x=0, y=0, width=800, height=800) - window = Window(screen, x=0, y=0, width=800, height=800, title='root') - window.set_visible(True) + window = Window(parent=screen, rect=Rect(x=0, y=0, width=800, height=800), title='root') ActionChains(self._driver).key_down('c').key_up('c').perform() @@ -179,29 +170,262 @@ class WidgetTestCase(unittest.TestCase): self.assertEqual(events[-1]['type'], 'keyRelease') self.assertEqual(events[-1]['key'], 'c') + def test_parent_window_limits_moves_of_children(self): + screen = Screen(self._driver, ScreenPosition.FIXED, + x=0, y=0, width=800, height=800) + + w1 = Window(parent=screen, rect=Rect(x=200, y=200, width=400, height=400), title='w1') + w1_w1 = Window(parent=w1, rect=Rect(x=100, y=100, width=200, height=200), title='w1_w1') + w1_w1_w1 = Window(parent=w1_w1, rect=Rect(50, 50, 100, 100), title='w1_w1_w1') + + self.assertEqual(w1.rect, Rect(200, 200, 400, 400)) + self.assertEqual(w1_w1.rect, Rect(100, 100, 200, 200)) + self.assertEqual(w1_w1_w1.rect, Rect(50, 50, 100, 100)) + + # Left - Middle window + w1_w1.drag(Handle.TOP_WINDOW_BAR, direction=LEFT(300)) + + self.assertEqual( + w1_w1.frame_rect.x, -w1_w1.frame_rect.width / 2) + w1_w1.drag(Handle.TOP_WINDOW_BAR, direction=RIGHT(w1_w1.frame_rect.width / 2 + 100)) + + # Right - Middle window + w1_w1.drag(Handle.TOP_WINDOW_BAR, direction=RIGHT(300)) + + self.assertEqual( + w1_w1.frame_rect.x, w1.rect.width - w1_w1.frame_rect.width / 2) + w1_w1.drag(Handle.TOP_WINDOW_BAR, direction=LEFT(w1.rect.width / 2)) + + # Left - Inner window + w1_w1_w1.drag(Handle.TOP_WINDOW_BAR, direction=LEFT(300)) + + self.assertEqual( + w1_w1_w1.frame_rect.x, -w1_w1_w1.frame_rect.width / 2) + + def test_child_window_activation(self): + screen = Screen(self._driver, ScreenPosition.FIXED, + x=0, y=0, width=800, height=800) + + bottom = Window(parent=screen, rect=Rect(x=0, y=0, width=800, height=800), title='root') + w1 = Window(parent=bottom, rect=Rect(x=100, y=100, width=600, height=600), title='w1') + w1_w1 = Window(parent=w1, rect=Rect(x=100, y=100, width=300, height=300), title='w1_w1') + w1_w1_w1 = Window(parent=w1_w1, rect=Rect(x=100, y=100, width=100, height=100), title='w1_w1_w1') + w1_w1_w2 = Window(parent=w1_w1, rect=Rect(x=150, y=150, width=100, height=100), title='w1_w1_w2') + w1_w2 = Window(parent=w1, rect=Rect(x=300, y=300, width=300, height=300), title='w1_w2') + w1_w2_w1 = Window(parent=w1_w2, rect=Rect(x=100, y=100, width=100, height=100), title='w1_w2_w1') + w2 = Window(parent=bottom, rect=Rect(x=300, y=300, width=450, height=450), title='w2') + + self.assertEqual(screen.window_stack_at_point(w1_w1.bounding_box.midpoint[0], w1_w1.bounding_box.midpoint[1]), + [w2, w1_w1_w2, w1_w1_w1, w1_w1, w1, bottom]) + + self.assertEqual(screen.window_stack_at_point(w2.bounding_box.midpoint[0], w2.bounding_box.midpoint[1]), + [w2, w1_w2_w1, w1_w2, w1, bottom]) + + for w in [w1, w1_w1, w1_w1_w1, w1_w1_w2, w1_w2, w1_w2_w1]: + self.assertFalse(w.active) + self.assertTrue(w2.active) + + w1.click(0, 0) + + for w in [w1, w1_w2, w1_w2_w1]: + self.assertTrue(w.active) + for w in [w1_w1, w1_w1_w1, w1_w1_w2, w2]: + self.assertFalse(w.active) + + self.assertEqual(screen.window_stack_at_point(w2.frame_rect.midpoint[0], w2.frame_rect.midpoint[1]), + [w1_w2_w1, w1_w2, w1, w2, bottom]) + + w1_w1_w1.click(0, 0) + + for w in [w1, w1_w1, w1_w1_w1]: + self.assertTrue(w.active) + for w in [w1_w1_w2, w1_w2, w1_w2_w1, w2]: + self.assertFalse(w.active) + + self.assertEqual(screen.window_stack_at_point(w1_w1_w1.bounding_box.midpoint[0], w1_w1_w1.bounding_box.midpoint[1]), + [w1_w1_w1, w1_w1_w2, w1_w1, w1, w2, bottom]) + + w1_w1_w2.click(w1_w1_w2.bounding_box.width, w1_w1_w2.bounding_box.height) + + for w in [w1, w1_w1, w1_w1_w2]: + self.assertTrue(w.active) + for w in [w1_w1_w1, w1_w2, w1_w2_w1, w2]: + self.assertFalse(w.active) + + self.assertEqual(screen.window_stack_at_point(w1_w1_w2.bounding_box.x, w1_w1_w2.bounding_box.y), + [w1_w1_w2, w1_w1_w1, w1_w1, w1, w2, bottom]) + + def test_window_reparenting(self): + screen = Screen(self._driver, ScreenPosition.FIXED, + x=0, y=0, width=800, height=800) + + bottom = Window(parent=screen, rect=Rect(x=800, y=800, width=300, height=300), title='bottom') + w1 = Window(parent=screen, rect=Rect(x=50, y=50, width=300, height=300), title='w1') + w2 = Window(parent=screen, rect=Rect(x=50, y=50, width=300, height=300), title='w2') + w3 = Window(parent=screen, rect=Rect(x=50, y=50, width=300, height=300), title='w3') + + self.assertTrue( + w2.element not in [*w1.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w3.element not in [*w1.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w1.element not in [*w2.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w3.element not in [*w2.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w1.element not in [*w3.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w2.element not in [*w3.element.find_elements(By.XPATH, "ancestor::div")]) + + w2.set_parent(w1) + + self.assertTrue( + w2.element not in [*w1.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w3.element not in [*w1.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w1.element in [*w2.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w3.element not in [*w2.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w1.element not in [*w3.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w2.element not in [*w3.element.find_elements(By.XPATH, "ancestor::div")]) + + w3.set_parent(w2) + + self.assertTrue( + w2.element not in [*w1.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w3.element not in [*w1.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w1.element in [*w2.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w3.element not in [*w2.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w1.element in [*w3.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w2.element in [*w3.element.find_elements(By.XPATH, "ancestor::div")]) + + w2.set_parent(screen) + + self.assertTrue( + w2.element not in [*w1.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w3.element not in [*w1.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w1.element not in [*w2.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w3.element not in [*w2.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w1.element not in [*w3.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w2.element in [*w3.element.find_elements(By.XPATH, "ancestor::div")]) + + w1.set_parent(w2) + + self.assertTrue( + w2.element in [*w1.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w3.element not in [*w1.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w1.element not in [*w2.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w3.element not in [*w2.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w1.element not in [*w3.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w2.element in [*w3.element.find_elements(By.XPATH, "ancestor::div")]) + + w3.set_parent(screen) + + self.assertTrue( + w2.element in [*w1.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w3.element not in [*w1.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w1.element not in [*w2.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w3.element not in [*w2.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w1.element not in [*w3.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w2.element not in [*w3.element.find_elements(By.XPATH, "ancestor::div")]) + + w2.set_parent(w3) + + self.assertTrue( + w2.element in [*w1.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w3.element in [*w1.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w1.element not in [*w2.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w3.element in [*w2.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w1.element not in [*w3.element.find_elements(By.XPATH, "ancestor::div")]) + self.assertTrue( + w2.element not in [*w3.element.find_elements(By.XPATH, "ancestor::div")]) + + def test_window_closing(self): + screen = Screen(self._driver, ScreenPosition.FIXED, + x=0, y=0, width=800, height=800) + + bottom = Window(parent=screen, rect=Rect(x=800, y=800, width=300, height=300), title='root') + bottom.close() + + w1 = Window(parent=screen, rect=Rect(x=50, y=50, width=300, height=300), title='w1') + w2 = Window(parent=screen, rect=Rect(x=50, y=50, width=300, height=300), title='w2') + w3 = Window(parent=screen, rect=Rect(x=50, y=50, width=300, height=300), title='w3') + + w3.close() + + self.assertFalse(w3 in screen.query_windows()) + self.assertTrue(w2 in screen.query_windows()) + self.assertTrue(w1 in screen.query_windows()) + + w4 = Window(parent=screen, rect=Rect(x=50, y=50, width=300, height=300), title='w4') + + self.assertTrue(w4 in screen.query_windows()) + self.assertTrue(w2 in screen.query_windows()) + self.assertTrue(w1 in screen.query_windows()) + + w2.close() + w1.close() + + self.assertTrue(w4 in screen.query_windows()) + self.assertFalse(w2 in screen.query_windows()) + self.assertFalse(w1 in screen.query_windows()) + + w4.close() + + self.assertFalse(w4 in screen.query_windows()) + def tearDown(self): self._driver.quit() - class ScreenPosition(Enum): FIXED = auto() RELATIVE = auto() IN_SCROLL_CONTAINER = auto() - class Screen: - def __init__(self, driver, positioning, x, y, width, height, container_width=0, container_height=0): + def __init__(self, driver, positioning=None, x=None, y=None, width=None, height=None, container_width=0, container_height=0, screen_name=None): self.driver = driver - self.x = x - self.y = y - self.width = width - self.height = height + if screen_name is not None: + screen_information = call_instance_function(self.driver, 'screenInformation') + if len(screen_information) != 1: + raise AssertionError('Expecting exactly one screen_information!') + self.screen_info = screen_information[0] + self.element = driver.find_element(By.CSS_SELECTOR, f'#test-screen-1') + return + if positioning == ScreenPosition.FIXED: - command = f'initializeScreenWithFixedPosition({self.x}, {self.y}, {self.width}, {self.height})' + command = f'initializeScreenWithFixedPosition({x}, {y}, {width}, {height})' elif positioning == ScreenPosition.RELATIVE: - command = f'initializeScreenWithRelativePosition({self.x}, {self.y}, {self.width}, {self.height})' + command = f'initializeScreenWithRelativePosition({x}, {y}, {width}, {height})' elif positioning == ScreenPosition.IN_SCROLL_CONTAINER: - command = f'initializeScreenInScrollContainer({container_width}, {container_height}, {self.x}, {self.y}, {self.width}, {self.height})' + command = f'initializeScreenInScrollContainer({container_width}, {container_height}, {x}, {y}, {width}, {height})' self.element = self.driver.execute_script( f''' return testSupport.{command}; @@ -223,26 +447,72 @@ class Screen: geo = self.screen_info['geometry'] return Rect(geo['x'], geo['y'], geo['width'], geo['height']) + @property + def name(self): + return self.screen_info['name'] + def scroll_to(self): ActionChains(self.driver).scroll_to_element(self.element).perform() - -class Window: - def __init__(self, screen, x, y, width, height, title='title'): - self.driver = screen.driver - self.title = title - self.driver.execute_script( + def hit_test_point(self, x, y): + return self.driver.execute_script( f''' - instance.createWindow({x}, {y}, {width}, {height}, '{screen.screen_info["name"]}', '{title}'); + return testSupport.hitTestPoint({x}, {y}, '{self.element.get_attribute("id")}'); ''' ) + + def window_stack_at_point(self, x, y): + return [ + Window(self, element=element) for element in [ + *filter(lambda elem: (elem.get_attribute('id') if elem.get_attribute('id') is not None else '') + .startswith('qt-window-'), self.hit_test_point(x, y))]] + + def query_windows(self): + return [ + Window(self, element=element) for element in self.element.shadow_root.find_elements( + By.CSS_SELECTOR, f'div#{self.name} > div.qt-window')] + + +class Window: + def __init__(self, parent=None, rect=None, title=None, element=None, visible=True): + self.driver = parent.driver + if element is not None: + self.element = element + self.title = element.find_element( + By.CSS_SELECTOR, f'.title-bar > .window-name').text + information = self.__window_information() + self.screen = Screen(self.driver, screen_name=information['screen']['name']) + pass + else: + self.title = title = title if title is not None else 'window' + if isinstance(parent, Window): + self.driver.execute_script( + f''' + instance.createWindow({rect.x}, {rect.y}, {rect.width}, {rect.height}, 'window', '{parent.title}', '{title}'); + ''' + ) + self.screen = parent.screen + else: + assert(isinstance(parent, Screen)) + self.driver.execute_script( + f''' + instance.createWindow({rect.x}, {rect.y}, {rect.width}, {rect.height}, 'screen', '{parent.name}', '{title}'); + ''' + ) + self.screen = parent self._window_id = self.__window_information()['id'] - self.element = screen.element.shadow_root.find_element( - By.CSS_SELECTOR, f'#qt-window-{self._window_id}') + self.element = self.screen.element.shadow_root.find_element( + By.CSS_SELECTOR, f'#qt-window-{self._window_id}') + if visible: + self.set_visible(True) + + def __eq__(self, other): + return self._window_id == other._window_id if isinstance(other, Window) else False def __window_information(self): information = call_instance_function(self.driver, 'windowInformation') - return next(filter(lambda e: e['title'] == self.title, information)) + #print(information) + return next(filter(lambda e: e['title'] == self.title, information)) @property def rect(self): @@ -308,6 +578,61 @@ class Window: offset = (0, -height/2 + top_frame_bar_width/2) return {'window': self, 'offset': offset} + @property + def bounding_box(self): + raw = self.driver.execute_script(""" + return arguments[0].getBoundingClientRect(); + """, self.element) + return Rect(raw['x'], raw['y'], raw['width'], raw['height']) + + @property + def active(self): + return not self.inactive + # self.assertFalse('inactive' in window_element.get_attribute( + # 'class').split(' '), window_element.get_attribute('id')) + + @property + def inactive(self): + window_chain = [ + *self.element.find_elements(By.XPATH, "ancestor::div"), self.element] + return next(filter(lambda elem: 'qt-window' in elem.get_attribute('class').split(' ') and + 'inactive' in elem.get_attribute( + 'class').split(' '), + window_chain + ), None) is not None + + def click(self, x, y): + rect = self.bounding_box + + SELENIUM_IMPRECISION_COMPENSATION = 2 + ActionChains(self.driver).move_to_element( + self.element).move_by_offset(-rect.width / 2 + x + SELENIUM_IMPRECISION_COMPENSATION, + -rect.height / 2 + y + SELENIUM_IMPRECISION_COMPENSATION).click().perform() + + def set_parent(self, parent): + if isinstance(parent, Screen): + # TODO won't work with screen that is not parent.screen + self.screen = parent + self.driver.execute_script( + f''' + instance.setWindowParent('{self.title}', 'none'); + ''' + ) + else: + assert(isinstance(parent, Window)) + self.screen = parent.screen + self.driver.execute_script( + f''' + instance.setWindowParent('{self.title}', '{parent.title}'); + ''' + ) + + def close(self): + self.driver.execute_script( + f''' + instance.closeWindow('{self.title}'); + ''' + ) class TouchDragAction: def __init__(self, origin, direction): @@ -477,10 +802,13 @@ class Rect: def __str__(self): return f'(x: {self.x}, y: {self.y}, width: {self.width}, height: {self.height})' + @property + def midpoint(self): + return self.x + self.width / 2, self.y + self.height / 2, + def assert_rects_equal(geo1, geo2, msg=None): if geo1.x != geo2.x or geo1.y != geo2.y or geo1.width != geo2.width or geo1.height != geo2.height: raise AssertionError(f'Rectangles not equal: \n{geo1} \nvs \n{geo2}') - unittest.main() |