Addon Manager: Fix GUI tests on macOS
This commit is contained in:
committed by
Chris Hennes
parent
fe1c09f841
commit
e5587cd935
@@ -23,26 +23,21 @@
|
||||
from PySide import QtCore, QtWidgets
|
||||
|
||||
|
||||
class DialogWatcher(QtCore.QObject):
|
||||
"""Examine the running GUI and look for a modal dialog with a given title, containing a button
|
||||
with a given label. Click that button, which is expected to close the dialog. Generally run on
|
||||
a one-shot QTimer to allow the dialog time to open up. If the specified dialog is found, but
|
||||
it does not contain the expected button, button_found will be false, and the dialog will be
|
||||
closed with a reject() slot."""
|
||||
class DialogInteractor(QtCore.QObject):
|
||||
"""Takes the title of the dialog, a button string, and a callable. The callable is passed
|
||||
the widget we found and can do whatever it wants to it. Whatever it does should eventually
|
||||
close the dialog, however."""
|
||||
|
||||
def __init__(self, dialog_to_watch_for, button=QtWidgets.QDialogButtonBox.NoButton):
|
||||
def __init__(self, dialog_to_watch_for, interaction):
|
||||
super().__init__()
|
||||
|
||||
# Status variables for tests to check:
|
||||
self.dialog_found = False
|
||||
self.has_run = False
|
||||
self.button_found = False
|
||||
self.interaction = interaction
|
||||
|
||||
self.dialog_to_watch_for = dialog_to_watch_for
|
||||
if button != QtWidgets.QDialogButtonBox.NoButton:
|
||||
self.button = button
|
||||
else:
|
||||
self.button = QtWidgets.QDialogButtonBox.Cancel
|
||||
|
||||
self.execution_counter = 0
|
||||
self.timer = QtCore.QTimer()
|
||||
@@ -51,17 +46,12 @@ class DialogWatcher(QtCore.QObject):
|
||||
|
||||
def run(self):
|
||||
widget = QtWidgets.QApplication.activeModalWidget()
|
||||
if widget:
|
||||
# Is this the widget we are looking for?
|
||||
if (
|
||||
hasattr(widget, "windowTitle")
|
||||
and callable(widget.windowTitle)
|
||||
and widget.windowTitle() == self.dialog_to_watch_for
|
||||
):
|
||||
# Found the dialog we are looking for: now try to "click" the appropriate button
|
||||
self.click_button(widget)
|
||||
self.dialog_found = True
|
||||
self.timer.stop()
|
||||
if widget and self._dialog_matches(widget):
|
||||
# Found the dialog we are looking for: now try to run the interaction
|
||||
if self.interaction is not None and callable(self.interaction):
|
||||
self.interaction(widget)
|
||||
self.dialog_found = True
|
||||
self.timer.stop()
|
||||
|
||||
if self.execution_counter > 25 and not self.dialog_found:
|
||||
# OK, it wasn't the active modal widget... was it some other window, and never became
|
||||
@@ -69,11 +59,12 @@ class DialogWatcher(QtCore.QObject):
|
||||
windows = QtWidgets.QApplication.topLevelWidgets()
|
||||
for widget in windows:
|
||||
if (
|
||||
hasattr(widget, "windowTitle")
|
||||
and callable(widget.windowTitle)
|
||||
and widget.windowTitle() == self.dialog_to_watch_for
|
||||
hasattr(widget, "windowTitle")
|
||||
and callable(widget.windowTitle)
|
||||
and widget.windowTitle() == self.dialog_to_watch_for
|
||||
):
|
||||
self.click_button(widget)
|
||||
if self.interaction is not None and callable(self.interaction):
|
||||
self.interaction(widget)
|
||||
self.timer.stop()
|
||||
print("Found a window with the expected title, but it was not the active modal dialog.")
|
||||
|
||||
@@ -83,6 +74,32 @@ class DialogWatcher(QtCore.QObject):
|
||||
print("Stopped timer after 100 iterations")
|
||||
self.timer.stop()
|
||||
|
||||
def _dialog_matches(self, widget) -> bool:
|
||||
# Is this the widget we are looking for? Only applies on Linux and Windows: macOS
|
||||
# doesn't set the title of a modal dialog:
|
||||
os = QtCore.QSysInfo.productType() # Qt5 gives "osx", Qt6 gives "macos"
|
||||
if os in ["osx", "macos"] or (
|
||||
hasattr(widget, "windowTitle")
|
||||
and callable(widget.windowTitle)
|
||||
and widget.windowTitle() == self.dialog_to_watch_for
|
||||
):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class DialogWatcher(DialogInteractor):
|
||||
"""Examine the running GUI and look for a modal dialog with a given title, containing a button
|
||||
with a role. Click that button, which is expected to close the dialog. Generally run on
|
||||
a one-shot QTimer to allow the dialog time to open up. If the specified dialog is found, but
|
||||
it does not contain the expected button, button_found will be false, and the dialog will be
|
||||
closed with a reject() slot."""
|
||||
def __init__(self, dialog_to_watch_for, button=QtWidgets.QDialogButtonBox.NoButton):
|
||||
super().__init__(dialog_to_watch_for, self.click_button)
|
||||
if button != QtWidgets.QDialogButtonBox.NoButton:
|
||||
self.button = button
|
||||
else:
|
||||
self.button = QtWidgets.QDialogButtonBox.Cancel
|
||||
|
||||
def click_button(self, widget):
|
||||
button_boxes = widget.findChildren(QtWidgets.QDialogButtonBox)
|
||||
if len(button_boxes) == 1: # There should be one, and only one
|
||||
@@ -96,30 +113,6 @@ class DialogWatcher(QtCore.QObject):
|
||||
widget.reject()
|
||||
|
||||
|
||||
class DialogInteractor(DialogWatcher):
|
||||
def __init__(self, dialog_to_watch_for, interaction):
|
||||
"""Takes the title of the dialog, a button string, and a callable. The callable is passed
|
||||
the widget we found and can do whatever it wants to it. Whatever it does should eventually
|
||||
close the dialog, however."""
|
||||
super().__init__(dialog_to_watch_for, None)
|
||||
self.interaction = interaction
|
||||
|
||||
def run(self):
|
||||
widget = QtWidgets.QApplication.activeModalWidget()
|
||||
if widget:
|
||||
# Is this the widget we are looking for?
|
||||
if (
|
||||
hasattr(widget, "windowTitle")
|
||||
and callable(widget.windowTitle)
|
||||
and widget.windowTitle() == self.dialog_to_watch_for
|
||||
):
|
||||
self.dialog_found = True
|
||||
if self.dialog_found:
|
||||
self.has_run = True
|
||||
if self.interaction is not None and callable(self.interaction):
|
||||
self.interaction(widget)
|
||||
|
||||
|
||||
class FakeWorker:
|
||||
def __init__(self):
|
||||
self.called = False
|
||||
|
||||
Reference in New Issue
Block a user