4242import static java .util .Arrays .asList ;
4343
4444class BrowserContextImpl extends ChannelOwner implements BrowserContext {
45- private final BrowserImpl browser ;
45+ protected BrowserImpl browser ;
4646 private final TracingImpl tracing ;
4747 private final APIRequestContextImpl request ;
4848 private final ClockImpl clock ;
@@ -51,7 +51,7 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
5151
5252 final Router routes = new Router ();
5353 final WebSocketRouter webSocketRoutes = new WebSocketRouter ();
54- private boolean closeWasCalled ;
54+ private boolean closingOrClosed ;
5555 private final WaitableEvent <EventType , ?> closePromise ;
5656 final Map <String , BindingCallback > bindings = new HashMap <>();
5757 PageImpl ownerPage ;
@@ -69,8 +69,6 @@ private static final Map<EventType, String> eventSubscriptions() {
6969 }
7070 private final ListenerCollection <EventType > listeners = new ListenerCollection <>(eventSubscriptions (), this );
7171 final TimeoutSettings timeoutSettings = new TimeoutSettings ();
72- Path videosDir ;
73- URL baseUrl ;
7472 final Map <String , HarRecorder > harRecorders = new HashMap <>();
7573
7674 static class HarRecorder {
@@ -98,32 +96,32 @@ enum EventType {
9896
9997 BrowserContextImpl (ChannelOwner parent , String type , String guid , JsonObject initializer ) {
10098 super (parent , type , guid , initializer );
101- if (parent instanceof BrowserImpl ) {
102- browser = (BrowserImpl ) parent ;
103- } else {
104- browser = null ;
105- }
10699 tracing = connection .getExistingObject (initializer .getAsJsonObject ("tracing" ).get ("guid" ).getAsString ());
107100 request = connection .getExistingObject (initializer .getAsJsonObject ("requestContext" ).get ("guid" ).getAsString ());
108101 request .timeoutSettings = timeoutSettings ;
109102 clock = new ClockImpl (this );
110- closePromise = new WaitableEvent <>(listeners , EventType .CLOSE );
103+ closePromise = new WaitableEvent <>(listeners , EventType .CLOSE );
111104 }
112105
113- void setRecordHar (Path path , HarContentPolicy policy ) {
114- if (path != null ) {
115- harRecorders .put ("" , new HarRecorder (path , policy ));
106+ Path videosDir () {
107+ JsonObject recordVideo = initializer .getAsJsonObject ("options" ).getAsJsonObject ("recordVideo" );
108+ if (recordVideo == null ) {
109+ return null ;
116110 }
111+ return Paths .get (recordVideo .get ("dir" ).getAsString ());
117112 }
118113
119- void setBaseUrl (String spec ) {
120- try {
121- this .baseUrl = new URL (spec );
122- } catch (MalformedURLException e ) {
123- this .baseUrl = null ;
114+ URL baseUrl () {
115+ JsonElement url = initializer .getAsJsonObject ("options" ).get ("baseURL" );
116+ if (url != null ) {
117+ try {
118+ return new URL (url .getAsString ());
119+ } catch (MalformedURLException e ) {
120+ }
124121 }
122+ return null ;
125123 }
126-
124+
127125 String effectiveCloseReason () {
128126 if (closeReason != null ) {
129127 return closeReason ;
@@ -286,8 +284,8 @@ public List<Cookie> cookies(String url) {
286284 }
287285
288286 private void closeImpl (CloseOptions options ) {
289- if (!closeWasCalled ) {
290- closeWasCalled = true ;
287+ if (!closingOrClosed ) {
288+ closingOrClosed = true ;
291289 if (options == null ) {
292290 options = new CloseOptions ();
293291 }
@@ -481,7 +479,7 @@ public APIRequestContextImpl request() {
481479
482480 @ Override
483481 public void route (String url , Consumer <Route > handler , RouteOptions options ) {
484- route (UrlMatcher .forGlob (baseUrl , url , this .connection .localUtils , false ), handler , options );
482+ route (UrlMatcher .forGlob (baseUrl () , url , this .connection .localUtils , false ), handler , options );
485483 }
486484
487485 @ Override
@@ -500,10 +498,10 @@ public void routeFromHAR(Path har, RouteFromHAROptions options) {
500498 options = new RouteFromHAROptions ();
501499 }
502500 if (options .update != null && options .update ) {
503- recordIntoHar (null , har , options );
501+ recordIntoHar (null , har , options , null );
504502 return ;
505503 }
506- UrlMatcher matcher = UrlMatcher .forOneOf (baseUrl , options .url , this .connection .localUtils , false );
504+ UrlMatcher matcher = UrlMatcher .forOneOf (baseUrl () , options .url , this .connection .localUtils , false );
507505 HARRouter harRouter = new HARRouter (connection .localUtils , har , options .notFound );
508506 onClose (context -> harRouter .dispose ());
509507 route (matcher , route -> harRouter .handle (route ), null );
@@ -518,7 +516,7 @@ private void route(UrlMatcher matcher, Consumer<Route> handler, RouteOptions opt
518516
519517 @ Override
520518 public void routeWebSocket (String url , Consumer <WebSocketRoute > handler ) {
521- routeWebSocketImpl (UrlMatcher .forGlob (baseUrl , url , this .connection .localUtils , true ), handler );
519+ routeWebSocketImpl (UrlMatcher .forGlob (baseUrl () , url , this .connection .localUtils , true ), handler );
522520 }
523521
524522 @ Override
@@ -538,24 +536,28 @@ private void routeWebSocketImpl(UrlMatcher matcher, Consumer<WebSocketRoute> han
538536 });
539537 }
540538
541- void recordIntoHar (PageImpl page , Path har , RouteFromHAROptions options ) {
539+ void recordIntoHar (PageImpl page , Path har , RouteFromHAROptions options , HarContentPolicy contentPolicy ) {
540+ if (contentPolicy == null ) {
541+ contentPolicy = Utils .convertType (options .updateContent , HarContentPolicy .class );;
542+ }
543+ if (contentPolicy == null ) {
544+ contentPolicy = HarContentPolicy .ATTACH ;
545+ }
546+
542547 JsonObject params = new JsonObject ();
543548 if (page != null ) {
544549 params .add ("page" , page .toProtocolRef ());
545550 }
546- JsonObject jsonOptions = new JsonObject ();
547- jsonOptions .addProperty ("path" , har .toAbsolutePath ().toString ());
548- jsonOptions .addProperty ("content" , options .updateContent == null ?
549- HarContentPolicy .ATTACH .name ().toLowerCase () :
550- options .updateContent .name ().toLowerCase ());
551- jsonOptions .addProperty ("mode" , options .updateMode == null ?
552- HarMode .MINIMAL .name ().toLowerCase () :
553- options .updateMode .name ().toLowerCase ());
554- addHarUrlFilter (jsonOptions , options .url );
555- params .add ("options" , jsonOptions );
551+ JsonObject recordHarArgs = new JsonObject ();
552+ recordHarArgs .addProperty ("zip" , har .toString ().endsWith (".zip" ));
553+ recordHarArgs .addProperty ("content" , contentPolicy .name ().toLowerCase ());
554+ recordHarArgs .addProperty ("mode" , (options .updateMode == null ? HarMode .MINIMAL : options .updateMode ).name ().toLowerCase ());
555+ addHarUrlFilter (recordHarArgs , options .url );
556+
557+ params .add ("options" , recordHarArgs );
556558 JsonObject json = sendMessage ("harStart" , params ).getAsJsonObject ();
557559 String harId = json .get ("harId" ).getAsString ();
558- harRecorders .put (harId , new HarRecorder (har , HarContentPolicy . ATTACH ));
560+ harRecorders .put (harId , new HarRecorder (har , contentPolicy ));
559561 }
560562
561563 @ Override
@@ -639,7 +641,7 @@ public void unrouteAll() {
639641
640642 @ Override
641643 public void unroute (String url , Consumer <Route > handler ) {
642- unroute (UrlMatcher .forGlob (this .baseUrl , url , this .connection .localUtils , false ), handler );
644+ unroute (UrlMatcher .forGlob (this .baseUrl () , url , this .connection .localUtils , false ), handler );
643645 }
644646
645647 @ Override
@@ -849,8 +851,10 @@ protected void handleEvent(String event, JsonObject params) {
849851 }
850852
851853 void didClose () {
854+ closingOrClosed = true ;
852855 if (browser != null ) {
853856 browser .contexts .remove (this );
857+ browser .browserType .playwright .selectors .contextsForSelectors .remove (this );
854858 }
855859 listeners .notify (EventType .CLOSE , this );
856860 }
@@ -862,4 +866,46 @@ WritableStream createTempFile(String name, long lastModifiedMs) {
862866 JsonObject json = sendMessage ("createTempFile" , params ).getAsJsonObject ();
863867 return connection .getExistingObject (json .getAsJsonObject ("writableStream" ).get ("guid" ).getAsString ());
864868 }
869+
870+ protected void initializeHarFromOptions (Browser .NewContextOptions options ) {
871+ if (options .recordHarPath == null ) {
872+ if (options .recordHarOmitContent != null ) {
873+ throw new PlaywrightException ("recordHarOmitContent is set but recordHarPath is null" );
874+ }
875+ if (options .recordHarUrlFilter != null ) {
876+ throw new PlaywrightException ("recordHarUrlFilter is set but recordHarPath is null" );
877+ }
878+ if (options .recordHarMode != null ) {
879+ throw new PlaywrightException ("recordHarMode is set but recordHarPath is null" );
880+ }
881+ if (options .recordHarContent != null ) {
882+ throw new PlaywrightException ("recordHarContent is set but recordHarPath is null" );
883+ }
884+ return ;
885+ }
886+
887+ HarContentPolicy contentPolicy = options .recordHarContent ;
888+ if (contentPolicy == null && options .recordHarOmitContent != null && options .recordHarOmitContent == true ) {
889+ contentPolicy = HarContentPolicy .OMIT ;
890+ }
891+ if (contentPolicy == null ) {
892+ contentPolicy = options .recordHarPath .endsWith (".zip" ) ? HarContentPolicy .ATTACH : HarContentPolicy .EMBED ;
893+ }
894+ RouteFromHAROptions routeFromHAROptions = new RouteFromHAROptions ();
895+
896+ if (options .recordHarUrlFilter instanceof String ) {
897+ routeFromHAROptions .setUrl ((String ) options .recordHarUrlFilter );
898+ } else if (options .recordHarUrlFilter instanceof Pattern ) {
899+ routeFromHAROptions .setUrl ((Pattern ) options .recordHarUrlFilter );
900+ }
901+
902+ if (options .recordHarMode != null ) {
903+ routeFromHAROptions .updateMode = options .recordHarMode ;
904+ } else {
905+ routeFromHAROptions .updateMode = HarMode .FULL ;
906+ }
907+ routeFromHAROptions .url = options .recordHarUrlFilter ;
908+
909+ recordIntoHar (null , options .recordHarPath , routeFromHAROptions , contentPolicy );
910+ }
865911}
0 commit comments