@@ -1327,6 +1327,7 @@ async function mountChatView(options: {
13271327 snapshot : OrchestrationReadModel ;
13281328 configureFixture ?: ( fixture : TestFixture ) => void ;
13291329 resolveRpc ?: ( body : NormalizedWsRpcRequestBody ) => unknown | undefined ;
1330+ initialPath ?: string ;
13301331} ) : Promise < MountedChatView > {
13311332 fixture = buildFixture ( options . snapshot ) ;
13321333 options . configureFixture ?.( fixture ) ;
@@ -1346,7 +1347,7 @@ async function mountChatView(options: {
13461347
13471348 const router = getRouter (
13481349 createMemoryHistory ( {
1349- initialEntries : [ `/${ LOCAL_ENVIRONMENT_ID } /${ THREAD_ID } ` ] ,
1350+ initialEntries : [ options . initialPath ?? `/${ LOCAL_ENVIRONMENT_ID } /${ THREAD_ID } ` ] ,
13501351 } ) ,
13511352 ) ;
13521353
@@ -2512,6 +2513,119 @@ describe("ChatView timeline estimator parity (full app)", () => {
25122513 }
25132514 } ) ;
25142515
2516+ it ( "uses the active draft route session when changing the base branch" , async ( ) => {
2517+ const staleDraftId = draftIdFromPath ( "/draft/draft-stale-branch-session" ) ;
2518+ const activeDraftId = draftIdFromPath ( "/draft/draft-active-branch-session" ) ;
2519+
2520+ useComposerDraftStore . setState ( {
2521+ draftThreadsByThreadKey : {
2522+ [ staleDraftId ] : {
2523+ threadId : THREAD_ID ,
2524+ environmentId : LOCAL_ENVIRONMENT_ID ,
2525+ projectId : PROJECT_ID ,
2526+ logicalProjectKey : `${ PROJECT_DRAFT_KEY } :stale` ,
2527+ createdAt : NOW_ISO ,
2528+ runtimeMode : "full-access" ,
2529+ interactionMode : "default" ,
2530+ branch : "main" ,
2531+ worktreePath : null ,
2532+ envMode : "worktree" ,
2533+ } ,
2534+ [ activeDraftId ] : {
2535+ threadId : THREAD_ID ,
2536+ environmentId : LOCAL_ENVIRONMENT_ID ,
2537+ projectId : PROJECT_ID ,
2538+ logicalProjectKey : PROJECT_DRAFT_KEY ,
2539+ createdAt : NOW_ISO ,
2540+ runtimeMode : "full-access" ,
2541+ interactionMode : "default" ,
2542+ branch : "main" ,
2543+ worktreePath : null ,
2544+ envMode : "worktree" ,
2545+ } ,
2546+ } ,
2547+ logicalProjectDraftThreadKeyByLogicalProjectKey : {
2548+ [ `${ PROJECT_DRAFT_KEY } :stale` ] : staleDraftId ,
2549+ [ PROJECT_DRAFT_KEY ] : activeDraftId ,
2550+ } ,
2551+ } ) ;
2552+
2553+ const mounted = await mountChatView ( {
2554+ viewport : DEFAULT_VIEWPORT ,
2555+ snapshot : createDraftOnlySnapshot ( ) ,
2556+ initialPath : `/draft/${ activeDraftId } ` ,
2557+ resolveRpc : ( body ) => {
2558+ if ( body . _tag === WS_METHODS . gitListBranches ) {
2559+ return {
2560+ isRepo : true ,
2561+ hasOriginRemote : true ,
2562+ nextCursor : null ,
2563+ totalCount : 2 ,
2564+ branches : [
2565+ {
2566+ name : "main" ,
2567+ current : true ,
2568+ isDefault : true ,
2569+ worktreePath : null ,
2570+ } ,
2571+ {
2572+ name : "release/next" ,
2573+ current : false ,
2574+ isDefault : false ,
2575+ worktreePath : null ,
2576+ } ,
2577+ ] ,
2578+ } ;
2579+ }
2580+ return undefined ;
2581+ } ,
2582+ } ) ;
2583+
2584+ try {
2585+ const branchButton = await waitForElement (
2586+ ( ) =>
2587+ Array . from ( document . querySelectorAll ( "button" ) ) . find (
2588+ ( button ) => button . textContent ?. trim ( ) === "From main" ,
2589+ ) as HTMLButtonElement | null ,
2590+ 'Unable to find branch selector button with "From main".' ,
2591+ ) ;
2592+ branchButton . click ( ) ;
2593+
2594+ const branchOption = await waitForElement (
2595+ ( ) =>
2596+ Array . from ( document . querySelectorAll ( "span" ) ) . find (
2597+ ( element ) => element . textContent ?. trim ( ) === "release/next" ,
2598+ ) as HTMLSpanElement | null ,
2599+ 'Unable to find the "release/next" branch option.' ,
2600+ ) ;
2601+ branchOption . click ( ) ;
2602+
2603+ await vi . waitFor (
2604+ ( ) => {
2605+ expect ( useComposerDraftStore . getState ( ) . getDraftSession ( activeDraftId ) ?. branch ) . toBe (
2606+ "release/next" ,
2607+ ) ;
2608+ expect ( useComposerDraftStore . getState ( ) . getDraftSession ( staleDraftId ) ?. branch ) . toBe (
2609+ "main" ,
2610+ ) ;
2611+ } ,
2612+ { timeout : 8_000 , interval : 16 } ,
2613+ ) ;
2614+
2615+ await vi . waitFor (
2616+ ( ) => {
2617+ const updatedButton = Array . from ( document . querySelectorAll ( "button" ) ) . find ( ( button ) =>
2618+ button . textContent ?. trim ( ) . includes ( "From release/next" ) ,
2619+ ) ;
2620+ expect ( updatedButton ) . toBeTruthy ( ) ;
2621+ } ,
2622+ { timeout : 8_000 , interval : 16 } ,
2623+ ) ;
2624+ } finally {
2625+ await mounted . cleanup ( ) ;
2626+ }
2627+ } ) ;
2628+
25152629 it ( "surrounds selected plain text and preserves the inner selection for repeated wrapping" , async ( ) => {
25162630 const mounted = await mountChatView ( {
25172631 viewport : DEFAULT_VIEWPORT ,
0 commit comments