[gtk/test-text-buffer-undo: 3/5] Add a dnd test to the headless tests




commit 20cc789808debc65892a38e5cb7294e9c58a209a
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed Apr 28 06:29:41 2021 -0400

    Add a dnd test to the headless tests

 tests/headless-input-tests.py | 259 +++++++++++++++++++++++++++++++++++++++---
 1 file changed, 242 insertions(+), 17 deletions(-)
---
diff --git a/tests/headless-input-tests.py b/tests/headless-input-tests.py
index 807eff41e0..888c50b040 100644
--- a/tests/headless-input-tests.py
+++ b/tests/headless-input-tests.py
@@ -5,10 +5,10 @@ import gi
 gi.require_version('Gdk', '4.0')
 gi.require_version('Gtk', '4.0')
 
-from gi.repository import GLib, Gdk, Gtk
+from gi.repository import GLib, GObject, Gdk, Gtk
 from pydbus import SessionBus
 
-verbose = False
+verbose = True
 
 remote_desktop = None
 screen_cast = None
@@ -68,12 +68,11 @@ def motion_cb (controller, x, y):
 
     if verbose:
         print(f'got motion: {x}, {y}')
-    assert expected_change != None, "Unexpected motion"
-    assert expected_change['type'] == 'motion', "Motion event expected"
-    assert x == expected_change['x'], "Unexpected x coord in motion event"
-    assert y == expected_change['y'], "Unexpected y coord in motion event"
-
-    expected_change = None
+    if expected_change != None:
+        assert expected_change['type'] == 'motion', "Motion event expected"
+        assert x == expected_change['x'], "Unexpected x coord in motion event"
+        assert y == expected_change['y'], "Unexpected y coord in motion event"
+        expected_change = None
     loop.quit()
 
 def enter_cb (controller, x, y):
@@ -90,6 +89,33 @@ def enter_cb (controller, x, y):
     expected_change = None
     loop.quit()
 
+def pressed_cb(controller, n, x, y):
+    global expected_change
+    global loop
+
+    if verbose:
+        print(f'got pressed')
+    assert expected_change != None, "Unexpected event"
+    assert expected_change['type'] == 'press', "Button press expected"
+    assert expected_change['button'] == controller.get_current_button(), "Unexpected button pressed"
+    assert x == expected_change['x'], "Unexpected x coord in motion event"
+    assert y == expected_change['y'], "Unexpected y coord in motion event"
+
+    expected_change = None
+    loop.quit()
+
+def released_cb(controller, n, x, y):
+    global expected_change
+    global loop
+
+    if verbose:
+        print(f'got released')
+    assert expected_change != None, "Unexpected event"
+    assert expected_change['type'] == 'release', "Button release expected"
+
+    expected_change = None
+    loop.quit()
+
 def expect_key_press(keyval, state, timeout):
     global expected_change
     expected_change = {
@@ -130,8 +156,31 @@ def expect_enter(x, y, timeout):
     wait(timeout)
     assert expected_change == None, "Expected event did not happen"
 
+def expect_button_press(button, x, y, timeout):
+    global expected_change
+    expected_change = {
+      'type' : 'press',
+      'button' : button,
+      'x' : x,
+      'y' : y
+    }
+    wait(timeout)
+    assert expected_change == None, "Button press did not arrive"
+
+def expect_button_release(button, x, y, timeout):
+    global expected_change
+    expected_change = {
+      'type' : 'release',
+      'button' : button,
+      'x' : x,
+      'y' : y
+    }
+    wait(timeout)
+    assert expected_change == None, "Button release did not arrive"
+
 def got_active(object, pspec):
     global loop
+    object.disconnect_by_func(got_active)
     loop.quit()
 
 def launch_observer():
@@ -160,6 +209,12 @@ def launch_observer():
     controller.connect('motion', motion_cb)
     window.add_controller(controller)
 
+    controller = Gtk.GestureClick.new()
+    controller.set_propagation_phase(Gtk.PropagationPhase.CAPTURE)
+    controller.connect('pressed', pressed_cb)
+    controller.connect('released', released_cb)
+    window.add_controller(controller)
+
     window.connect('notify::is-active', got_active)
     window.maximize()
     window.present()
@@ -188,6 +243,22 @@ def key_release(keyval):
         print(f'release key {keyval}')
     session.NotifyKeyboardKeysym(keyval, False)
 
+buttons = {
+    1 : 0x110,
+    2 : 0x111,
+    3 : 0x112
+}
+
+def button_press(button):
+    if verbose:
+        print(f'press button {button}')
+    session.NotifyPointerButton(buttons[button], True)
+
+def button_release(button):
+    if verbose:
+        print(f'relase button {button}')
+    session.NotifyPointerButton(buttons[button], False)
+
 def pointer_move(x, y):
     if verbose:
         print(f'pointer move {x} {y}')
@@ -222,21 +293,175 @@ def basic_keyboard_tests():
 
 def basic_pointer_tests():
     try:
-      pointer_move(-100.0, -100.0)
-      launch_observer()
+        pointer_move(-100.0, -100.0)
+        launch_observer()
+
+        # observer window is maximized, so window coords == global coords
+        pointer_move(500.0, 300.0)
+        expect_enter(x=500, y=300, timeout=200)
+
+        pointer_move(400.0, 200.0)
+        expect_motion(x=400, y=200, timeout=200)
+
+        button_press(1)
+        expect_button_press(button=1, x=400, y=200, timeout=200)
 
-      # observer window is maximized, so window coords == global coords
-      pointer_move(500.0, 300.0)
-      expect_enter(x=500, y=300, timeout=200)
+        pointer_move(220.0, 200.0)
+        expect_motion(x=220, y=200, timeout=200)
 
-      pointer_move(200.0, 200.0)
-      expect_motion(x=200, y=200, timeout=200)
+        button_release(1)
+        expect_button_release(button=1, x=220, y=200, timeout=200)
 
-      stop_observer()
+        stop_observer()
     except AssertionError as e:
         print("Error in basic_pointer_tests: {0}".format(e))
         terminate()
 
+ds_window = None
+ds = None
+
+def drag_begin(controller, drag):
+    global expected_change
+    global loop
+
+    if verbose:
+        print(f'got drag begin')
+    assert expected_change != None, "Unexpected drag begin"
+    assert expected_change['type'] == 'drag', "Drag begin expected"
+
+    expected_change = None
+    loop.quit()
+
+def launch_drag_source(value):
+    global display
+    global ds_window
+    global ds
+
+    if verbose:
+        print('launch drag source')
+
+    if display == None:
+        Gdk.set_allowed_backends('wayland')
+        display = Gdk.Display.open('gtk-test')
+
+    ds_window = Gtk.Window.new()
+    ds_window.set_title('Drag Source')
+    ds_window.set_display(display)
+
+    ds = Gtk.DragSource.new()
+    ds.set_content(Gdk.ContentProvider.new_for_value(value))
+    ds_window.add_controller(ds)
+    ds.connect('drag-begin', drag_begin)
+
+    controller = Gtk.GestureClick.new()
+    controller.set_propagation_phase(Gtk.PropagationPhase.CAPTURE)
+    controller.connect('pressed', pressed_cb)
+    controller.connect('released', released_cb)
+    ds_window.add_controller(controller)
+
+    ds_window.connect('notify::is-active', got_active)
+    ds_window.maximize()
+    ds_window.present()
+
+    wait(500)
+
+    assert ds_window.is_active(), "drag source not active"
+    assert ds_window.get_width() == 1024, "Window not maximized"
+    assert ds_window.get_height() == 768, "Window not maximized"
+
+    # we need to wait out the map animation, or pointer coords will be off
+    wait(1000)
+
+def stop_drag_source():
+    global ds_window
+    ds_window.destroy()
+    ds_window = None
+
+dt_window = None
+
+def do_drop(controller, value, x, y):
+    global expected_change
+    global loop
+
+    if verbose:
+        print(f'got drop {value}')
+    assert expected_change != None, "Unexpected drop begin"
+    assert expected_change['type'] == 'drop', "Drop expected"
+    assert expected_change['value'] == value, "Unexpected value dropped"
+
+    expected_change = None
+    loop.quit()
+
+def launch_drop_target():
+    global dt_window
+
+    if verbose:
+        print('launch drop target')
+
+    dt_window = Gtk.Window.new()
+    dt_window.set_title('Drop Target')
+    dt_window.set_display(display)
+
+    controller = Gtk.DropTarget.new(GObject.TYPE_STRING, Gdk.DragAction.COPY)
+    dt_window.add_controller(controller)
+    controller.connect('drop', do_drop)
+
+    dt_window.connect('notify::is-active', got_active)
+    dt_window.maximize()
+    dt_window.present()
+
+    wait(500)
+
+    assert dt_window.is_active(), "drop target not active"
+    assert dt_window.get_width() == 1024, "Window not maximized"
+    assert dt_window.get_height() == 768, "Window not maximized"
+
+    # we need to wait out the map animation, or pointer coords will be off
+    wait(1000)
+
+def stop_drop_target():
+    global dt_window
+    dt_window.destroy()
+    dt_window = None
+
+def expect_drag(timeout):
+    global expected_change
+    expected_change = {
+      'type' : 'drag',
+    }
+    wait(timeout)
+    assert expected_change == None, "DND operation not started"
+
+def expect_drop(value, timeout):
+    global expected_change
+    expected_change = {
+      'type' : 'drop',
+      'value' : value
+    }
+    wait(timeout)
+    assert expected_change == None, "Drop has not happened"
+
+def dnd_tests():
+    try:
+        launch_drag_source('abc')
+
+        pointer_move(100, 100)
+        button_press(1)
+        expect_button_press(button=1, x=100, y=100, timeout=300)
+
+        pointer_move(120, 150)
+        expect_drag(timeout=1000)
+
+        launch_drop_target()
+        button_release(1)
+        expect_drop('abc', timeout=200)
+
+        stop_drop_target()
+        stop_drag_source()
+    except AssertionError as e:
+        print("Error in dnd_tests: {0}".format(e))
+        terminate()
+
 def session_closed_cb():
     print('Session closed')
 
@@ -266,11 +491,11 @@ def mutter_appeared(name):
     screen_cast_session = bus.get('org.gnome.Mutter.ScreenCast', screen_cast_session_path)
 
     stream_path = screen_cast_session.RecordMonitor('Meta-0', {})
-
     session.Start()
 
     basic_keyboard_tests()
     basic_pointer_tests()
+    dnd_tests()
 
     session.Stop()
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]