Selenium python (webdrivers): how to handle cases with multiple interconnected windows - python

I am looking for a way to track an app built on multiple interconnected windows.
Basically I have webdriver running happily, and launch the application which open a window; I can access its elements and everything is fine.
But there is another part of the application, that open on its own, which cause the main view to close. It is still the same application, but the main window is destroyed and the new one is created.
This cause sadly the issue that webdriver can't find the context anymore (because rightfully so, the app to which it was attached, has been destroyed).
content shell came up empty, the driver is Chromedriver 2.23.40 on OSX
Is there a way to handle such case with Selenium python webdriver?

Selenium has a switch_to method to control switching the active window.
# Get window handles
windows = driver.window_handles
print("Number of window handles: {0}".format(len(windows))
print("Current window handle: {0}".format(driver.current_window_handle)
# Switch that most recently opened one
driver.switch_to.window(windows[-1])
print("New window handle: {0}".format(driver.current_window_handle)

Related

Interact with website without sending keystrokes to window (Python, Windows)?

Is it possible to interact with a webpage loaded into a web browser (such as Chrome) without the window being active and without sending keystrokes to it? For example, suppose I have SoundCloud loaded in chrome and the chrome window minimized, but I want to create a hotkey on my computer (such as through Autohotkey) which acts as a play/pause button for the track. Would it be possible to have a Python script somehow interact with the browser to obtain that functionality without having to send it a keystroke?
The reason I'm trying to avoid having to send keystrokes is because it would require the Window to become briefly maximized and active. I can already do this in autohotkey. For example, I have an ahk script that iterates over all the windows, finds one with Soundcloud in the title, maximizes the window if it is minimized, sends the spacebar keystroke (which acts as play/pause on Soundcloud), and then minimizes the Window again if it was minimized to begin with.
This has the undesirable effect of making the Window flash briefly if it was minimized, or if virtual desktops are used, all the Windows flash if the Chrome window with Soundcloud is located on another virtual desktop other than the active one.
Ideally I could just write some program that runs silently in the background to send some kind of the request to the site that has the same effect as pressing the play/pause button without having to use the janky keystroke method I suggested above. But I am not sure if this is possible. What is actually happening when I click the play/pause button on Soundcloud, and is there some way write a program to get Chrome to do that without using keystrokes?
Any suggestions? I would prefer to do this without any browser plugins if possible.

Python Selenium will stall if window is left in background

I have a setup where I create a Remote driver (with Chromedriver), go to a website, perform actions on it. I'm running the driver with headless=False, so Selenium creates a Chrome window.
When I have the Chrome window open and in foreground, everything works just fine.
When I have it reduced to icon, or even open but in background - so using other apps when Selenium is working -, then the driver can stall - but it will, like 80% of the times.
When this happens, I have to reopen the Chrome window and, if this fails to resume the execution, I have to go to the running script's terminal and press Enter - so send an event to the script -; usually this solves the stall, and the execution will continue.
I know that, when running with headless=True, this problem doesn't show up; however I cannot use it, since the website in question will change the page according to this setting, so my currently situation is running this script with this Chrome window in front of me.
The script execution will last from 5 to 10 minutes everytime it's runned, if this can may be related to the problem.
Is there anything I can do to mitigate, or even remove this problem at all?

How to use subprocess to run a program without a window showing?

I am using subprocess.call() to programatically launch a software on my PC (the Meta Trader platform for forex trading, to be exact). The call works fine, the terminal is launched properly, however I now want to improve the experience by removing the popping up Meta Trader window. I know that in web scraping it is possible to use a headless browser, enabling that scraping be done without an actual(ly visible) web browser window showing on the screen. I was wondering if there is some way to achieve the same functionality using subprocess.call() (or else).
There doesn't seem to be built-in support on other platforms, but it's possible on Windows by passing a STARTUPINFO instance to the Popen constructor.
The following example starts the Notepad editor in the background. Its window is hidden, but the program is running as the Task Manager would show. Pressing Ctrl+C stops the program and terminates the background process.
import subprocess
from time import sleep
process = subprocess.Popen(
'notepad',
startupinfo=subprocess.STARTUPINFO(
dwFlags=subprocess.STARTF_USESHOWWINDOW,
wShowWindow=subprocess.SW_HIDE,
),
)
try:
while process.poll() is None:
sleep(1)
except KeyboardInterrupt:
process.kill()
Note that this may not work for more complex applications that start their own subprocesses, such as the Chrome browser to name but one example. One may then have to go through the Windows API in order to hide the application windows after they were created.

Python3, Selenium, Chromedriver console window

I've a made a selenium test using python3 and selenium library.
I've also used Tkinter to make a GUI to put some input on (account, password..).
I've managed to hide the console window for python by saving to the .pyw extension; and when I make an executable with my code, the console doesn't show up even if it's saved with .py extension.
However, everytime the chromedriver starts, it also starts a console window, and when the driver exists, this window does not.
so in a loop, i'm left with many webdriver consoles.
Is there a work around this to prevent the driver from launching a console everytime it runs ?
I hated dealing with this in selenium until I remembered that this was an obvious use case for context managers just like the usage of open.
I did find out that selenium is about to add this officially to their package in this pull request
Until this is officially added, this snippet should give you the functionality you need to get things going :)
import contextlib
#contextlib.contextmanager
def Chrome(*args, **kwargs):
webdriver = webdriver.Chrome(*args, **kwargs)
try:
yield webdriver
finally:
webdriver.quit()
with Chrome() as driver:
# whatever you're planning on doing goes here
driver.close() and driver.quit() are two different methods for closing the browser session in Selenium WebDriver.
driver.close() - It closes the the browser window on which the focus is set.
driver.quit() – It basically calls driver.dispose method which in turn closes all the browser windows and ends the WebDriver session gracefully.
You should use driver.quit whenever you want to end the program. It will close all opened browser window and terminates the WebDriver session. If you do not use driver.quit at the end of program, WebDriver session will not close properly and files would not be cleared off memory. This may result in memory leak errors.

Pywinauto menu selection error - Wireshark

I am very new to windows automation.I am automating wireshark using autopy.Now i need to open a file wireshark.I dont have swapy tool.I also dot want to do it in pyshark.I just want to try only in pywinauto.so i tried this way:
from pywinauto import application
print("Starting the proogram")
app=application.Application()
app.start_(r"C:\Program Files\Wireshark\Wireshark.exe")
win = app.window_(title_re = ".*Wireshark Network Analyzer.*")
win.MenuSelect("File->Open")
But i get this below error :
pywinauto.findwindows.WindowNotFoundError
Kindly help me out here with this guys.Thanks in advance
As I can see WireShark is starting up several seconds. You need waiting main window longer than default timeout (5 sec.).
win.wait('ready', timeout=15)
"Software Update" window can also be handled if it pops up:
if app.SoftwareUpdate.exists(timeout=10):
app.SoftwareUpdate.SkipThisVersion.click()
app.SoftwareUpdate.wait_not('visible') # just to make sure it's closed
win.wait('ready', timeout=15)
EDIT (2019, Jan, 21): the latest version of WireShark is built on Qt5 and current pywinauto example is maintained in the repo: examples/wireshark.py.
(old part of the answer below)
But in any case pywinauto doesn't support GDK widgets (even Windows UI Automation API doesn't support GDK apps). Menu is not available to pywinauto or UIA-based tools. You can deal with WireShark using workarounds only like so:
win.type_keys('%F{ENTER}') # Alt+F, Enter (it calls "&File->&Open" menu)
app.WiresharkOpenCaptureFile.FilenameEdit.set_edit_text('I can set text here')
app.WiresharkOpenCaptureFile.Open.click()
app.WiresharkOpenCaptureFile.wait_not('visible')
"Open" dialog is standard variation of Windows Open/Save dialog and pywinauto supports many controls on it.
To check which dialog is supported well by pywinauto use print_control_identifiers() method:
win.print_control_identifiers() # prints nothing
app.WiresharkOpenCaptureFile.print_control_identifiers() # prints a lot of controls

Categories