microsoft / WinAppDriver

Windows Application Driver
MIT License
3.69k stars 1.4k forks source link

Using FindElementsByXPath is causing the Application Under Test to Leak Memory and Crash #547

Open rm185033 opened 5 years ago

rm185033 commented 5 years ago

Hello All,

I have been using the Winappdriver framework to automate a Desktop application (which is very similar to how an ATM application would work). This application is a Windows Desktop application with a browser object embedded inside it and it renders HTML pages.

I create a Session with this specific application (lets call it app) and use FindElementsByXPath on this app to look for a specific text in the HTML page. So far good. However calling FindElementsByXPath repeatedly over time is bloating the size of this app and eventually crashes.

I have run this desktop app manually (for the same number of runs as i run in automode), but the memory stays just fine. Using the FindElementsByXPath dramatically increases the various Memory counters (working set here) per transaction leading to a huge bloat.

I am on Windows build 1703.

Is this a known issue with FindElementsByXPath call? have others seen something similar? Does the Winappdriver listener (server), inject any DLLs into the application under test and it thus responsible for increasing the memory consumption?

thank you Ramesh

hassanuz commented 5 years ago

Hi @rm185033,

This sounds like a bug with the application itself as WinAppDriver does not inject external content into the targeted app itself.

Would it be possible for you to share the application in question for us to repro + XPath + and WinAppDriver.exe logs?

Thanks

rm185033 commented 5 years ago

Thank you @hassanuz. I may not be able to share the application with you, but i will definitely share the winappdriver logs soon.

Here are a few observations, i run this application "manually" and then automate the same for the same number of iterations. I repeatedly see that the application workset (and private bytes) show drastic increase in memory in the automation mode. This does not ever happen when i manually run the same application for the same iterations.

As an aside, May i ask you the behavior of the following line of code, if it is run repeatedly (For me this is the suspect...)

while (TRUE) { anElement = appSession.FindElementsByXPath($"//Text[starts-with(@Name, \"{SomeCONSTText}\")]"); Console.WriteLine(anElement.ToString()); Thread.Sleep(someSaneAmountOfTime) ; // so that this loop doesn't really thrash or overwhelm this thread }

Does this repeated "automated walk through" the element sub-tree of the GUI app, cause any leaks in the WPF of target app ? I unerstand FindElementbyXPath uses UIA...in which case, do you see any memory leak issues during the "cross process calls" done by UIA during this search...

I cannot call close on this app's session on a per-loop basis as it closes the application,which is not the desired behavior.

thank you.

hassanuz commented 5 years ago

Hi @rm185033,

Can you try switching away from FindElementsByXpath to something else (like Name, ClassName, or Accessibility ID), and if that is the case see if the memory continues to increase?

rm185033 commented 5 years ago

Thank you for the suggestion. I can try that, however, i must say that FindElementsByXpath is the most suitable API call (among all other ways) to retrieve the element i am looking for. Using others will at best be a compromise. However can you let me know if FindElementsByXpath is by any chance a suspect for Memory leak issues? thank you.

m33x commented 5 years ago

After running a long lasting job (the scripts runs over one week) I noticed a significant memory leak. After killing the WinAppDriver.exe and rebooting Windows 1903 everything is back to normal. I'm using find_element_by_name because element_to_be_clickable is way too slow:

element = WebDriverWait(self.driver, self.delay).until(EC.element_to_be_clickable((By.XPATH, myxpath)))

so I replaced it with that:

def search_element(self, element_name):
    attempts = 0
    while True:
        try:
            return self.driver.find_element_by_name(element_name)
        except:
            attempts += 1
            if attempts % 10 == 0:
                now = datetime.datetime.now()
                print(now.strftime("%Y-%m-%d %H:%M:%S"), "Searching for '", element_name, "' this is attempt:", attempts)
            time.sleep(0.1)

because it is way faster.

memleak

After killing WinAppDriver.exe

killing

ashkaps commented 4 years ago

@hassanuz we are also experiencing the same issue with our app. Subsequent "driver" operations keeps increasing memory usage. Was a fix was ever identified for this?