11using System ;
22using System . Collections . Generic ;
33using System . Linq ;
4- using System . Net . Http ;
5- using System . Net . Http . Headers ;
6- using System . Net . Http . Json ;
74using System . Reflection ;
8- using System . Text ;
95using BrowserStack ;
106using CSF . Screenplay . Performances ;
7+ using Microsoft . Extensions . DependencyInjection ;
118
129namespace CSF . Screenplay . Selenium . BrowserStack ;
1310
1411public sealed class BrowserStackExtension : IDisposable
1512{
16- const string urlPattern = "https://api.browserstack.com/automate/sessions/{0}.json" ;
17-
1813 Local ? browserStackLocal ;
1914 IHasPerformanceEvents ? eventBus ;
20- HttpClient ? httpClient ;
2115
2216 public async Task OnTestRunStarting ( )
2317 {
@@ -33,8 +27,6 @@ public async Task OnTestRunStarting()
3327 }
3428 if ( ! browserStackLocal . isRunning ( ) ) throw new TimeoutException ( "BrowserStack Local is still not running after 20 seconds" ) ;
3529
36- httpClient = GetHttpClient ( ) ;
37-
3830 eventBus = ScreenplayLocator . GetScreenplay ( Assembly . GetExecutingAssembly ( ) ) . GetEventBus ( ) ;
3931 eventBus . PerformanceFinished += UpdateBrowserStackSession ;
4032
@@ -44,43 +36,24 @@ void UpdateBrowserStackSession(object? sender, PerformanceFinishedEventArgs e)
4436 {
4537 if ( ! e . Success . HasValue ) return ;
4638
47- var sessionId = BrowserStackSessionIdProvider . GetBrowserStackSessionId ( e . Performance ) ;
48- if ( sessionId is null ) return ;
49-
50- var uri = GetApiUri ( sessionId ) ;
51- var requestMessage = GetRequestMessage ( uri , e . Success . Value ) ;
52- httpClient ! . Send ( requestMessage ) ;
53- }
54-
55- static HttpRequestMessage GetRequestMessage ( Uri requestUri , bool success )
56- {
57- return new ( HttpMethod . Put , requestUri )
58- {
59- Content = JsonContent . Create ( @$ "{{""status"":""{ ( success ? "passed" : "failed" ) } "", ""reason"":""""}}") ,
60- } ;
61- }
62-
63- static Uri GetApiUri ( string sessionId ) => new ( string . Format ( urlPattern , sessionId ) ) ;
39+ var cast = e . Performance . ServiceProvider . GetRequiredService < ICast > ( ) ;
40+ var ability = ( from actorName in cast . GetCastList ( )
41+ let actor = cast . GetActor ( actorName )
42+ where ( ( IHasAbilities ) actor ) . HasAbility < BrowseTheWeb > ( )
43+ select actor . GetAbility < BrowseTheWeb > ( ) )
44+ . FirstOrDefault ( ) ;
6445
65- static HttpClient GetHttpClient ( )
66- {
67- var client = new HttpClient ( ) ;
68- client . DefaultRequestHeaders . Authorization = GetAuthenticationHeaderValue ( ) ;
69- return client ;
70- }
46+ if ( ability is null ) return ;
7147
72- static AuthenticationHeaderValue GetAuthenticationHeaderValue ( )
73- {
74- var headerBytes = Encoding . ASCII . GetBytes ( $ "{ BrowserStackEnvironment . GetBrowserStackUserName ( ) } :{ BrowserStackEnvironment . GetBrowserStackAccessKey ( ) } ") ;
75- var headerValue = Convert . ToBase64String ( headerBytes ) ;
76- return new ( "Basic" , headerValue ) ;
48+ var jsExecutor = ability . GetJavaScriptExecutor ( ) ;
49+ var json = $@ "{{""action"":""setSessionStatus"",""arguments"":{{""status"":""{ ( e . Success . Value ? "passed" : "failed" ) } "",""reason"":""Test completion""}}}}";
50+ jsExecutor . ExecuteScript ( "browserstack_executor: " + json ) ;
7751 }
7852
7953 /// <inheritdoc/>
8054 public void Dispose ( )
8155 {
8256 browserStackLocal ? . stop ( ) ;
83- httpClient ? . Dispose ( ) ;
8457
8558 if ( eventBus is null ) return ;
8659 eventBus . PerformanceFinished -= UpdateBrowserStackSession ;
0 commit comments