@@ -37,6 +37,11 @@ type SidebarLifecycleState = HTMLElement & {
3737 sessionsAgentId : string | null ;
3838 sessionsResult : SessionsListResult | null ;
3939 updateComplete : Promise < boolean > ;
40+ variant : "panel" | "drawer" ;
41+ } ;
42+
43+ type LobsterPetElement = HTMLElement & {
44+ runOutcome : "ok" | "error" | "aborted" ;
4045} ;
4146
4247function createGatewayHarness ( client : GatewayBrowserClient ) {
@@ -157,11 +162,16 @@ function createContext(
157162 } as unknown as ApplicationContext < RouteId > ;
158163}
159164
160- async function mountSidebar ( gateway : ApplicationGateway , sessions : SessionCapability ) {
165+ async function mountSidebar (
166+ gateway : ApplicationGateway ,
167+ sessions : SessionCapability ,
168+ variant : SidebarLifecycleState [ "variant" ] = "panel" ,
169+ ) {
161170 const provider = document . createElement ( PROVIDER_ELEMENT_NAME ) as AppSidebarContextProvider ;
162171 const sidebar = document . createElement (
163172 "openclaw-app-sidebar" ,
164173 ) as unknown as SidebarLifecycleState ;
174+ sidebar . variant = variant ;
165175 provider . setContext ( createContext ( gateway , sessions ) ) ;
166176 provider . append ( sidebar ) ;
167177 document . body . append ( provider ) ;
@@ -173,6 +183,50 @@ afterEach(() => {
173183 document . body . replaceChildren ( ) ;
174184} ) ;
175185
186+ describe ( "AppSidebar lobster outcome wiring" , ( ) => {
187+ it . each ( [
188+ [ "panel" , "failed" , "error" ] ,
189+ [ "panel" , "killed" , "aborted" ] ,
190+ [ "drawer" , "failed" , "error" ] ,
191+ [ "drawer" , "killed" , "aborted" ] ,
192+ ] as const ) (
193+ "passes the %s variant's latest %s session outcome" ,
194+ async ( variant , status , expectedOutcome ) => {
195+ const client = { } as GatewayBrowserClient ;
196+ const gateway = createGateway ( client ) ;
197+ const sessions = createSessionsHarness ( "main" , [ "agent:main:main" ] ) ;
198+ const { sidebar } = await mountSidebar ( gateway , sessions . sessions , variant ) ;
199+ const terminalState = createSessionState ( "main" , [ "agent:main:main" ] ) ;
200+ const result = terminalState . result ;
201+ if ( ! result ) {
202+ throw new Error ( "expected terminal session result" ) ;
203+ }
204+ const row = result . sessions [ 0 ] ;
205+ if ( ! row ) {
206+ throw new Error ( "expected terminal session row" ) ;
207+ }
208+
209+ sessions . publishList ( {
210+ result : {
211+ ...result ,
212+ sessions : [
213+ {
214+ ...row ,
215+ status,
216+ endedAt : 100 ,
217+ } ,
218+ ] ,
219+ } ,
220+ agentId : terminalState . agentId ,
221+ } ) ;
222+ await sidebar . updateComplete ;
223+
224+ const pet = sidebar . querySelector < LobsterPetElement > ( "openclaw-lobster-pet" ) ;
225+ expect ( pet ?. runOutcome ) . toBe ( expectedOutcome ) ;
226+ } ,
227+ ) ;
228+ } ) ;
229+
176230describe ( "AppSidebar session source lifecycle" , ( ) => {
177231 it ( "resets cached rows and creation order when the sessions source changes" , async ( ) => {
178232 const client = { } as GatewayBrowserClient ;
0 commit comments