diff --git a/src/chat-swarm-runtime.test.ts b/src/chat-swarm-runtime.test.ts index 4493d9411..13ab20869 100644 --- a/src/chat-swarm-runtime.test.ts +++ b/src/chat-swarm-runtime.test.ts @@ -223,6 +223,10 @@ test("CDP prompt delivery targets the visible editable composer before textarea assert.match(expression, /data-testid="send-button"/); assert.ok(expression.indexOf("const editable=") < expression.indexOf("const textarea=")); assert.match(expression, /const el=editable\|\|textarea/); + assert.match(expression, /document\.createRange\(\)/); + assert.match(expression, /selectNodeContents\(editable\)/); + assert.match(expression, /document\.execCommand\('insertText',false,prompt\)/); + assert.doesNotMatch(expression, /editable\.textContent=prompt/); }); function openCliDriverForTest() { diff --git a/src/chat-swarm-runtime.ts b/src/chat-swarm-runtime.ts index 9f0735387..0b185a4d9 100644 --- a/src/chat-swarm-runtime.ts +++ b/src/chat-swarm-runtime.ts @@ -2198,7 +2198,7 @@ export class CdpMacWebDriver implements MacWebDriver { const expectedUrl = JSON.stringify(expectedConversationUrl ?? null); const result = await this.evaluate<{ ok: boolean; reason?: string }>( target, - `(() => { const expectedUrl=${expectedUrl}; if(expectedUrl && location.href !== expectedUrl) return {ok:false,reason:'CHATGPT_CONVERSATION_IDENTITY_DRIFT'}; const prompt=${encoded}; const visible=(el) => { const rect=el.getBoundingClientRect(); const style=getComputedStyle(el); return rect.width > 0 && rect.height > 0 && style.display !== 'none' && style.visibility !== 'hidden'; }; const editable=[...document.querySelectorAll('[contenteditable="true"]')].find(visible); const textarea=[...document.querySelectorAll('textarea')].find(visible); const el=editable||textarea; if(!el) return {ok:false,reason:'composer_missing'}; el.focus(); if(editable){ editable.textContent=prompt; editable.dispatchEvent(new InputEvent('input',{bubbles:true,inputType:'insertText',data:prompt})); } else { const setter=Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype,'value')?.set; setter?.call(textarea,prompt); textarea.dispatchEvent(new Event('input',{bubbles:true})); } const button=document.querySelector('[data-testid="send-button"]') || [...document.querySelectorAll('button')].find(b => /send/i.test((b.getAttribute('aria-label')||b.textContent||''))); if(!button || button.disabled) return {ok:false,reason:'send_button_missing_or_disabled'}; button.click(); return {ok:true}; })()`, + `(() => { const expectedUrl=${expectedUrl}; if(expectedUrl && location.href !== expectedUrl) return {ok:false,reason:'CHATGPT_CONVERSATION_IDENTITY_DRIFT'}; const prompt=${encoded}; const visible=(el) => { const rect=el.getBoundingClientRect(); const style=getComputedStyle(el); return rect.width > 0 && rect.height > 0 && style.display !== 'none' && style.visibility !== 'hidden'; }; const editable=[...document.querySelectorAll('[contenteditable="true"]')].find(visible); const textarea=[...document.querySelectorAll('textarea')].find(visible); const el=editable||textarea; if(!el) return {ok:false,reason:'composer_missing'}; el.focus(); if(editable){ const range=document.createRange(); range.selectNodeContents(editable); const selection=window.getSelection(); if(!selection) return {ok:false,reason:'composer_selection_unavailable'}; selection.removeAllRanges(); selection.addRange(range); const inserted=document.execCommand('insertText',false,prompt); selection.removeAllRanges(); if(!inserted) return {ok:false,reason:'composer_insert_failed'}; } else { const setter=Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype,'value')?.set; setter?.call(textarea,prompt); textarea.dispatchEvent(new Event('input',{bubbles:true})); } const button=document.querySelector('[data-testid="send-button"]') || [...document.querySelectorAll('button')].find(b => /send/i.test((b.getAttribute('aria-label')||b.textContent||''))); if(!button || button.disabled) return {ok:false,reason:'send_button_missing_or_disabled'}; button.click(); return {ok:true}; })()`, ); if (!result?.ok) { throw new Error(result?.reason ?? "ChatGPT prompt delivery failed");