11import httpx
22import pytest
3+ from types import SimpleNamespace
34import hyperbrowser .client .managers .async_manager .sandboxes .sandbox_terminal as async_terminal_module
45import hyperbrowser .client .managers .sync_manager .sandboxes .sandbox_terminal as sync_terminal_module
56
2526from hyperbrowser .client .managers .sync_manager .sandboxes .sandbox_terminal import (
2627 SandboxTerminalApi ,
2728)
29+ from hyperbrowser .client .managers .sandboxes .shared import _build_sandbox_exposed_url
2830from hyperbrowser .models import (
2931 CreateSandboxParams ,
3032 SandboxDetail ,
7072 "diskSizeMiB" : 8192 ,
7173 "runtime" : {
7274 "transport" : "regional_proxy" ,
73- "host" : "runtime.example.com" ,
74- "baseUrl" : "https://runtime.example.com" ,
75+ "host" : "https:// runtime.example.com" ,
76+ "baseUrl" : "https://runtime.example.com/sandbox/sbx_123 " ,
7577 },
7678 "exposedPorts" : [
7779 {
7880 "port" : 3000 ,
7981 "auth" : True ,
80- "url" : "https://3000-runtime.example.com/" ,
81- "browserUrl" : "https://3000-runtime.example.com/_hb/auth?grant=test&next=%2F" ,
82+ "url" : "https://3000-sbx_123. runtime.example.com/" ,
83+ "browserUrl" : "https://3000-sbx_123. runtime.example.com/_hb/auth?grant=test&next=%2F" ,
8284 "browserUrlExpiresAt" : "2026-03-12T02:00:00Z" ,
8385 }
8486 ],
122124 "diskSizeMiB" : 8192 ,
123125 "runtime" : {
124126 "transport" : "regional_proxy" ,
125- "host" : "runtime.example.com" ,
126- "baseUrl" : "https://runtime.example.com" ,
127+ "host" : "https:// runtime.example.com" ,
128+ "baseUrl" : "https://runtime.example.com/sandbox/sbx_123 " ,
127129 },
128130 "exposedPorts" : [
129131 {
130132 "port" : 3000 ,
131133 "auth" : False ,
132- "url" : "https://3000-runtime.example.com/" ,
133- "browserUrl" : "https://3000-runtime.example.com/" ,
134+ "url" : "https://3000-sbx_123. runtime.example.com/" ,
135+ "browserUrl" : "https://3000-sbx_123. runtime.example.com/" ,
134136 }
135137 ],
136138 }
296298EXPOSE_PAYLOAD = {
297299 "port" : 3000 ,
298300 "auth" : True ,
299- "url" : "https://3000-runtime.example.com/" ,
300- "browserUrl" : "https://3000-runtime.example.com/_hb/auth?grant=test&next=%2F" ,
301+ "url" : "https://3000-sbx_123. runtime.example.com/" ,
302+ "browserUrl" : "https://3000-sbx_123. runtime.example.com/_hb/auth?grant=test&next=%2F" ,
301303 "browserUrlExpiresAt" : "2026-03-12T02:00:00Z" ,
302304}
303305
@@ -719,6 +721,7 @@ def test_sync_sandbox_control_manager_uses_expected_wire_keys():
719721 assert sandbox .memory_mib == 2048
720722 assert sandbox .disk_mib == 8192
721723 assert sandbox .exposed_ports [0 ].browser_url is not None
724+ assert sandbox .get_exposed_url (3000 ) == "https://3000-sbx_123.runtime.example.com/"
722725 assert expose_call ["json" ] == {"port" : 3000 , "auth" : True }
723726 assert exposed .browser_url is not None
724727 assert expose_call ["url" ].endswith ("/sandbox/sbx_123/expose" )
@@ -733,6 +736,30 @@ def test_snapshot_summary_allows_missing_compatibility_tag():
733736 assert snapshot .compatibility_tag is None
734737
735738
739+ def test_build_sandbox_exposed_url_uses_runtime_base_path_session_id ():
740+ runtime = SimpleNamespace (
741+ host = "https://runtime.example.com" ,
742+ base_url = "https://runtime.example.com/sandbox/sbx_123" ,
743+ )
744+
745+ assert (
746+ _build_sandbox_exposed_url (runtime , 3000 )
747+ == "https://3000-sbx_123.runtime.example.com/"
748+ )
749+
750+
751+ def test_build_sandbox_exposed_url_uses_session_id_from_runtime_host_path ():
752+ runtime = SimpleNamespace (
753+ host = "https://runtime.example.com/sandbox/sbx_123" ,
754+ base_url = "https://runtime.example.com" ,
755+ )
756+
757+ assert (
758+ _build_sandbox_exposed_url (runtime , 3000 )
759+ == "https://3000-sbx_123.runtime.example.com/"
760+ )
761+
762+
736763def test_sync_sandbox_runtime_apis_use_expected_wire_keys ():
737764 transport = RecordingTransport ()
738765
@@ -1017,6 +1044,7 @@ async def test_async_sandbox_control_manager_uses_expected_wire_keys():
10171044 assert sandbox .memory_mib == 2048
10181045 assert sandbox .disk_mib == 8192
10191046 assert sandbox .exposed_ports [0 ].browser_url is not None
1047+ assert sandbox .get_exposed_url (3000 ) == "https://3000-sbx_123.runtime.example.com/"
10201048 assert expose_call ["json" ] == {"port" : 3000 , "auth" : True }
10211049 assert exposed .browser_url is not None
10221050 assert isinstance (unexposed , SandboxUnexposeResult )
0 commit comments