1+ using FlaUI . Core ;
12using FlaUI . WebDriver . Models ;
23using Microsoft . AspNetCore . Mvc ;
34using System . Diagnostics ;
@@ -29,8 +30,6 @@ public async Task<ActionResult> CreateNewSession([FromBody] CreateSessionRequest
2930 . Where ( capabilities => TryMatchCapabilities ( capabilities , out matchedCapabilities , out _ ) )
3031 . Select ( capabillities => matchedCapabilities ! ) ;
3132
32- Core . Application ? app ;
33- var isAppOwnedBySession = false ;
3433 var capabilities = matchingCapabilities . FirstOrDefault ( ) ;
3534 if ( capabilities == null )
3635 {
@@ -43,69 +42,87 @@ public async Task<ActionResult> CreateNewSession([FromBody] CreateSessionRequest
4342 Message = string . Join ( "; " , mismatchIndications )
4443 } ) ;
4544 }
45+
46+ var timeoutsConfiguration = new TimeoutsConfiguration ( ) ;
47+ if ( capabilities . TryGetCapability < TimeoutsConfiguration > ( "timeouts" , out var timeoutsConfigurationFromCapabilities ) )
48+ {
49+ timeoutsConfiguration = timeoutsConfigurationFromCapabilities ! ;
50+ }
51+ var newCommandTimeout = TimeSpan . FromSeconds ( 60 ) ;
52+ if ( capabilities . TryGetNumberCapability ( "appium:newCommandTimeout" , out var newCommandTimeoutFromCapabilities ) )
53+ {
54+ newCommandTimeout = TimeSpan . FromSeconds ( newCommandTimeoutFromCapabilities ) ;
55+ }
56+
57+ Application ? app = GetApp ( capabilities , out bool isAppOwnedBySession ) ;
58+ Session session ;
59+ try
60+ {
61+ session = new Session ( app , isAppOwnedBySession , timeoutsConfiguration , newCommandTimeout ) ;
62+ }
63+ catch ( Exception )
64+ {
65+ app ? . Dispose ( ) ;
66+ throw ;
67+ }
68+
69+ _sessionRepository . Add ( session ) ;
70+ _logger . LogInformation ( "Created session with ID {SessionId} and capabilities {Capabilities}" , session . SessionId , capabilities ) ;
71+ return await Task . FromResult ( WebDriverResult . Success ( new CreateSessionResponse ( )
72+ {
73+ SessionId = session . SessionId ,
74+ Capabilities = capabilities . Capabilities
75+ } ) ) ;
76+ }
77+
78+ private static Application ? GetApp ( MergedCapabilities capabilities , out bool isAppOwnedBySession )
79+ {
4680 if ( capabilities . TryGetStringCapability ( "appium:app" , out var appPath ) )
4781 {
4882 if ( appPath == "Root" )
4983 {
50- app = null ;
84+ isAppOwnedBySession = false ;
85+ return null ;
5186 }
52- else
87+
88+ capabilities . TryGetStringCapability ( "appium:appArguments" , out var appArguments ) ;
89+ try
5390 {
54- capabilities . TryGetStringCapability ( "appium:appArguments" , out var appArguments ) ;
55- try
91+ if ( appPath . EndsWith ( "!App" ) )
5692 {
57- if ( appPath . EndsWith ( "!App" ) )
58- {
59- app = Core . Application . LaunchStoreApp ( appPath , appArguments ) ;
60- }
61- else
62- {
63- var processStartInfo = new ProcessStartInfo ( appPath , appArguments ?? "" ) ;
64- if ( capabilities . TryGetStringCapability ( "appium:appWorkingDir" , out var appWorkingDir ) )
65- {
66- processStartInfo . WorkingDirectory = appWorkingDir ;
67- }
68- app = Core . Application . Launch ( processStartInfo ) ;
69- }
93+ isAppOwnedBySession = true ;
94+ return Application . LaunchStoreApp ( appPath , appArguments ) ;
7095 }
71- catch ( Exception e )
96+
97+ var processStartInfo = new ProcessStartInfo ( appPath , appArguments ?? "" ) ;
98+ if ( capabilities . TryGetStringCapability ( "appium:appWorkingDir" , out var appWorkingDir ) )
7299 {
73- throw WebDriverResponseException . InvalidArgument ( $ "Starting app ' { appPath } ' with arguments ' { appArguments } ' threw an exception: { e . Message } " ) ;
100+ processStartInfo . WorkingDirectory = appWorkingDir ;
74101 }
102+ isAppOwnedBySession = true ;
103+ return Application . Launch ( processStartInfo ) ;
104+ }
105+ catch ( Exception e )
106+ {
107+ throw WebDriverResponseException . InvalidArgument ( $ "Starting app '{ appPath } ' with arguments '{ appArguments } ' threw an exception: { e . Message } ") ;
75108 }
76-
77- isAppOwnedBySession = true ;
78109 }
79- else if ( capabilities . TryGetStringCapability ( "appium:appTopLevelWindow" , out var appTopLevelWindowString ) )
110+
111+ if ( capabilities . TryGetStringCapability ( "appium:appTopLevelWindow" , out var appTopLevelWindowString ) )
80112 {
113+ isAppOwnedBySession = false ;
81114 Process process = GetProcessByMainWindowHandle ( appTopLevelWindowString ) ;
82- app = Core . Application . Attach ( process ) ;
115+ return Application . Attach ( process ) ;
83116 }
84- else if ( capabilities . TryGetStringCapability ( "appium:appTopLevelWindowTitleMatch" , out var appTopLevelWindowTitleMatch ) )
117+
118+ if ( capabilities . TryGetStringCapability ( "appium:appTopLevelWindowTitleMatch" , out var appTopLevelWindowTitleMatch ) )
85119 {
120+ isAppOwnedBySession = false ;
86121 Process ? process = GetProcessByMainWindowTitle ( appTopLevelWindowTitleMatch ) ;
87- app = Core . Application . Attach ( process ) ;
88- }
89- else
90- {
91- throw WebDriverResponseException . InvalidArgument ( "One of appium:app, appium:appTopLevelWindow or appium:appTopLevelWindowTitleMatch must be passed as a capability" ) ;
92- }
93- var session = new Session ( app , isAppOwnedBySession ) ;
94- if ( capabilities . TryGetNumberCapability ( "appium:newCommandTimeout" , out var newCommandTimeout ) )
95- {
96- session . NewCommandTimeout = TimeSpan . FromSeconds ( newCommandTimeout ) ;
122+ return Application . Attach ( process ) ;
97123 }
98- if ( capabilities . TryGetCapability < TimeoutsConfiguration > ( "timeouts" , out var timeoutsConfiguration ) )
99- {
100- session . TimeoutsConfiguration = timeoutsConfiguration ! ;
101- }
102- _sessionRepository . Add ( session ) ;
103- _logger . LogInformation ( "Created session with ID {SessionId} and capabilities {Capabilities}" , session . SessionId , capabilities ) ;
104- return await Task . FromResult ( WebDriverResult . Success ( new CreateSessionResponse ( )
105- {
106- SessionId = session . SessionId ,
107- Capabilities = capabilities . Capabilities
108- } ) ) ;
124+
125+ throw WebDriverResponseException . InvalidArgument ( "One of appium:app, appium:appTopLevelWindow or appium:appTopLevelWindowTitleMatch must be passed as a capability" ) ;
109126 }
110127
111128 private string ? GetMismatchIndication ( MergedCapabilities capabilities )
@@ -163,7 +180,7 @@ private bool TryMatchCapabilities(MergedCapabilities capabilities, [MaybeNullWhe
163180 matchedCapabilities . Copy ( "appium:appTopLevelWindow" , capabilities ) ;
164181 }
165182 else if ( capabilities . Contains ( "appium:appTopLevelWindowTitleMatch" ) )
166- {
183+ {
167184 matchedCapabilities . Copy ( "appium:appTopLevelWindowTitleMatch" , capabilities ) ;
168185 }
169186 else
@@ -199,8 +216,8 @@ private static Process GetProcessByMainWindowTitle(string appTopLevelWindowTitle
199216 try
200217 {
201218 appMainWindowTitleRegex = new Regex ( appTopLevelWindowTitleMatch ) ;
202- }
203- catch ( ArgumentException e )
219+ }
220+ catch ( ArgumentException e )
204221 {
205222 throw WebDriverResponseException . InvalidArgument ( $ "Capability appium:appTopLevelWindowTitleMatch '{ appTopLevelWindowTitleMatch } ' is not a valid regular expression: { e . Message } ") ;
206223 }
@@ -209,7 +226,7 @@ private static Process GetProcessByMainWindowTitle(string appTopLevelWindowTitle
209226 {
210227 throw WebDriverResponseException . InvalidArgument ( $ "Process with main window title matching '{ appTopLevelWindowTitleMatch } ' could not be found") ;
211228 }
212- else if ( processes . Length > 1 )
229+ if ( processes . Length > 1 )
213230 {
214231 throw WebDriverResponseException . InvalidArgument ( $ "Found multiple ({ processes . Length } ) processes with main window title matching '{ appTopLevelWindowTitleMatch } '") ;
215232 }
0 commit comments