Three touch points that move/resize three windows simultaneously are tested Change-Id: I17d0c8c6c5c90f5121a098e5b67174167cd5aaa5 Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
389 lines
17 KiB
Python
389 lines
17 KiB
Python
# Copyright (C) 2022 The Qt Company Ltd.
|
|
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
|
|
|
from selenium.webdriver import Chrome
|
|
from selenium.webdriver.common.actions.action_builder import ActionBuilder
|
|
from selenium.webdriver.common.actions.pointer_actions import PointerActions
|
|
from selenium.webdriver.common.actions.interaction import POINTER_TOUCH
|
|
from selenium.webdriver.common.actions.pointer_input import PointerInput
|
|
from selenium.webdriver.common.by import By
|
|
from selenium.webdriver.support.expected_conditions import presence_of_element_located
|
|
from selenium.webdriver.support.ui import WebDriverWait
|
|
from selenium.webdriver.common.action_chains import ActionChains
|
|
|
|
import unittest
|
|
|
|
|
|
class WidgetTestCase(unittest.TestCase):
|
|
def setUp(self):
|
|
self._driver = Chrome()
|
|
self._driver.get(
|
|
'http://localhost:8001/qwasmwindow_harness.html')
|
|
self._test_sandbox_element = WebDriverWait(self._driver, 30).until(
|
|
presence_of_element_located((By.ID, 'test-sandbox'))
|
|
)
|
|
|
|
def _make_geometry(self, x, y, width, height):
|
|
return {'x': x, 'y': y, 'width': width, 'height': height}
|
|
|
|
def test_window_resizing(self):
|
|
screen = self._create_screen_with_fixed_position(0, 0, 600, 600)
|
|
screen_information = self._screen_information()
|
|
self.assertEqual(len(screen_information), 1)
|
|
screen_information = screen_information[-1]
|
|
window = self._create_window(
|
|
100, 100, 200, 200, screen, screen_information["name"], 'title')
|
|
|
|
window_information = self._window_information()[0]
|
|
self.assertEqual(
|
|
window_information["geometry"], self._make_geometry(100, 100, 200, 200))
|
|
|
|
self._drag_window(window, window_information, [0, 0], [-10, -10])
|
|
window_information = self._window_information()[0]
|
|
self.assertEqual(
|
|
window_information["geometry"], self._make_geometry(90, 90, 210, 210))
|
|
|
|
self._drag_window(window, window_information,
|
|
[window_information['frameGeometry']['width'] / 2, 0], [-100, 10])
|
|
window_information = self._window_information()[0]
|
|
self.assertEqual(
|
|
window_information["geometry"], self._make_geometry(90, 100, 210, 200))
|
|
|
|
self._drag_window(window, window_information,
|
|
[window_information['frameGeometry']['width'], 0], [-5, -5])
|
|
window_information = self._window_information()[0]
|
|
|
|
self.assertEqual(
|
|
window_information["geometry"], self._make_geometry(90, 95, 205, 205))
|
|
|
|
self._drag_window(window, window_information,
|
|
[window_information['frameGeometry']['width'],
|
|
window_information['frameGeometry']['height'] / 2], [5, 100])
|
|
window_information = self._window_information()[0]
|
|
|
|
self.assertEqual(
|
|
window_information["geometry"], self._make_geometry(90, 95, 210, 205))
|
|
|
|
self._drag_window(window, window_information,
|
|
[window_information['frameGeometry']['width'],
|
|
window_information['frameGeometry']['height']], [-10, -5])
|
|
window_information = self._window_information()[0]
|
|
|
|
self.assertEqual(self._window_information()[0]["geometry"],
|
|
self._make_geometry(90, 95, 200, 200))
|
|
|
|
self._drag_window(window, window_information, [
|
|
window_information['frameGeometry']['width'] / 2,
|
|
window_information['frameGeometry']['height']], [-100, 20])
|
|
window_information = self._window_information()[0]
|
|
|
|
self.assertEqual(self._window_information()[0]["geometry"],
|
|
self._make_geometry(90, 95, 200, 220))
|
|
|
|
self._drag_window(window, window_information, [
|
|
0, window_information['frameGeometry']['height']], [-10, 10])
|
|
window_information = self._window_information()[0]
|
|
|
|
self.assertEqual(self._window_information()[0]["geometry"],
|
|
self._make_geometry(80, 95, 210, 230))
|
|
|
|
self._drag_window(window, window_information, [
|
|
0, window_information['frameGeometry']['height'] / 2], [-5, 343])
|
|
window_information = self._window_information()[0]
|
|
|
|
self.assertEqual(self._window_information()[0]["geometry"],
|
|
self._make_geometry(75, 95, 215, 230))
|
|
|
|
def test_cannot_resize_over_screen_top_edge(self):
|
|
screen = self._create_screen_with_fixed_position(200, 200, 300, 300)
|
|
screen_information = self._screen_information()[-1]
|
|
|
|
window = self._create_window(
|
|
300, 300, 100, 100, screen, screen_information['name'], 'title')
|
|
|
|
window_information = self._window_information()[0]
|
|
frame_geometry_before_resize = window_information["frameGeometry"]
|
|
self.assertEqual(
|
|
window_information["geometry"], self._make_geometry(300, 300, 100, 100))
|
|
|
|
self._drag_window(window, window_information,
|
|
[window_information['frameGeometry']['width'] / 2, 0], [0, -200])
|
|
|
|
geometry = self._window_information()[0]["geometry"]
|
|
frame_geometry = self._window_information()[0]["frameGeometry"]
|
|
self.assertEqual(geometry['x'], 300)
|
|
self.assertEqual(frame_geometry['y'],
|
|
screen_information['geometry']['y'])
|
|
self.assertEqual(geometry['width'], 100)
|
|
self.assertEqual(frame_geometry['y'] + frame_geometry['height'],
|
|
frame_geometry_before_resize['y'] + frame_geometry_before_resize['height'])
|
|
|
|
def test_window_move(self):
|
|
screen = self._create_screen_with_fixed_position(200, 200, 300, 300)
|
|
screen_information = self._screen_information()[-1]
|
|
|
|
window = self._create_window(
|
|
300, 300, 100, 100, screen, screen_information['name'], 'title')
|
|
|
|
self.assertEqual(
|
|
self._window_information()[0]["geometry"], self._make_geometry(300, 300, 100, 100))
|
|
|
|
window_information = self._window_information()[0]
|
|
self._drag_window(window, window_information,
|
|
[window_information['frameGeometry']['width'] / 2, 6], [0, -30])
|
|
|
|
self.assertEqual(self._window_information()[0]["geometry"],
|
|
self._make_geometry(300, 270, 100, 100))
|
|
|
|
window_information = self._window_information()[0]
|
|
window_frame_top = window_information['frameGeometry']['y']
|
|
window_client_area_top = window_information['geometry']['y']
|
|
|
|
top_frame_height = window_client_area_top - window_frame_top + 1
|
|
|
|
self._drag_window(window, window_information,
|
|
[window_information['frameGeometry']['width'] / 2,
|
|
top_frame_height], [0, -30])
|
|
|
|
self.assertEqual(self._window_information()[0]["geometry"],
|
|
self._make_geometry(300, 270, 100, 100))
|
|
|
|
def test_screen_limits_window_moves(self):
|
|
screen = self._create_screen_with_relative_position(200, 200, 300, 300)
|
|
screen_information = self._screen_information()[-1]
|
|
|
|
window = self._create_window(
|
|
300, 300, 100, 100, screen, screen_information['name'], 'title')
|
|
|
|
self.assertEqual(self._window_information()[0]["geometry"],
|
|
self._make_geometry(300, 300, 100, 100))
|
|
|
|
window_information = self._window_information()[0]
|
|
self._drag_window(window, window_information,
|
|
[window_information['frameGeometry']['width'] / 2, 6], [-300, 0])
|
|
self.assertEqual(
|
|
self._window_information()[0]["frameGeometry"]['x'],
|
|
screen_information['geometry']['x'] - window_information['frameGeometry']['width'] / 2)
|
|
|
|
def test_screen_in_scroll_container_limits_window_moves(self):
|
|
_, screen = self._create_screen_in_scroll_container(
|
|
500, 7000, 200, 2000, 300, 300)
|
|
screen_information = self._screen_information()[-1]
|
|
|
|
ActionChains(self._driver).scroll_to_element(screen).perform()
|
|
|
|
window = self._create_window(
|
|
300, 2100, 100, 100, screen, screen_information['name'], 'title')
|
|
|
|
self.assertEqual(self._window_information()[0]["geometry"],
|
|
self._make_geometry(300, 2100, 100, 100))
|
|
|
|
window_information = self._window_information()[0]
|
|
self._drag_window(window, window_information,
|
|
[window_information['frameGeometry']['width'] / 2, 6], [-300, 0])
|
|
self.assertEqual(
|
|
self._window_information()[0]["frameGeometry"]['x'],
|
|
screen_information['geometry']['x'] - window_information['frameGeometry']['width'] / 2)
|
|
|
|
def test_maximize(self):
|
|
screen = self._create_screen_with_relative_position(200, 200, 300, 300)
|
|
screen_information = self._screen_information()[-1]
|
|
|
|
window = self._create_window(
|
|
300, 300, 100, 100, screen, screen_information['name'], 'Maximize')
|
|
|
|
self.assertEqual(self._window_information()[0]["geometry"],
|
|
self._make_geometry(300, 300, 100, 100))
|
|
|
|
maximize_button = window.find_element(
|
|
By.CSS_SELECTOR, f'.title-bar :nth-child(6)')
|
|
maximize_button.click()
|
|
|
|
self.assertEqual(
|
|
self._window_information()[0]["frameGeometry"],
|
|
self._make_geometry(200, 200, 300, 300))
|
|
|
|
def test_multitouch_window_move(self):
|
|
screen = self._create_screen_with_fixed_position(0, 0, 800, 800)
|
|
screen_information = self._screen_information()[-1]
|
|
|
|
windows = [
|
|
self._create_window(50, 50, 100, 100, screen,
|
|
screen_information['name'], 'First'),
|
|
self._create_window(
|
|
400, 400, 100, 100, screen, screen_information['name'], 'Second'),
|
|
self._create_window(50, 400, 100, 100, screen,
|
|
screen_information['name'], 'Third')
|
|
]
|
|
|
|
window_information = [
|
|
self._window_information(title) for title in ['First', 'Second', 'Third']]
|
|
|
|
self.assertEqual(
|
|
window_information[0]["geometry"], self._make_geometry(50, 50, 100, 100))
|
|
self.assertEqual(
|
|
window_information[1]["geometry"], self._make_geometry(400, 400, 100, 100))
|
|
self.assertEqual(
|
|
window_information[2]["geometry"], self._make_geometry(50, 400, 100, 100))
|
|
|
|
touch_action_builder = ActionBuilder(self._driver)
|
|
|
|
touch_pointer_actions = [PointerActions(source=touch_action_builder.add_pointer_input(
|
|
POINTER_TOUCH, f'touch_input_{i}')) for i in range(3)]
|
|
|
|
# Move the touch pointers to the middle of the title bar
|
|
for window, info, action in zip(windows, window_information, touch_pointer_actions):
|
|
action.move_to(window, x=0, y=-
|
|
info['frameGeometry']['height'] / 2 + 6)
|
|
action.pointer_down(width=10, height=10, pressure=1)
|
|
|
|
offsets = [[2, 2], [-2, 2], [2, -2]]
|
|
for _ in range(10):
|
|
for action, offset in zip(touch_pointer_actions, offsets):
|
|
action.move_by(x=offset[0], y=offset[1], width=10, height=10)
|
|
|
|
for action in touch_pointer_actions:
|
|
action.pointer_up()
|
|
|
|
touch_action_builder.perform()
|
|
|
|
self.assertEqual(self._window_information('First')["geometry"],
|
|
self._make_geometry(70, 70, 100, 100))
|
|
self.assertEqual(self._window_information('Second')["geometry"],
|
|
self._make_geometry(380, 420, 100, 100))
|
|
self.assertEqual(self._window_information('Third')["geometry"],
|
|
self._make_geometry(70, 380, 100, 100))
|
|
|
|
def test_multitouch_window_resize(self):
|
|
screen = self._create_screen_with_fixed_position(0, 0, 800, 800)
|
|
screen_information = self._screen_information()[-1]
|
|
|
|
windows = [
|
|
self._create_window(50, 50, 100, 100, screen,
|
|
screen_information['name'], 'First'),
|
|
self._create_window(
|
|
400, 400, 100, 100, screen, screen_information['name'], 'Second'),
|
|
self._create_window(50, 400, 100, 100, screen,
|
|
screen_information['name'], 'Third')
|
|
]
|
|
|
|
window_information = [
|
|
self._window_information(title) for title in ['First', 'Second', 'Third']]
|
|
|
|
self.assertEqual(
|
|
window_information[0]["geometry"], self._make_geometry(50, 50, 100, 100))
|
|
self.assertEqual(
|
|
window_information[1]["geometry"], self._make_geometry(400, 400, 100, 100))
|
|
self.assertEqual(
|
|
window_information[2]["geometry"], self._make_geometry(50, 400, 100, 100))
|
|
|
|
touch_action_builder = ActionBuilder(self._driver)
|
|
|
|
touch_pointer_actions = [PointerActions(source=touch_action_builder.add_pointer_input(
|
|
POINTER_TOUCH, f'touch_input_{i}')) for i in range(3)]
|
|
|
|
initial_offsets = [
|
|
# top left
|
|
[-window_information[0]['frameGeometry']['width'] / 2,
|
|
-window_information[0]['frameGeometry']['height'] / 2],
|
|
# top
|
|
[0,
|
|
-window_information[1]['frameGeometry']['height'] / 2],
|
|
# bottom right
|
|
[window_information[2]['frameGeometry']['width'] / 2,
|
|
window_information[2]['frameGeometry']['height'] / 2],
|
|
]
|
|
|
|
for window, initial_offset, action in zip(windows, initial_offsets, touch_pointer_actions):
|
|
action.move_to(window, x=initial_offset[0], y=initial_offset[1])
|
|
action.pointer_down(width=10, height=10, pressure=1)
|
|
|
|
# First resizes NE, Second NW, Third SE
|
|
offsets = [[2, 2], [-2, 2], [2, -2]]
|
|
for _ in range(10):
|
|
for action, offset in zip(touch_pointer_actions, offsets):
|
|
action.move_by(x=offset[0], y=offset[1], width=10, height=10)
|
|
|
|
for action in touch_pointer_actions:
|
|
action.pointer_up()
|
|
|
|
touch_action_builder.perform()
|
|
|
|
self.assertEqual(self._window_information('First')["geometry"],
|
|
self._make_geometry(70, 70, 80, 80))
|
|
self.assertEqual(self._window_information('Second')["geometry"],
|
|
self._make_geometry(400, 420, 100, 80))
|
|
self.assertEqual(self._window_information('Third')["geometry"],
|
|
self._make_geometry(50, 400, 120, 80))
|
|
|
|
def tearDown(self):
|
|
self._driver.quit()
|
|
|
|
def _drag_window(self, window_element, window_information, origin, offset):
|
|
ActionChains(self._driver).move_to_element(
|
|
window_element).move_by_offset(
|
|
-window_information['frameGeometry']['width'] / 2 + origin[0],
|
|
-window_information['frameGeometry']['height'] / 2 + origin[1]).click_and_hold(
|
|
).move_by_offset(*offset).release().perform()
|
|
|
|
def _call_instance_function(self, name):
|
|
return self._driver.execute_script(
|
|
f'''let result;
|
|
window.{name}Callback = data => result = data;
|
|
instance.{name}();
|
|
return eval(result);''')
|
|
|
|
def _window_information(self, title=None):
|
|
information = self._call_instance_function('windowInformation')
|
|
if not title:
|
|
return information
|
|
return next(filter(lambda e: e['title'] == title, information))
|
|
|
|
def _screen_information(self):
|
|
return self._call_instance_function('screenInformation')
|
|
|
|
def _get_resize_location(self, screen, window_info, which):
|
|
frame_geometry = window_info['frameGeometry']
|
|
frame_x_in_screen = frame_geometry['x'] - screen['geometry']['x']
|
|
frame_y_in_screen = frame_geometry['y'] - screen['geometry']['y']
|
|
|
|
return [frame_x_in_screen, frame_y_in_screen]
|
|
|
|
def _get_title_bar(self, window):
|
|
return window.find_element(
|
|
By.CSS_SELECTOR, f'.window-name')
|
|
|
|
def _create_screen_with_fixed_position(self, x, y, w, h):
|
|
return self._driver.execute_script(
|
|
f'''
|
|
return testSupport.initializeScreenWithFixedPosition({x}, {y}, {w}, {h});
|
|
'''
|
|
)
|
|
|
|
def _create_screen_with_relative_position(self, x, y, w, h):
|
|
return self._driver.execute_script(
|
|
f'''
|
|
return testSupport.initializeScreenWithRelativePosition({x}, {y}, {w}, {h});
|
|
'''
|
|
)
|
|
|
|
def _create_screen_in_scroll_container(self, containerW, containerH, x, y, w, h):
|
|
return self._driver.execute_script(
|
|
f'''
|
|
return testSupport.initializeScreenInScrollContainer(
|
|
{containerW}, {containerH}, {x}, {y}, {w}, {h});
|
|
'''
|
|
)
|
|
|
|
def _create_window(self, x, y, w, h, screen, screen_id, title):
|
|
self._driver.execute_script(
|
|
f'''
|
|
instance.createWindow({x}, {y}, {w}, {h}, '{screen_id}', '{title}');
|
|
'''
|
|
)
|
|
window_id = self._window_information(title)["id"]
|
|
return screen.shadow_root.find_element(By.CSS_SELECTOR, f'#qt-window-{window_id}')
|
|
|
|
|
|
unittest.main()
|