0

I'm doing some desktop application testing using Winium with Python. For my application, I'm first confirming the progress bar appears on the windows with some other text. I'm then confirming the progress bar no longer exists before continuing forward.

running_app = driver.find_element_by_name("MyApp")
status_bar = running_app.find_element_by_id("statusStrip1")
status_bar.find_element_by_class_name("WindowsForms10.msctls_progress32.app.0.141b42a_r9_ad1")
status_bar.find_element_by_name("Loading Default Files...")

# Confirm Progress Bar disappears before continuing
WebDriverWait(driver, 60).until_not(
     expected_conditions.presence_of_element_located((eval("By.CLASS_NAME"), "WindowsForms10.msctls_progress32.app.0.141b42a_r9_ad1"))
)

The issue I'm having is with the portion of the code that's meant to verify the Progress Bar has disappeared before continuing on. That particular line takes too long to execute. After some investigation, I concluded this is happening because I'm only able to feed the component address into 'presence_of_element_located' as opposed to its full address, which would look something like...

driver.find_element_by_name("MyApp").find_element_by_id("statusStrip1").find_element_by_class_name("WindowsForms10.msctls_progress32.app.0.141b42a_r9_ad1")

Unfortunately, I have no way of breaking this down into an XPath and using that instead. To the best of my knowledge, I don't know of a way to retrieve the XPath of an object using this address either. I'd like to find either a way to make to either.. (1) Insert this absolute/full address into expected_conditions.presence_of_element_located() or find an alternate way to confirm the object no longer exists.

- 20190502 UPDATE -

So far the closest I've come to a solution is combining the ideas below:

WebDriverWait(driver, 15).until(
    expected_conditions.invisibility_of_element_located((eval("By.XPATH"), "//*[@name='MyApp']//*[@id='statusStrip1']//*[@class='WindowsForms10.msctls_progress32.app.0.141b42a_r9_ad1']"))
)

This does get me past confirming the Progress Bar has vanished so the test can continue. It also has the same timing issue as the wildcards mean the object has to be searched for first.

- 20190502 UPDATE (2) -

So, I had a bit of a breakthrough as to figuring out this puzzle. For using XPath, if I was doing Web UI testing, I can look at the XML code and see that it's a '//div', '//table', '//input', '//tspn', etc.. I've been using the UISpy tool to figure out the names of objects on my desktop application. As I was looking at it, I became curious about the labels in front of the object it's referencing.

enter image description here

From the Control View, I see 'MyApp' has the label 'Window' next to it. So I decided to use that to alter my XPath attempt to the following:

WebDriverWait(driver, 15).until(
    expected_conditions.invisibility_of_element_located((eval("By.XPATH"), "//window[@name='MyApp']//*[@id='statusStrip1']//*[@class='WindowsForms10.msctls_progress32.app.0.141b42a_r9_ad1']"))
)

Not only did that work, but it was a tiny bit faster than the previous tries. The problem is the next layer is labeled as 'Status Bar' and I'm not really sure how to represent that in XPath.

rwbyrd
  • 416
  • 5
  • 24
  • Have you tried a CSS selector? Something like `[name='MyApp'] #statusStrip1 .WindowsForms10.msctls_progress32.app.0.141b42a_r9_ad1`. It's probably going on fail on that last class name since it contains periods and period indicate class names. For an XPath you could try, `//*[@name='MyApp']//*[@id='statusStrip1']//*[@class='WindowsForms10.msctls_progress32.app.0.141b42a_r9_ad1']`. – JeffC Apr 30 '19 at 22:07
  • JeffC, thanks for your response! You were correct about the CSS selector failing. The XPath was a bit more successful but still had the same long pause even after the Progress Bar disappeared. I believe that to be due to the wildcard characters being used. I've noticed whenever wildcard characters are used, it causes a delay before the object is eventually selected. For example, "//*[@LocalizedControlType='item'])[26]" causes the same delay in action at later portion of my code, so at some point, I'll need to replace that with something more direct as well. – rwbyrd May 02 '19 at 18:47
  • Agreed... I only use `*` when I'm looking for more than one element type. If I know that it's a `DIV` then I always use `//div` and so on. – JeffC May 02 '19 at 19:34
  • Agreed. I actually had a bit of a breakthrough. If you get a chance, take a look & let me know if you have any insight. – rwbyrd May 02 '19 at 20:52
  • Have you tried replacing the other two wildcards (`//*`) with the actual elements? Was that any faster? – JeffC May 02 '19 at 21:50

1 Answers1

0

You can wait for the invisibility of the progress bar using explicit wait. It will only wait for the invisibility of the progress bar and no more.

You can try using the element:

WebDriverWait(driver, 10).until(EC.invisibility_of_element(progressbar))

here I've passed the web element to the condition. progressbar is the progress bar element.

Or you can pass the locator strategy and locator to the condition directly:

locator = (By.LOCATOR_STRATEGY, "locator")
WebDriverWait(driver, 10).until(EC.invisibility_of_element_located(locator))

here, in the locator you need to put your locator strategy and locator of the progress bar

to use waits you have to imports the following:

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
S Ahmed
  • 1,454
  • 1
  • 8
  • 14
  • S Ahmed, thanks for your reply. The issue with your method is my Progress Bar above isn't defined by just one locator strategy, but rather 3 strategies (NAME, ID, & CLASS_NAME). So if I use your method of defining the Progress Bar [i.e. progress_bar = driver.find_element_by_name("MyApp").find_element_by_id("statusStrip1").find_element_by_class_name("WindowsForms10.msctls_progress32.app.0.141b42a_r9_ad1"))] & then put it into your suggested condition, I receive the following error: TypeError: find_element() argument after * must be a sequence, not WebElement. – rwbyrd May 02 '19 at 19:31
  • Actually, I was meaning that whatever locator strategy works for your element. That includes xpath and css selectors also. What actually you have to do is use the wait for the invisibility of that element. And I fixed the typo. locator doesn't need to be preceded by another lcoator strategy for the second code. – S Ahmed May 02 '19 at 21:35