PyWinAuto - How do I check when a button control becomes visible? - python

I am writing UI Automation tests for a WPF application that has a button which only becomes enabled on the UI when certain conditions are met.
I've read through all the uia_controls wrappers available to use (https://pywinauto.readthedocs.io/en/latest/code/pywinauto.controls.uia_controls.html) and there doesn't seem to be one that will allow me to check whether a button control is enabled before clicking on it.
Please advise if pywinauto is able to check that a button is enabled before interacting with it.

Check the enabled property of the element_info.
https://pywinauto.readthedocs.io/en/latest/code/pywinauto.element_info.html#pywinauto.element_info.ElementInfo.enabled

There are few ways. The first one is calling .wait('visible', timeout=10) on WindowSpecification object. The second one is checking return result of method .is_visible() for the wrapper object. Of course, you should know the difference between WindowSpecification and wrapper (see the Getting Started Guide).
Also see chapter Waiting for Long Operations.
P.S. Using UIAElementInfo directly is not recommended as it is low level of the implementation hidden behind wrapper interface.

Related

Pywinauto waiting too long to do an action

I need help.
I'm doing a UI automation, and it works properly.
However, it waits for all controls get done, but for example, the textbox I want to send keys is activated.
Because of that, my automation is very slow, and I couldn't find any helpful information in module documentation.
Thank you all
I find out the solution. If you have the same problem, you should always search for controls, with child_window function.
If you use the bracket notation, pywiauto will search all controls from root window, and depending the application, it takes a long time.
However, using child window, you can filter by control type, title and automation id
Global timings for every operation can be changed in module pywinauto.timings:
https://pywinauto.readthedocs.io/en/latest/code/pywinauto.timings.html
But please be careful. Aggressive timings can make some actions unstable.

Key binding for window/app in python Gtk+ 3 without menu items, UI manager, etc

I'm trying to use GTK3 and Cairo from Python for a minimal plotting application where the on-screen display of Cairo's output is for user convenience.
The typical usage is that I run a command, a plot pops up on screen and is also written to file, and I want to be able to dismiss the window as quickly as possible, ideally just a "q" keypress but also the common Ctrl-W and Ctrl-Q in addition to the default Alt-F4 (does anyone really use that regularly?!?).
I also want as little UI clutter in the window as possible: ideally just the standard window surround, no menus, toolbars, etc.
So... how can I bind my "q", "Ctrl-Q", etc. keybindings to Gtk.main_quit without having to a) create a cluttersome drop-down menu bar and b) go though the heavyweight Gtk.UIManager focused on by the Python Gtk+ 3 documentation here: http://python-gtk-3-tutorial.readthedocs.org/en/latest/menus.html . I hope this is possible, and doesn't require a lot of code (at least not as much as to set up all the menus!), but I can't find an example anywhere online: maybe I'm just searching for the wrong terms, being a GTK newbie.
Unfortunately there doesn't seem to be any documentation on making such a minimal accelerator setup, and the code to configure accelerator keys seems to differ a great deal between GTK2 and 3... thanks for helping.
Connect a signal to your main frame Win.connect('key-press-event', self.on_key_function) and in on_key_function (self, widget, event) check the value of event.keyval. For ESC is 65307 if you like hardcoded. Also, for key combinations, event.state report shift, alt(meta), and so on: if Gdk.ModifierType.CONTROL_MASK & event.state:do_something if ctrl is pressed
You could have separate stataments for left-ctrl, right-alt; be sure not to try to capture predefined key combinations, thay may be consumed by window manager.
A IDE with a good introspection will help you a lot, just write Gdk (previously imported) and autocompletion will popup a lot of functions/clases, most of them with a self-explanatory name.
Don't use key-press-event and keyval, it won't work for users with non-Latin keyboard layouts. GTK+ does a great job internally to match keyvals to hardware keys, this functionality is exposed via accelerators (often shortened as accel in the API) and bindings.

wxPython - Disable a whole menu

I have come across a problem while using wxPython lately: I want to grey out a whole wx.Menu and I can't find a way to do it. I could disable all the wx.MenuItem instances related to the wx.Menu, but I find it less efficient ergonomically speaking than greying out the menu itself.
The wx.Menu class has a method named Enable() which accepts the 'enable' argument, but its solely use is to enable/disable a related wx.MenuItem and not the wx.Menu itself. Actually, I'm not even sure that what I want can be done.
However, I would be glad to listen to your solutions if you have some.
Enable is just for the menu items. EnableTop should counter-intuitively disable the entire menu. See my old tutorial on menus about half-way down for more info. Here's how I did it:
self.menuBar.EnableTop(0, False)
Note that it's zero-based, so zero is the first menu, one is the second, etc.

How to handle button states efficiently in Tkinter

I've done a few searches but I couldn't find anything about this topic. Perhaps because it is common programmer knowledge (I'm not a programmer, I've learned from necessity), or because I'm going about it the wrong way.
I would like ideas/suggestions on how to manage button states for a GUI. For example, if I have a program which allows the user to import and process data, then certain functions should be inaccessible until the data has been imported successfully, or if they want to graph certain data, they need to select which data to graph before hitting the 'graph' or 'export' button. Even in the simple programs I've built these relationships seems to get complicated quickly. It seems simple to say "User shouldn't be able to hit button 'A' until 'B' and 'C' have been completed, then 'A' should be disabled if button 'D' or the 'Cancel' button. But that's a lot to track for one button. Thus far, I've tried two things:
Changing/Checking button states in the callback functions for the button. So in the above example, I would have code in buttons B's and C's callback to check if A should be enabled. And in buttons D's and Cancel's callbacks I would have code to disable button A. This gets complicated quickly and is difficult to maintain as code changes.
Setting boolean variables in every buttons callback (or just checking the states later using cget()) and checking the variables in a polling function to determine which buttons should be enabled or disabled.
I'm just not sure about this. I would like to make code as short and easy to understand as possible (and easy to edit later), but I don't like the idea of polling all the button states every few hundred milliseconds just for button 'management'. You can extend the same idea to check boxes, menu items, etc... but I'd like to here what others have done and why they do it the way they do.
You are only changing button states based on events, right? There is no reason to 'poll' to see if a button state has changed. What you can do is build a function which does all of the calling for you, then call it with something like disable_buttons([okButton, graphButton, printButton]). When an event takes place that modifies the appropriate user interface options (such as importing data), have another function that turns them on: enable_buttons([graphButton]). You could do this with each object's methods, of course, but making a wrapper allows you to be consistent throughout your application.

How to make PowerBuilder UI testing application?

I'm not familiar with PowerBuilder but I have a task to create Automatic UI Test Application for PB. We've decided to do it in Python with pywinauto and iaccesible libraries. The problem is that some UI elements like newly added lists record can not be accesed from it (even inspect32 can't get it).
Any ideas how to reach this elements and make them testable?
I'm experimenting with code for a tool for automating PowerBuilder-based GUIs as well. From what I can see, your best bet would be to use the PowerBuilder Native Interface (PBNI), and call PowerScript code from within your NVO.
If you like, feel free to send me an email (see my profile for my email address), I'd be interested in exchanging ideas about how to do this.
I didn't use PowerBuilder for a while but I guess that the problem that you are trying to solve is similar to the one I am trying to address for people making projects with SCADA systems like Wonderware Intouch.
The problem with such an application is that there is no API to get or set the value of a control. So a pywinauto approach can't work.
I've made a small tool to simulate the user events and to get the results from a screencapture. I am usig PIL and pytesser ORM for the analysis of the screen captures. It is not the easiest way but it works OK.
The tool is open-source and free of charge and can be downloaded from my website (Sorry in french). You just need an account but it's free as well. Just ask.
If you can read french, here is one article about testing Intouch-based applications
Sorry for the self promotion, but I was facing a similar problem with no solution so I've written my own. Anyway, that's free and open-source...
I've seen in AutomatedQa support that they a recipe recommending using msaa and setting some properties on the controls. I do not know if it works.
If you are testing DataWindows (the class is pbdwxxx, e.g. pbdw110) you will have to use a combination of clicking at specific coordinates and sending Tab keys to get to the control you want. Of course you can also send up and down arrow keys to move among rows. The easiest thing to do is to start with a normal control like an SLE and tab into the DataWindow. The problem is that the DataWindow is essentially just an image. There is no control for a given field until you move the focus there by clicking or tabbing. I've also found that the DataWindow's iAccessible interface is a bit strange. If you ask the DataWindow for the object with focus, you don't get the right answer. If you enumerate through all of the children you can find the one that has focus. If you can modify the source I also advise that you set AccessibleName for your DataWindow controls, otherwise you probably won't be able to identify the controls except by position (by DataWindow controls I mean the ones inside the DataWindow, not the DataWindow itself). If it's an MDI application, you may also find it useful to locate the MicroHelp window (class fnhelpxxx, e.g. fnhelp110, find from the main application window) to help determine your current context.
Edited to add:
Sikuli looks very promising for testing PowerBuilder. It works by recognizing objects on the screen from a saved fragment of screenshot. That is, you take a screenshot of the part of the screen you want it to find.

Categories