@@ -3,9 +3,11 @@ import type { Page } from "@playwright/test"
33import { test , expect } from "../fixtures"
44import { assistantText , sessionIDFromUrl } from "../actions"
55import { promptSelector } from "../selectors"
6+ import { createSdk } from "../utils"
67import { openaiModel , promptMatch , titleMatch , withMockOpenAI } from "./mock"
78
89const text = ( value : string | null ) => ( value ?? "" ) . replace ( / \u200B / g, "" ) . trim ( )
10+ type Sdk = ReturnType < typeof createSdk >
911
1012const isBash = ( part : unknown ) : part is ToolPart => {
1113 if ( ! part || typeof part !== "object" ) return false
@@ -14,47 +16,15 @@ const isBash = (part: unknown): part is ToolPart => {
1416 return "state" in part
1517}
1618
17- async function edge ( page : Page , pos : "start" | "end" ) {
18- await page . locator ( promptSelector ) . evaluate ( ( el : HTMLDivElement , pos : "start" | "end" ) => {
19- const selection = window . getSelection ( )
20- if ( ! selection ) return
21-
22- const walk = document . createTreeWalker ( el , NodeFilter . SHOW_TEXT )
23- const nodes : Text [ ] = [ ]
24- for ( let node = walk . nextNode ( ) ; node ; node = walk . nextNode ( ) ) {
25- nodes . push ( node as Text )
26- }
27-
28- if ( nodes . length === 0 ) {
29- const node = document . createTextNode ( "" )
30- el . appendChild ( node )
31- nodes . push ( node )
32- }
33-
34- const node = pos === "start" ? nodes [ 0 ] ! : nodes [ nodes . length - 1 ] !
35- const range = document . createRange ( )
36- range . setStart ( node , pos === "start" ? 0 : ( node . textContent ?? "" ) . length )
37- range . collapse ( true )
38- selection . removeAllRanges ( )
39- selection . addRange ( range )
40- } , pos )
41- }
42-
4319async function wait ( page : Page , value : string ) {
4420 await expect . poll ( async ( ) => text ( await page . locator ( promptSelector ) . textContent ( ) ) ) . toBe ( value )
4521}
4622
47- async function reply (
48- sdk : { session : { messages : Parameters < typeof assistantText > [ 0 ] [ "session" ] } } ,
49- sessionID : string ,
50- token : string ,
51- ) {
52- await expect
53- . poll ( ( ) => assistantText ( sdk as Parameters < typeof assistantText > [ 0 ] , sessionID ) , { timeout : 90_000 } )
54- . toContain ( token )
23+ async function reply ( sdk : Sdk , sessionID : string , token : string ) {
24+ await expect . poll ( ( ) => assistantText ( sdk , sessionID ) , { timeout : 90_000 } ) . toContain ( token )
5525}
5626
57- async function shell ( sdk : Parameters < typeof withSession > [ 0 ] , sessionID : string , cmd : string , token : string ) {
27+ async function shell ( sdk : Sdk , sessionID : string , cmd : string , token : string ) {
5828 await expect
5929 . poll (
6030 async ( ) => {
@@ -142,76 +112,64 @@ test("prompt history restores unsent draft with arrow navigation", async ({
142112 } )
143113} )
144114
145- test ( "shell history stays separate from normal prompt history" , async ( { page, llm , backend , withBackendProject } ) => {
115+ test . fixme ( "shell history stays separate from normal prompt history" , async ( { page, sdk , gotoSession } ) => {
146116 test . setTimeout ( 120_000 )
147117
148- await withMockOpenAI ( {
149- serverUrl : backend . url ,
150- llmUrl : llm . url ,
151- fn : async ( ) => {
152- const firstToken = `E2E_SHELL_ONE_${ Date . now ( ) } `
153- const secondToken = `E2E_SHELL_TWO_${ Date . now ( ) } `
154- const normalToken = `E2E_NORMAL_${ Date . now ( ) } `
155- const first = `echo ${ firstToken } `
156- const second = `echo ${ secondToken } `
157- const normal = `Reply with exactly: ${ normalToken } `
118+ const firstToken = `E2E_SHELL_ONE_${ Date . now ( ) } `
119+ const secondToken = `E2E_SHELL_TWO_${ Date . now ( ) } `
120+ const normalToken = `E2E_NORMAL_${ Date . now ( ) } `
121+ const first = `echo ${ firstToken } `
122+ const second = `echo ${ secondToken } `
123+ const normal = `Reply with exactly: ${ normalToken } `
158124
159- await llm . textMatch ( titleMatch , "E2E Title" )
160- await llm . textMatch ( promptMatch ( normalToken ) , normalToken )
125+ await gotoSession ( )
161126
162- await withBackendProject (
163- async ( project ) => {
164- const prompt = page . locator ( promptSelector )
127+ const prompt = page . locator ( promptSelector )
165128
166- await prompt . click ( )
167- await page . keyboard . type ( "!" )
168- await page . keyboard . type ( first )
169- await page . keyboard . press ( "Enter" )
170- await wait ( page , "" )
129+ await prompt . click ( )
130+ await page . keyboard . type ( "!" )
131+ await page . keyboard . type ( first )
132+ await page . keyboard . press ( "Enter" )
133+ await wait ( page , "" )
171134
172- await expect ( page ) . toHaveURL ( / \/ s e s s i o n \/ [ ^ / ? # ] + / , { timeout : 30_000 } )
173- const sessionID = sessionIDFromUrl ( page . url ( ) ) !
174- project . trackSession ( sessionID )
175- await shell ( project . sdk , sessionID , first , firstToken )
135+ await expect ( page ) . toHaveURL ( / \/ s e s s i o n \/ [ ^ / ? # ] + / , { timeout : 30_000 } )
136+ const sessionID = sessionIDFromUrl ( page . url ( ) ) !
137+ await shell ( sdk , sessionID , first , firstToken )
176138
177- await prompt . click ( )
178- await page . keyboard . type ( "!" )
179- await page . keyboard . type ( second )
180- await page . keyboard . press ( "Enter" )
181- await wait ( page , "" )
182- await shell ( project . sdk , sessionID , second , secondToken )
139+ await prompt . click ( )
140+ await page . keyboard . type ( "!" )
141+ await page . keyboard . type ( second )
142+ await page . keyboard . press ( "Enter" )
143+ await wait ( page , "" )
144+ await shell ( sdk , sessionID , second , secondToken )
183145
184- await prompt . click ( )
185- await page . keyboard . type ( "!" )
186- await page . keyboard . press ( "ArrowUp" )
187- await wait ( page , second )
146+ await page . keyboard . press ( "Escape" )
147+ await wait ( page , "" )
188148
189- await page . keyboard . press ( "ArrowUp" )
190- await wait ( page , first )
149+ await prompt . click ( )
150+ await page . keyboard . type ( "!" )
151+ await page . keyboard . press ( "ArrowUp" )
152+ await wait ( page , second )
191153
192- await page . keyboard . press ( "ArrowDown " )
193- await wait ( page , second )
154+ await page . keyboard . press ( "ArrowUp " )
155+ await wait ( page , first )
194156
195- await page . keyboard . press ( "ArrowDown" )
196- await wait ( page , "" )
157+ await page . keyboard . press ( "ArrowDown" )
158+ await wait ( page , second )
197159
198- await page . keyboard . press ( "Escape " )
199- await wait ( page , "" )
160+ await page . keyboard . press ( "ArrowDown " )
161+ await wait ( page , "" )
200162
201- await prompt . click ( )
202- await page . keyboard . type ( normal )
203- await page . keyboard . press ( "Enter" )
204- await wait ( page , "" )
205- await reply ( project . sdk , sessionID , normalToken )
163+ await page . keyboard . press ( "Escape" )
164+ await wait ( page , "" )
206165
207- await prompt . click ( )
208- await page . keyboard . press ( "ArrowUp" )
209- await wait ( page , normal )
210- } ,
211- {
212- model : openaiModel ,
213- } ,
214- )
215- } ,
216- } )
166+ await prompt . click ( )
167+ await page . keyboard . type ( normal )
168+ await page . keyboard . press ( "Enter" )
169+ await wait ( page , "" )
170+ await reply ( sdk , sessionID , normalToken )
171+
172+ await prompt . click ( )
173+ await page . keyboard . press ( "ArrowUp" )
174+ await wait ( page , normal )
217175} )
0 commit comments