capabilities = new DesiredCapabilities();
capabilities.setCapability("app", "C:\\Program Files (x86)\\Microsoft Office\\Office15\\OUTLOOK.exe");
windowDriver = new WindowsDriver<WebElement>(new URL("http://127.0.0.1:4723"), capabilities);
windowDriver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);
Thread.sleep(1000*10);
Set<String> set=windowDriver.getWindowHandles();
org.openqa.selenium.WebDriverException: Build info: version: '3.3.1', revision: '5234b325d5', time: '2017-03-10 09:10:29 +0000'
System info: host: 'NDE-58717135', ip: '10.187.67.237', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_201'
Driver info: io.appium.java_client.windows.WindowsDriver
Capabilities [{app=C:\Program Files (x86)\Microsoft Office\Office15\OUTLOOK.exe, platformName=Windows, platform=ANY}]
Session ID: 7068CCCF-836B-4F49-B6D0-47AF58CBF4AD
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:216)
at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:168)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:638)
at io.appium.java_client.DefaultGenericMobileDriver.execute(DefaultGenericMobileDriver.java:46)
at io.appium.java_client.AppiumDriver.execute(AppiumDriver.java:1)
at io.appium.java_client.windows.WindowsDriver.execute(WindowsDriver.java:1)
at org.openqa.selenium.remote.RemoteWebDriver.getWindowHandles(RemoteWebDriver.java:509)
at com.bcg.outlook.testcases.OutlookDesktop.outlookDesktop(OutlookDesktop.java:53)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:580)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:716)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:988)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.privateRun(TestRunner.java:648)
at org.testng.TestRunner.run(TestRunner.java:505)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
at org.testng.SuiteRunner.run(SuiteRunner.java:364)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
at org.testng.TestNG.runSuites(TestNG.java:1049)
at org.testng.TestNG.run(TestNG.java:1017)
at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:114)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)
Hello,
I have faced a similar issue with applications that have a splash screen. After the splash is closed the window the session was attached to does not exist anymore and therefore no more actions can be taken. The most reliable solution was to start a total of 3 sessions to handle the splash screen.
Look here for the example: https://github.com/Microsoft/WinAppDriver/issues/392#issuecomment-412728379
@Bulbul1234 This works for me. I have a splash screen and a log-in. But, here is the code for the splash screen.
public static void StartApplication()
{
if (session == null)
{
DesiredCapabilities appCapabilities = new DesiredCapabilities();
appCapabilities.SetCapability("app", "MyApp.exe");
appCapabilities.SetCapability("newCommandTimeout", "100");
appCapabilities.SetCapability("platformName", "Windows");
appCapabilities.SetCapability("deviceName", "WindowsPC");
session = new WindowsDriver<WindowsElement>(new Uri(WindowsApplicationDriverUrl), appCapabilities);
Assert.IsNotNull(session);
string splash = $"{session.CurrentWindowHandle}";
WebDriverWait wait = new WebDriverWait(session, new TimeSpan(0, 0, 15));
wait.Until(drv => drv.WindowHandles[0] != splash);
session.SwitchTo().Window(session.WindowHandles[0]);
System.Collections.ObjectModel.ReadOnlyCollection<string> allWindowHandles = session.WindowHandles;
}
}
Hi @Bulbul1234,
Thank you for bringing it up. @Kamilbrd is exactly right that the session no longer took an operation once the splash screen was dismissed. In addition, @liljohnak's solution is indeed clever even though it still has a chance to hit the same error you saw.
I understand that it would be much more convenient and elegant to be able to enumerate all top level application window with the same process Id after the main window is dismissed. I am working on making this improvement in GetWindowHandles soon. Please stay tune and thank you everyone for the great feedback and suggestion.
Hi @Bulbul1234, @Kamilbrd, and @liljohnak,
Thank you for bringing this issue up which helped making WinAppDriver better. The v1.1.1 GetWindowHandles endpoint will now continue to work even when the current application window is closed/destroyed. This will allow you to enumerate through all application top level windows with the same processId until the session is terminated. Would you please give it a try?
Having the same problem with Outlook. I have installed WinAppDriver 1.1.1 but I am using the AppiumLibrary in RobotFramework to do the automation.
Basically I want to launch Outlook and click on the File Menu. That is all I am trying to do...
Here is my sample code from RobotFramework:
*** Settings ***
Library AppiumLibrary timeout=30
Test Setup Open Application ${REMOTE_URL} platformName=Windows deviceName=WindowsPC app=${APP}
Test Teardown Close Application
*** Variables ***
${REMOTE_URL} http://localhost:4723
${APP} C:\\Program${SPACE}Files\\Microsoft${SPACE}Office\\root\\Office16\\Outlook.exe
*** Test Cases ***
Open Outlook
Click Element accessibility_id=FileTabButton
I am getting the following error from WinAppDriver:
==========================================
POST /session/E2E05584-B751-4CEC-BEE8-50C7A6813B13/elements HTTP/1.1
Accept: application/json
Accept-Encoding: identity
Content-Length: 108
Content-Type: application/json;charset=UTF-8
Host: 127.0.0.1:4723
User-Agent: appium/python 0.38 (selenium/3.141.0 (python windows))
{"using": "accessibility id", "value": "FileTabButton", "sessionId": "E2E05584-B751-4CEC-BEE8-50C7A6813B13"}
HTTP/1.1 400 Bad Request
Content-Length: 102
Content-Type: application/json
{"status":23,"value":{"error":"no such window","message":"Currently selected window has been closed"}}
Apologies for the delay, I've just implemented v1.1.1 and can confirm it works as intended, the workaround with multiple driver sessions is no longer required. Thank you for the support.
@YouWhy
What I think you are doing above is trying to find the element in the splash screen window and that has been closed. You still have to switch windows and make sure it's the correct one in case the splash screen is slow to disappear.
Here's a bit of code that should help you get the idea:
for (int attempt = 0; attempt < 5; attempt++)
{
var WindowHandles = _driver.WindowHandles;
try
{
_driver.SwitchTo().Window(WindowHandles[0]);
if (_driver.FindElementByName(<outlook_main_window_name>).Displayed)
{
break;
}
}
catch (Exception) { }
}
return _driver;
@Kamilbrd Thanks for your support. On another thread, I got my answer. I needed to create a DESKTOP session and then using that session, get the window I needed. I am able to do this successfully in my Robot Framework script now using the following code snippet:
#Opening a Desktop session. This will give you control of all OPEN Applications.
${desktop_index}= Open Application ${REMOTE_URL} app=Root
#Switch control to the Desktop session
Switch Application ${desktop_index}
#Assuming Outlook main window launched, get the NativeWindowHandle attribute of the Top Level Outlook Window.
${id}= Get Element Attribute xpath=//Window[@Name='<name of outlook window from inspect>'] NativeWindowHandle
${outlook_index_2}= Open Application ${REMOTE_URL} appTopLevelWindow=${id}
#Switch from the desktop session to the new outlook session
Switch Application ${outlook_index_2}
#Click on file menu to prove that we can manipulate outlook
Click Element xpath=//Button[@Name='File Tab']
Most helpful comment
Apologies for the delay, I've just implemented v1.1.1 and can confirm it works as intended, the workaround with multiple driver sessions is no longer required. Thank you for the support.
@YouWhy
What I think you are doing above is trying to find the element in the splash screen window and that has been closed. You still have to switch windows and make sure it's the correct one in case the splash screen is slow to disappear.
Here's a bit of code that should help you get the idea: