Search code examples
pythonfirefoxautomated-testspywinauto

Pywinauto Not Entering Address into Mozilla Address bar


app = pywinauto.Application(backend="win32").start("C:\\Program Files\\Mozilla Firefox\\firefox.exe")
app = pywinauto.Application(backend="win32").connect(title_re='.*Mozilla Firefox', timeout=5)
dlg_spec = app.window(title="Mozilla Firefox", class_name="MozillaWindowClass")
#dlg_spec.print_control_identifiers()
child_window = dlg_spec.child_window(class_name="MozillaCompositorWindowClass")
address_bar = child_window.child_window(control_type='Edit', class_name='Edit')
address_bar.set_edit_text("https://google.com")

The above script launches Mozilla Firefox window and then throws the following runtime error after about 5-10 seconds:

pywinauto.timings.TimeoutError: 

During handling of the above exception, another exception occurred:

  <script_path> line 61, in <module>
    address_bar.set_edit_text("https://google.com")
    ^^^^^^^^^^^^^^^^^^^^^^^^^
pywinauto.findwindows.ElementNotFoundError: {'control_type': 'Edit', 'class_name': 'Edit', 'top_level_only': False, 'parent': <win32_element_info.HwndElementInfo - '', MozillaCompositorWindowClass, 6883088>, 'backend': 'win32'}

The following commented out code shows seems to show my control identifiers are correct. Running #dlg_spec.print_control_identifiers() produces:

MozillaWindowClass - 'Mozilla Firefox' (L-1928, T-8, R8, B1040) ['MozillaWindowClass', 'Mozilla FirefoxMozillaWindowClass', 'Mozilla Firefox'] child_window(title="Mozilla Firefox", class_name="MozillaWindowClass") | | MozillaCompositorWindowClass - '' (L-1920, T0, R0, B1032) | ['MozillaCompositorWindowClass'] | child_window(class_name="MozillaCompositorWindowClass")

Expected Result: I am expecting the launched instance of Firefox to navigate to designated URL.

Things I have tried: time.sleep for a few seconds thinking maybe address bar attempted to be accessed before loading in. Tried Type_keys or a method very similar to that in place of set_edit_text. And several other things.

I'm not sure what is happening. Any help would be greatly appreciated


Solution

  • If you are okay to automate that using keyboard shortcuts, you can just send a Ctrl + L, paste/type in your address and then just send an Enter to navigate to your url.

    using pywinauto.keyboard.send_keys():

    import pywinauto as pwa
    
    # start firefox
    app = pwa.Application(backend="win32").start("C:\\Program Files\\Mozilla Firefox\\firefox.exe")
    # wait for it to start (we can also use time.sleep(5) here if waiting everytime is not a problem)
    app = pywinauto.Application(backend="win32").connect(title_re='.*Mozilla Firefox', timeout=5)
    # set address bar as active using Ctrl + L, type our url then press Enter
    pwa.keyboard.send_keys('^l{BACKSPACE}https://google.com{ENTER}')
    

    If you want to use pywinauto's window specification methods to automate, I would suggest you first try to make sure that the "win32" backend you've used is indeed the right one to use for your use case. Also if you are new to pywinauto I'd suggest to take a look at Magic Attributes.

    using window specification methods and "uia" backend:

    import pywinauto as pwa
    from time import sleep
    
    firefox = pwa.Application(backend="win32").start("C:\\Program Files\\Mozilla Firefox\\firefox.exe")
    sleep(5)
    firefox = pwa.Application(backend="uia").connect(title_re='.*Mozilla Firefox', timeout=5)
    # firefox.print_control_identifiers(depth=4)
    # NOTE: The magic attribute lookup is very slow, could take even 30 secs
    address_bar = firefox.Mozilla_Firefox.Navigation.ComboBox.Edit
    address_bar.set_edit_text('https://google.com')