Skip to content

Conversation

@nicoddemus
Copy link
Member

Added waitForWindowExposed for PyQt5.

Fixes #158

@coveralls
Copy link

coveralls commented Sep 16, 2016

Coverage Status

Coverage decreased (-1.8%) to 98.168% when pulling ace332e on nicoddemus:wait-window-params into dfbd99d on pytest-dev:master.

2 similar comments
@coveralls
Copy link

Coverage Status

Coverage decreased (-1.8%) to 98.168% when pulling ace332e on nicoddemus:wait-window-params into dfbd99d on pytest-dev:master.

@coveralls
Copy link

Coverage Status

Coverage decreased (-1.8%) to 98.168% when pulling ace332e on nicoddemus:wait-window-params into dfbd99d on pytest-dev:master.

@coveralls
Copy link

coveralls commented Sep 16, 2016

Coverage Status

Coverage remained the same at 100.0% when pulling 7289785 on nicoddemus:wait-window-params into dfbd99d on pytest-dev:master.

@nicoddemus
Copy link
Member Author

I plan to release 2.1 after this is merged.

@The-Compiler
Copy link
Member

The-Compiler commented Sep 16, 2016

I think we still have some things to consider here, ideally before releasing it as they're API changes - unsorted braindump as I don't have much time right now:

  • Probably should have qWaitForWindowActive too?
  • Why not make it raise on a timeout, with an optional raising=False? If we already have a Python wrapper with a (slightly) different name, let's make the API more pythonic and don't force the caller to check a return value, IMHO.
  • In the same vein, should it be a context manager? IMHO, this looks better:
with qtbot.waitForWindowExposed(window):
    window.show()
assert window.isVisible()

compared to:

window.show()
qtbot.waitForWindowExposed(window)
assert window.isVisible()

@nicoddemus
Copy link
Member Author

Good point about waitForWindowActive... I should also review if there are other additions to QTest that should go in.

I agree having a higher level API is nice, but perhaps we should add them as separate methods rather than changing the original functions? I would rather keep the original QTest functions "as is" instead of adding additional behavior; it might be a little surprising to users and makes converting C++ examples to Python easier (for example as we did in the qmodeltester fixture).

Following your example, how about those context managers then:

def waitExposed(self, widget, timeout=1000, raising=True):
    pass
def waitActive(self, widget, timeout=1000, raising=True):
    pass
def waitFocus(self, widget, timeout=1000, raising=True):
    pass

The last one in particular is tricky to achieve in my experience, specially when executing under pytest-xdist.

Also, I think those high-level APIs are only worthwhile doing for PyQt5... let's move forward only. 😁

@The-Compiler
Copy link
Member

FWIW we already change the function names by stripping the leading q 😉

I guess adding those would work. No big opinion on backends, I think nobody should use Qt4 nowadays anyways 😆

I also thought about having qtbot.waitForWindowActive(...) act as before, but the context manager form raising by default, but I guess that'd be kind of weird too.

@nicoddemus
Copy link
Member Author

OK! Thanks for coming back to this. 😁

I will see if I can tackle this during the week.

@nicoddemus
Copy link
Member Author

nicoddemus commented Oct 12, 2016

Hey @The-Compiler,

I implemented waitForWindowActive as we discussed.

After implementing the waitExposed and waitActive context managers as we discussed, I'm not sure they are any better than the actual functions.

Consider:

widget.show()
assert qtbot.waitForWindowExposed(widget, timeout)

vs:

with qtbot.waitExposed(widget, timeout):
    widget.show()

I feel we don't gain much and will bloat the API without compelling reason.

What do you think?

@coveralls
Copy link

coveralls commented Oct 12, 2016

Coverage Status

Coverage decreased (-2.08%) to 97.92% when pulling c93a69c on nicoddemus:wait-window-params into dfbd99d on pytest-dev:master.

@coveralls
Copy link

coveralls commented Oct 12, 2016

Coverage Status

Coverage decreased (-2.08%) to 97.92% when pulling 193fc3f on nicoddemus:wait-window-params into dfbd99d on pytest-dev:master.

1 similar comment
@coveralls
Copy link

Coverage Status

Coverage decreased (-2.08%) to 97.92% when pulling 193fc3f on nicoddemus:wait-window-params into dfbd99d on pytest-dev:master.

@The-Compiler
Copy link
Member

The desire for those two things is actually because I make those mistakes a lot. Accidentally using it as a context manager isn't that bad, accidentally thinking it'd be raising is 😉

The reason I make those mistakes over and over again is because the API is inconsistent - I can use other qtbot.wait* methods as a context manager and they'll raise when something is wrong, so I think it's a cognitive burden to have some wait* methods behave one way and some wait* methods behave differently.

FWIW, I think the cleanest design/API would be to have convenience wrappers as qtbot.wait*, and all the QTest methods as qtbot.qtest.* (or a separate qtest fixture even) - but I guess that's 3.0 material 😉

@nicoddemus
Copy link
Member Author

The reason I make those mistakes over and over again is because the API is inconsistent - I can use other qtbot.wait* methods as a context manager and they'll raise when something is wrong, so I think it's a cognitive burden to have some wait* methods behave one way and some wait* methods behave differently.

Hmm I see, I agree that those are all valid points.

Well, since we are talking about adding two news methods, waitForWindowExposed and waitForWindowActive, we might decide to not expose them directly and expose a version we find more user-friendly:

def waitActive(self, widget, timeout=1000):
    """
    Raises a TimeoutError if the widget does not show in timeout miliseconds. 
    Calls the QTest.qWaitForWindowActive.
    PyQt5 only.
    """

Similarly for waitExposed.

  1. We might think about adding a raising=True parameter, but I'm not sure it is a common need to ensure something is not being activated/exposed which is the only situation I can think of someone wanting to pass raising=False and observe the returned value, so I would rather avoid "bloating" the API. It is always simpler to add it later than having to deprecate/remove something.
  2. Perhaps those should be context managers, for consistency with the other wait-signal methods?

FWIW, I think the cleanest design/API would be to have convenience wrappers as qtbot.wait_, and all the QTest methods as qtbot.qtest._ (or a separate qtest fixture even)

I agree it is cleaner, but I'm not sure it is better because it is not as convenient to use. Forcing to use qtbot.qtest.mouseClick instead of qtbot.mouseClick doesn't seem like a good trade-off in this case. Plus it would break all test suites and would be a little annoying to fix. Don't know, I would have to think about it some more.

Thanks as always for the thoughtful feedback! 😉

@The-Compiler
Copy link
Member

I agree about all your points! I think they definitely should be context managers for consistency, and I agree we can just default to raising=True and not add raising until someone has a good reason why it's needed 😉

@nicoddemus nicoddemus changed the title Add waitForWindowExposed method Add waitExposed and waitActive methods to QtBot Oct 18, 2016
@coveralls
Copy link

coveralls commented Oct 18, 2016

Coverage Status

Coverage decreased (-2.6%) to 97.442% when pulling a8e461c on nicoddemus:wait-window-params into dfbd99d on pytest-dev:master.

@coveralls
Copy link

coveralls commented Oct 18, 2016

Coverage Status

Coverage decreased (-2.6%) to 97.449% when pulling 36c261d on nicoddemus:wait-window-params into dfbd99d on pytest-dev:master.

@coveralls
Copy link

coveralls commented Oct 18, 2016

Coverage Status

Coverage decreased (-2.6%) to 97.368% when pulling 0dccfcc on nicoddemus:wait-window-params into dfbd99d on pytest-dev:master.

@coveralls
Copy link

coveralls commented Oct 18, 2016

Coverage Status

Coverage decreased (-2.6%) to 97.368% when pulling 7d48707 on nicoddemus:wait-window-params into dfbd99d on pytest-dev:master.

@coveralls
Copy link

coveralls commented Oct 19, 2016

Coverage Status

Coverage decreased (-2.6%) to 97.368% when pulling a3bc31f on nicoddemus:wait-window-params into dfbd99d on pytest-dev:master.

@coveralls
Copy link

coveralls commented Oct 19, 2016

Coverage Status

Coverage remained the same at 100.0% when pulling 5de1611 on nicoddemus:wait-window-params into dfbd99d on pytest-dev:master.

1 similar comment
@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 5de1611 on nicoddemus:wait-window-params into dfbd99d on pytest-dev:master.

@coveralls
Copy link

coveralls commented Oct 19, 2016

Coverage Status

Coverage decreased (-0.08%) to 99.915% when pulling 502c290 on nicoddemus:wait-window-params into dfbd99d on pytest-dev:master.

@nicoddemus
Copy link
Member Author

@The-Compiler I know you are pretty buys, just a ping to let you know this is ready for reviewing. 😁

Copy link
Member

@The-Compiler The-Compiler left a comment

Choose a reason for hiding this comment

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

Some minor stuff, and a SignalTimeout API change which is probably more important 😉


def waitActive(self, widget, timeout=1000):
"""
Context manager that waits for timeout milliseconds or until the window is active.
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't the timeout be monospace?


def waitActive(self, widget, timeout=1000):
"""
Context manager that waits for timeout milliseconds or until the window is active.
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't the timeout be monospace?

show_action()
:param QWidget widget:
Widget to wait on.
Copy link
Member

Choose a reason for hiding this comment

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

on -> for?

Widget to wait on.
:param int|None timeout:
How many miliseconds to wait on.
Copy link
Member

Choose a reason for hiding this comment

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

miliseconds -> milliseconds; on -> for?


wait_active = waitActive # pep-8 alias

def waitExposed(self, widget, timeout=1000):
Copy link
Member

Choose a reason for hiding this comment

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

Same changes as above in this docstring 😉

.. note:: In Qt5, the actual method called is qWaitForWindowExposed,
but this name is kept for backward compatibility
.. note:: In ``PyQt5`` this function is considered deprecated in favor of :meth:`waitForWindowExposed`.
Copy link
Member

Choose a reason for hiding this comment

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

Should we mention waitExposed instead?



# provide easy access to SignalTimeoutError to qtbot fixtures
class TimeoutError(Exception):
Copy link
Member

Choose a reason for hiding this comment

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

What about inheriting from SignalTimeoutError (for backwards compatibility) and deprecating SignalTimeoutError, like discussed in #157 (comment) some while ago?

Copy link
Member Author

Choose a reason for hiding this comment

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

Done, well remembered! 😁

msg = 'widget {} not {} in {} ms.'.format(self._widget, self._adjective_name, self._timeout)
raise TimeoutError(msg)
finally:
self._widget = None
Copy link
Member

Choose a reason for hiding this comment

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

Is this to avoid leaking memory?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes!

@nicoddemus
Copy link
Member Author

I implemented all the changes you commented @The-Compiler!

@coveralls
Copy link

coveralls commented Oct 24, 2016

Coverage Status

Coverage remained the same at 100.0% when pulling 24702b7 on nicoddemus:wait-window-params into dfbd99d on pytest-dev:master.

@The-Compiler
Copy link
Member

Thanks! 👍

@The-Compiler The-Compiler merged commit 894a827 into pytest-dev:master Oct 25, 2016
@The-Compiler The-Compiler mentioned this pull request May 31, 2021
10 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants