Skip to content
Merged
Show file tree
Hide file tree
Changes from 55 commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
ba2378f
first round of updates for UI Tester (default_registry toolkit setup …
aaronayres35 Aug 19, 2020
a6d28ca
attempt to handle Null toolkit
aaronayres35 Aug 19, 2020
28d5094
fixing null handling
aaronayres35 Aug 19, 2020
684be1c
setting up MouseClick for ButtonEditor
aaronayres35 Aug 20, 2020
9973d38
adding DefaultTarget locator class and logic to handle its use in ui_…
aaronayres35 Aug 20, 2020
547b52b
addressing comments
aaronayres35 Aug 20, 2020
7fecb2a
merging changes from ui-tester-api-updates1 after review comments
aaronayres35 Aug 20, 2020
a6ede42
this test update was accidentally left out of merge
aaronayres35 Aug 20, 2020
69d5cd5
adding tests (currently broken due to imports)
aaronayres35 Aug 20, 2020
b97a923
adding test for toolkit specific default registries which test mouse …
aaronayres35 Aug 20, 2020
39c034e
fixing broken tests, and convert TraitsUI test for ButtonEditor to us…
aaronayres35 Aug 20, 2020
57fcdda
addressing comments
aaronayres35 Aug 21, 2020
dcdfdf8
Merge branch 'ui-tester-api-updates1' into ui-tester-api-updates2
aaronayres35 Aug 21, 2020
6266a83
updating helper functions and adding docstrings
aaronayres35 Aug 21, 2020
578b280
Merge branch 'master' into ui-tester-api-updates2
aaronayres35 Aug 21, 2020
fe4c597
adding __init__.py files
aaronayres35 Aug 21, 2020
df81380
adding docstring for DefaultTarget locator class
aaronayres35 Aug 21, 2020
9803375
first steps for KeySequence, KeyClick and DisplayedText for TextEditor
aaronayres35 Aug 21, 2020
9077c08
add QLineEdit, change key press names to click
aaronayres35 Aug 21, 2020
400d9d3
docstring updates and simple name change
aaronayres35 Aug 24, 2020
33f750f
fixing typo
aaronayres35 Aug 24, 2020
51e5b45
adding tests for new UIWrapper DefaultTarget logic
aaronayres35 Aug 24, 2020
3149374
flake8 fixes
aaronayres35 Aug 24, 2020
c43c88a
rename wobject wx_object
aaronayres35 Aug 24, 2020
e444628
fixing wx test failures
aaronayres35 Aug 24, 2020
d4d8012
more flake8 fixes
aaronayres35 Aug 24, 2020
848d513
making suggested changes from comments
aaronayres35 Aug 24, 2020
9753816
pull new DefaultTarget logic out into its own private method, and add…
aaronayres35 Aug 24, 2020
db80b28
fixing failures from last commit
aaronayres35 Aug 24, 2020
bc0e7f1
first steps towards updating tests
aaronayres35 Aug 24, 2020
eab72a8
Merge branch 'ui-tester-api-updates2' into ui-tester-api-updates3
aaronayres35 Aug 24, 2020
8a59b57
missed in merge
aaronayres35 Aug 24, 2020
77f5903
pre-master merge
aaronayres35 Aug 25, 2020
12e9d8f
Merge branch 'master' into ui-tester-api-updates3
aaronayres35 Aug 25, 2020
8428778
more changes to align with master (recreate updates from ui-tester-ap…
aaronayres35 Aug 25, 2020
fb3a535
make refactor changes (since removal of DefaultTarget)
aaronayres35 Aug 25, 2020
8b0f2eb
updating test_helpers
aaronayres35 Aug 25, 2020
55e0bfa
fix some test and comment one out (unsure how to test key_click on wx)
aaronayres35 Aug 25, 2020
69b5618
reremoivng get_qobject_registry
aaronayres35 Aug 26, 2020
5aeef94
adding docstrings to qt helpers
aaronayres35 Aug 26, 2020
d8baa03
updating wx helpers
aaronayres35 Aug 26, 2020
0284280
simple helper test improvements
aaronayres35 Aug 26, 2020
e1fdef6
update test_text_editor
aaronayres35 Aug 26, 2020
38e6ff7
flake8 fixes
aaronayres35 Aug 26, 2020
1189ddc
adding tests using QLabel object (nothing should happen when trying t…
aaronayres35 Aug 26, 2020
7ba111e
adding range_editor implementation, and readding get___object_registr…
aaronayres35 Aug 26, 2020
f4f2be2
start of refactor for located basic object handlers
aaronayres35 Aug 27, 2020
40ad90a
improving tests, and adding mouse click on TextEditors for wx
aaronayres35 Aug 27, 2020
705a820
making suggested changes
aaronayres35 Aug 27, 2020
405a030
flake8
aaronayres35 Aug 27, 2020
e2b082a
Merge branch 'ui-tester-api-updates3' into ui-tester-api-updates4
aaronayres35 Aug 27, 2020
a96fb0d
refactor for located textbox handler logic
aaronayres35 Aug 27, 2020
7577c81
fixing broken tests
aaronayres35 Aug 28, 2020
5e75d0a
Merge branch 'master' into ui-tester-api-updates4
aaronayres35 Aug 28, 2020
1a0a7a9
starting to fix wx tests
aaronayres35 Aug 28, 2020
a287c52
fixing broken wx tests
aaronayres35 Aug 28, 2020
7c595ca
flake8
aaronayres35 Aug 28, 2020
7847933
removing commented out old code
aaronayres35 Aug 28, 2020
991be83
missed a flake8
aaronayres35 Aug 28, 2020
f08e54f
deleted an old unneeded test
aaronayres35 Aug 28, 2020
ee863e5
adding docstrings and a function rename
aaronayres35 Aug 28, 2020
73a97d4
fixing typos and adding a few docstrings
aaronayres35 Aug 31, 2020
b806e3a
making suggested changes
aaronayres35 Sep 1, 2020
78a7bf0
handling '\b' characters on wx
aaronayres35 Sep 1, 2020
c03ef46
renaming located_object_handlers as common_ui_targets
aaronayres35 Sep 1, 2020
f8b4b9c
more suggested changes
aaronayres35 Sep 1, 2020
4f723e1
revert SetKeyCode change and remove '\b' in test
aaronayres35 Sep 1, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions traitsui/qt4/range_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,9 @@ def update_object_on_scroll(self, pos):
def update_object_on_enter(self):
""" Handles the user pressing the Enter key in the text field.
"""
# it is possible we get the event after the control has gone away
if self.control is None:
return
try:
self.value = eval(str(self.control.text.text()).strip())
except TraitError as excp:
Expand Down
9 changes: 9 additions & 0 deletions traitsui/testing/tester/locator.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
applied.
"""

import enum


class NestedUI:
""" A locator for locating a nested ``traitsui.ui.UI`` object assuming
Expand All @@ -35,3 +37,10 @@ class TargetByName:
"""
def __init__(self, name):
self.name = name


class WidgetType(enum.Enum):
""" An Enum of widget types.
"""

textbox = "textbox"
4 changes: 4 additions & 0 deletions traitsui/testing/tester/qt4/default_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from traitsui.testing.tester.registry import TargetRegistry
from traitsui.testing.tester.qt4.implementation import (
button_editor,
range_editor,
text_editor,
)

Expand All @@ -33,4 +34,7 @@ def get_default_registry():
# TextEditor
text_editor.register(registry)

# RangeEditor
range_editor.register(registry)

return registry
57 changes: 57 additions & 0 deletions traitsui/testing/tester/qt4/implementation/range_editor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Copyright (c) 2005-2020, Enthought, Inc.
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in LICENSE.txt and may be redistributed only
# under the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
#
# Thanks for using Enthought open source!
#

from traitsui.qt4.range_editor import (
LargeRangeSliderEditor,
LogRangeSliderEditor,
RangeTextEditor,
SimpleSliderEditor,
Comment on lines +13 to +16
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eventually we will want to add SimpleSpinEditor, but this can be done in a later PR.
For later reference: The SimpleSpinEditor class in Qt has a control that is a QtGui.QSpinBox object, which subclasses QtGui.AbstractSpinBox which has a lineEdit() method which returns the QLineEdit for the spin box (likely we would just need to resolve to this and then the other handlers should work). For wx however, the SimpleSpinEditor has a control of a wx.SpinCtrl, which is supposedly combines a wx.SpinCtrl and wx.TextCtrl in one. However, it doesn't seem to subclass wx.TextCtrl and doesn't appear to support the same methods, so our handlers for KeyClick, KeySequence, etc. may not work correctly.

SimpleSpinEditor,
)

from traitsui.testing.tester import locator
from traitsui.testing.tester.qt4.located_object_handlers import LocatedTextbox


class RangeEditorTextbox(LocatedTextbox):
pass


def resolve_location_simple_slider(wrapper, location):
if location == locator.WidgetType.textbox:
return RangeEditorTextbox(textbox=wrapper.target.control.text)

raise NotImplementedError()

def resolve_location_range_text(wrapper, location):
if location == locator.WidgetType.textbox:
return RangeEditorTextbox(textbox=wrapper.target.control)

raise NotImplementedError()

def register(registry):

targets = [SimpleSliderEditor,
LogRangeSliderEditor,
LargeRangeSliderEditor]
for target_class in targets:
registry.register_solver(
target_class=target_class,
locator_class=locator.WidgetType,
solver=resolve_location_simple_slider,
)

registry.register_solver(
target_class=RangeTextEditor,
locator_class=locator.WidgetType,
solver=resolve_location_range_text,
)
RangeEditorTextbox.register(registry)
35 changes: 35 additions & 0 deletions traitsui/testing/tester/qt4/located_object_handlers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Copyright (c) 2005-2020, Enthought, Inc.
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in LICENSE.txt and may be redistributed only
# under the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
#
# Thanks for using Enthought open source!
#

from traitsui.testing.tester import command, locator, query
from traitsui.testing.tester.qt4 import helpers

class LocatedTextbox:
def __init__(self, textbox):
self.textbox = textbox

@classmethod
def register(cls, registry):
handlers = [
(command.KeySequence, (lambda wrapper, interaction: helpers.key_sequence_qwidget(
wrapper.target.textbox, interaction, wrapper.delay))),
(command.KeyClick, (lambda wrapper, interaction: helpers.key_click_qwidget(
wrapper.target.textbox, interaction, wrapper.delay))),
(command.MouseClick, (lambda wrapper, _: helpers.mouse_click_qwidget(
wrapper.target.textbox, wrapper.delay))),
(query.DisplayedText, lambda wrapper, _: wrapper.target.textbox.displayText()),
]
for interaction_class, handler in handlers:
registry.register_handler(
target_class=cls,
interaction_class=interaction_class,
handler=handler,
)
4 changes: 4 additions & 0 deletions traitsui/testing/tester/wx/default_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from traitsui.testing.tester.registry import TargetRegistry
from traitsui.testing.tester.wx.implementation import (
button_editor,
range_editor,
text_editor,
)

Expand All @@ -33,4 +34,7 @@ def get_default_registry():
# TextEditor
text_editor.register(registry)

# RangeEditor
range_editor.register(registry)

return registry
54 changes: 54 additions & 0 deletions traitsui/testing/tester/wx/implementation/range_editor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Copyright (c) 2005-2020, Enthought, Inc.
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in LICENSE.txt and may be redistributed only
# under the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
#
# Thanks for using Enthought open source!
#
from traitsui.wx.range_editor import (
LargeRangeSliderEditor,
LogRangeSliderEditor,
RangeTextEditor,
SimpleSliderEditor,
SimpleSpinEditor,
)

from traitsui.testing.tester import locator
from traitsui.testing.tester.wx.located_object_handlers import LocatedTextbox

class RangeEditorTextbox(LocatedTextbox):
pass

def resolve_location_simple_slider(wrapper, location):
if location == locator.WidgetType.textbox:
return RangeEditorTextbox(textbox=wrapper.target.control.text)

raise NotImplementedError()

def resolve_location_range_text(wrapper, location):
if location == locator.WidgetType.textbox:
return RangeEditorTextbox(textbox=wrapper.target.control)

raise NotImplementedError()


def register(registry):

targets = [SimpleSliderEditor,
LogRangeSliderEditor,
LargeRangeSliderEditor]
for target_class in targets:
registry.register_solver(
target_class=target_class,
locator_class=locator.WidgetType,
solver=resolve_location_simple_slider,
)
registry.register_solver(
target_class=RangeTextEditor,
locator_class=locator.WidgetType,
solver=resolve_location_simple_slider,
)
RangeEditorTextbox.register(registry)
35 changes: 35 additions & 0 deletions traitsui/testing/tester/wx/located_object_handlers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Copyright (c) 2005-2020, Enthought, Inc.
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in LICENSE.txt and may be redistributed only
# under the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
#
# Thanks for using Enthought open source!
#

from traitsui.testing.tester import command, locator, query
from traitsui.testing.tester.wx import helpers

class LocatedTextbox:
def __init__(self, textbox):
self.textbox = textbox

@classmethod
def register(cls, registry):
handlers = [
(command.KeySequence, (lambda wrapper, interaction: helpers.key_sequence_text_ctrl(
wrapper.target.textbox, interaction, wrapper.delay))),
(command.KeyClick, (lambda wrapper, interaction: helpers.key_click_text_ctrl(
wrapper.target.textbox, interaction, wrapper.delay))),
(command.MouseClick, (lambda wrapper, _: helpers.mouse_click_object(
wrapper.target.textbox, wrapper.delay))),
(query.DisplayedText, lambda wrapper, _: wrapper.target.textbox.GetValue()),
]
for interaction_class, handler in handlers:
registry.register_handler(
target_class=cls,
interaction_class=interaction_class,
handler=handler,
)
62 changes: 58 additions & 4 deletions traitsui/tests/editors/test_range_editor.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import unittest

from traits.api import HasTraits, Int
from traitsui.api import RangeEditor, UItem, View
from traits.api import HasTraits, Int, Range
from traitsui.api import Item, RangeEditor, UItem, View
from traitsui.testing.tester import command, locator, query
from traitsui.testing.tester.ui_tester import UITester
from traitsui.tests._tools import (
create_ui,
requires_toolkit,
Expand All @@ -14,6 +16,8 @@ class RangeModel(HasTraits):

value = Int()

class RangeTrait(HasTraits):
value = Range(1, 12)

@requires_toolkit([ToolkitName.qt, ToolkitName.wx])
class TestRangeEditor(unittest.TestCase):
Expand All @@ -33,8 +37,8 @@ def check_range_enum_editor_format_func(self, style):
)
)

with reraise_exceptions(),\
create_ui(obj, dict(view=view)) as ui:
tester = UITester()
with tester.create_ui(obj, dict(view=view)) as ui:
editor = ui.get_editors("value")[0]

# No formatting - simple strings
Expand All @@ -49,3 +53,53 @@ def test_simple_editor_format_func(self):

def test_custom_editor_format_func(self):
self.check_range_enum_editor_format_func("custom")

@requires_toolkit([ToolkitName.qt])
def check_set_with_text(self, mode):
model = RangeModel()
view = View(Item("value", editor=RangeEditor(low=1, high=12, mode=mode)), buttons=["OK"])
tester = UITester()
with tester.create_ui(model, dict(view=view)) as ui:
number_field = tester.find_by_name(ui, "value")
text = number_field.locate(locator.WidgetType.textbox)
text.perform(command.KeySequence("\b\b\b\b\b4"))
text.perform(command.KeyClick("Enter"))
self.assertEqual(model.value, 4)

def test_simple_slider_editor_set_with_text(self):
return self.check_set_with_text(mode='slider')

def test_large_range_slider_editor_set_with_text(self):
return self.check_set_with_text(mode='xslider')

def test_log_range_slider_editor_set_with_text(self):
return self.check_set_with_text(mode='logslider')

def test_range_text_editor_set_with_text(self):
return self.check_set_with_text(mode='text')


# "Enter" is not currently working to set the value on wx.
@requires_toolkit([ToolkitName.wx])
def check_set_with_text_wx(self, mode):
model = RangeModel()
view = View(Item("value", editor=RangeEditor(low=1, high=12, mode=mode)), buttons=["OK"])
tester = UITester()
with tester.create_ui(model, dict(view=view)) as ui:
number_field = tester.find_by_name(ui, "value")
text = number_field.locate(locator.WidgetType.textbox)
text.perform(command.KeySequence("\b\b\b\b\b4"))
tester.find_by_name(ui, "OK").perform(command.MouseClick)
self.assertEqual(model.value, 4)

"""def test_simple_slider_editor_set_with_text_wx(self):
return self.check_set_with_text_wx(mode='slider')

def test_large_range_slider_editor_set_with_text(self):
return self.check_set_with_text(mode='xslider')

def test_log_range_slider_editor_set_with_text(self):
return self.check_set_with_text(mode='logslider')

def test_range_text_editor_set_with_text(self):
return self.check_set_with_text(mode='text')"""
20 changes: 17 additions & 3 deletions traitsui/tests/editors/test_range_editor_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
from traitsui.view import View
from traitsui.editors.range_editor import RangeEditor

from traitsui.testing.tester import command, locator, query
from traitsui.testing.tester.ui_tester import UITester
from traitsui.tests._tools import (
create_ui,
press_ok_button,
Expand Down Expand Up @@ -68,7 +70,18 @@ def test_wx_text_editing(self):
# (tests a bug where this fails with an AttributeError)

num = NumberWithRangeEditor()
with reraise_exceptions(), create_ui(num) as ui:
tester = UITester()
with tester.create_ui(num) as ui:
# the following is equivalent to setting the text in the text
# control, then pressing OK
text = tester.find_by_name(ui, "number").locate(locator.WidgetType.textbox)
text.perform(command.KeyClick("1"))
text.perform(command.KeyClick("Enter"))

# the number traits should be between 3 and 8
self.assertTrue(3 <= num.number <= 8)

""" with reraise_exceptions(), create_ui(num) as ui:

# the following is equivalent to setting the text in the text
# control, then pressing OK
Expand All @@ -77,7 +90,7 @@ def test_wx_text_editing(self):
textctrl.SetValue("1")

# the number traits should be between 3 and 8
self.assertTrue(3 <= num.number <= 8)
self.assertTrue(3 <= num.number <= 8) """

@requires_toolkit([ToolkitName.qt])
def test_avoid_slider_feedback(self):
Expand All @@ -86,7 +99,8 @@ def test_avoid_slider_feedback(self):
from pyface import qt

num = FloatWithRangeEditor()
with reraise_exceptions(), create_ui(num) as ui:
tester = UITester()
with tester.create_ui(num) as ui:

# the following is equivalent to setting the text in the text
# control, then pressing OK
Expand Down