Unable to click on tree element through pywinauto - pywin32

I'm unable to click on tree view, please see snap:
For this I am using this code
evidence_treeview = context.new_evidence_window[u'TreeView']
time.sleep(2)
evidence_treeview.get_item([u'Evidence'], False).click()

It's not clear what is context variable? Is it WindowSpecification object? If yes, this is incorrect for "win32" backend, because it doesn't support more than 2 levels of window specifications (you requested 3 levels). By the way UIA backend supports 3+ levels, but TreeViewWrapper has different implementation there.
I suspect this code should work (but I'n not 100% sure without previous lines):
evidence_treeview = context[u'TreeView']
time.sleep(2)
evidence_treeview.get_item([u'Evidence'], False).click()

Related

pywinuto - click_input() function clicks on random node of tree view

I'm trying to automate the mmc (snap in console) type desktop app. Where I need to expand the tree.
Try 1 -
But when I do use expand() function it generates error popup which says that "the child nodes does not exists". After this script simply stops with no error message on console unless ok button is clicked on error popup. This I suspect because when tree node expanded it triggers some event which brings child nodes under it and somehow pywinauto is not getting Childs of this node. Please note that this error popup does not come up when the step is done manually.
Try 2 -
When I tried with select() then too same behavior observed as above. It generated same error popup.
Try 3 -
I tried click() and click_input() functions and it clicks on random tree node but not on the tree node on which it is called.
The all above trials are of my application which is not public.
For reproducing this issue I have tried it on common application available on windows OS. And we can see that the 3rd is still reproducible.
Reference code -
import time
from pywinauto.application import Application
from pywinauto import Desktop
app = Application().start(r'cmd.exe /c "C:\Windows\system32\perfmon.msc"', wait_for_idle=False)
app = Application(backend="win32").connect(title='Performance Monitor', timeout=10)
main_wind = app.window(best_match='MMCMainFrame', top_level_only=False)
console_wind = main_wind.child_window(best_match="MDIClients").child_window(best_match='MMCChildFrm').child_window(class_name="MMCViewWindow")
tree = console_wind.TreeView # print_control_identifiers()
children = tree.get_item(["Performance","Data Collector Sets"]).expand().get_child("System").expand().get_child('System Diagnostics')
print(children.text())
# below line will select the System Diagnostics
children.select()
time.sleep(4)
# Below line should click on System Diagnostics but it does NOT and same happens for click() function
children.click_input()
Any help will be really helpful in knowing why this click() and click_input() clicks on random tree node and Why expand() and select() method generates the non functional error popup?
Please mention if there is concrete workaround to this.
versions -
Windows OS 10, build 20H2
Python 3.10.4
comtypes 1.1.11
pip 22.0.4
pywin32 303
pywinauto 0.6.8
setuptools 61.2.0
six 1.16.0
wheel 0.37.1
TIA..
I have referenced some stack overflow and github issue tracker as for this problem as below but nothing works.
Treeview problem
select() for TreeView items (and similar) leads error if this selection calls other dialogs etc
Python: Click by coordinate inside a window
This was all because of incorrect backend API used for snap in control application. Unfortunately my POC I did on win32 API where it worked because I was doing some initial steps manually hence the problem I was facing(explained in try1) was not there and everything was working perfectly fine.
As soon as I switched the backend to UIA it gave me different identifiers for the controls that I used previously. Now I used this identifiers and started using UIA documentation and everything started working smoothly.
Also in my investigation there is no proper way to identify the backend API for the desktop application unless you try both and figure out which works for you.
Suggestion to readers - If you are using win32 API as backend there are different api methods available for that in the documentation. and for UIA backend different. read documentation carefully.
You can try the uispy tool and find that perfmon.msc can be automated with uia

How to get SMAC3 working for Python 3x on Windows

This is a great package for Bayesian optimization of hyperparameters (especially mixed integer/continuous/categorical...and has shown to be better than Spearmint in benchmarks). However, clearly it is meant for Linux. What do I do...?
First you need to download swig.exe (the whole package) and unzip it. Then drop it somewhere and add the folder to path so that the installer for SMAC3 can call swig.exe.
Next, the Resource module is going to cause issues because that is only meant for Linux. That is specifically used by Pynisher. You'll need to comment out import pynisher in the execute_func.py module. Then, set use_pynisher:bool=False in the def __init__(self...) in the same module. The default is true.
Then, go down to the middle of the module where an if self.use_pynisher....else statement exists. Obviously our code now enters the else part, but it is not setup correctly. Change result = self.ta(config, **obj_kwargs) to result = self.ta(list(config.get_dictionary().values())). This part may need to be adjusted yet depending on what kind of inputs your function handles, but essentially you can see that this will enable the basic example shown in the included branin_fmin.py module. If doing the random forest example, don't change at all...etc.

NodeJS with Selenium-webdriver : Click on coordinates (x,y) properly

I am currently using chrome-webdriver with selenium-webdriver in NodeJS.
I instantiate the chrome browser with NodeJS, and use selenium-webdriver asynchronously to interact with it's elements
Currently, as my example: I am trying to click on the canvass on this site
however as noted on this question, selenium does not allow that.
there are other posted solutions but are for Java or C#. I have tried looking for the equivalent of the "Actions" library in JAVA or the "ActionChains" in python but failed.
I am trying to do this without Helium, as the challenge is to use open source.
currently I have a hold of the element below (I assume we get a hold of the div instad of the canvass... but I might be mistaken)
element = await driver.findElement(By.id("aww-container"));
however, I have tried the following with failed solutions
.clickAt(x, y) (returns error "clickAt() is not a function")
driver.elementFromPoint(x,y) (also returns error "clickAt() is not a function"
document.elementFromPoint (fails because I am executing javascript from nodejs.. not from the browser.)
Is there a way for my current setup to click on an element via the x and y coordinates asynchronously with my setup? I do not mind adding another library as long as it is open source.

How can I write unit tests against code that uses QDesktopServices openUrl?

I'm working on a python (3.5) program that use a PyQt5 GUI. In the GUI, I need to add some help links to the documentation on a website. I manage to make it work with:
QDesktopServices.openUrl(QUrl("my_url"))
It works fine but I want to be sure that it will always be the case.
A quick and dirty unittest is to call the function and simply notice that there is no error. I would like to make a test that will check that the correct website page did show up. What should I use?
Checking for an error is not going to work at all, because Qt itself never raises errors (of course, Python or PyQt might do, but for completely unrelated reasons). The best you can do is check the return value of openUrl, which will simply return True or False depending on whether it was "successful". But note the following from the Qt docs for openUrl:
Warning: A return value of true indicates that the application has
successfully requested the operating system to open the URL in an
external application. The external application may still fail to
launch or fail to open the requested URL. This result will not be
reported back to the application.
If you want more control, I suggest you use Python's webbrowser module instead. This would, for example, allow you to register your own mock-browser class for the purposes of testing. The webbrowser module is written in pure Python and the code is quite straightforward.

Overriding PromptService in newer XULRunner

Our application uses embedded xulrunner. We override the default PromptService to provide custom dialogs for alert, prompt, etc by
componentRegistrar.RegisterFactory (PROMPTSERVICE_CID, aClassName, aContractID, MyPromptServiceFactory);
where,
PROMPTSERVICE_CID is "a2112d6a-0e28-421f-b46a-25c0b308cbd0"
CONTRACT_ID is "#mozilla.org/embedcomp/prompt-service;1"
When using XULRunner 1.9.* versions, this works perfectly and the call comes to MyPromptSerivceFactory. But, this doesn't work on newer XULRunner versions (>= 4.0)
I have modified the PROMPTSERVICE_CID to "7ad1b327-6dfa-46ec-9234-f2a620ea7e00" (copied from nsPrompter.manifest). While registering the factory I get the error NS_ERROR_FACTORY_EXISTS.
If I continue to use the old PROMPTSERVICE_CID, then nsIPromptService2 is not used instead nsIWindowCreator2.CreateChromeWindow2 is used to display alerts and prompts.
I have googled on this, but I couldn't find a solution to either fix the NS_ERROR_FACTORY_EXISTS error or for MyPromptServiceFactory to be used.
Any help/suggestions?
It would probably be better to use the existing prompt service the way Firefox does it rather than replace it. If you look at nsPrompter.openPrompt(), before opening a modal dialog it will try to locate and call a JavaScript function getTabModalPrompt() in the window containing the browser. It expects to get a promptBox element back and will call methods appendPrompt() and removePrompt() on it. Obviously, you don't have to give it a promptBox element, just something that behaves similarly - and displays a message any way you like.
But if you really want to replace system components, you shouldn't duplicate prompter's CID - use your own one but #mozilla.org/prompter;1 as contract ID (the old contract ID is for backwards compatibility only).

Resources