{"record":{"id":"e24be739738ed7f0","repo":"jackwener/OpenCLI","slug":"chatgpt-tool-selection-requires-native-browser-cli","errorCode":null,"errorMessage":"ChatGPT tool selection requires native browser click support.","messagePattern":"ChatGPT tool selection requires native browser click support\\.","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/chatgpt/utils.js","lineNumber":825,"sourceCode":"            ? [\n                node.textContent,\n                node.getAttribute('aria-label'),\n                node.getAttribute('title'),\n                node.getAttribute('data-testid'),\n            ]\n            : [];\n        const entry = Object.entries(labels).find(([, value]) => haystacks.some((candidate) => matchesLabel(candidate, value.labels)));\n        return {\n            tool: entry?.[0] ?? null,\n            label: entry?.[1]?.label ?? null,\n        };\n    })()`)), 'chatgpt current tool');\n}\n\nexport async function selectChatGPTTool(page, tool) {\n    const target = requireKnownChatGPTTool(tool);\n    if (typeof page.nativeClick !== 'function') {\n        throw new CommandExecutionError('ChatGPT tool selection requires native browser click support.');\n    }\n    await ensureOnChatGPT(page);\n    await ensureChatGPTComposer(page, 'ChatGPT tool selection requires a logged-in ChatGPT session with a visible composer.');\n\n    const before = await getCurrentChatGPTTool(page);\n    if (before.tool === target.key) {\n        return { Status: 'Already selected', Tool: target.label };\n    }\n\n    const menuButton = requireObjectEvaluateResult(unwrapEvaluateResult(await page.evaluate(`(() => {\n        const isVisible = (el) => {\n            if (!(el instanceof HTMLElement)) return false;\n            const style = window.getComputedStyle(el);\n            if (style.display === 'none' || style.visibility === 'hidden') return false;\n            const rect = el.getBoundingClientRect();\n            return rect.width > 0 && rect.height > 0;\n        };\n        const button = document.querySelector('button[data-testid=\"composer-plus-btn\"]');","sourceCodeStart":807,"sourceCodeEnd":843,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/chatgpt/utils.js#L807-L843","documentation":"selectChatGPTTool drives the tools (\"+\" / actions) menu with real mouse input, so it requires page.nativeClick to exist. If the page object lacks that method it throws CommandExecutionError immediately, before navigating or checking login, mirroring the model-selection capability check.","triggerScenarios":"Calling selectChatGPTTool with a page from a driver that doesn't implement nativeClick — minimal test fakes, alternate automation libraries exposing only evaluate(), or browser environments with CDP input injection disabled.","commonSituations":"Swapping drivers or downgrading the browser adapter; injecting a mock page in CI without nativeClick; remote/embedded browsers that strip input domains.","solutions":["Use the OpenCLI CDP page object that implements nativeClick.","Update/fix the browser driver so mouse input (CDP Input domain) works.","Extend test page stubs with a nativeClick(x, y) implementation.","Toggle the tool manually in the ChatGPT UI if native clicks are impossible in your environment."],"exampleFix":"// before\nconst page = fakePage(); // no nativeClick\nawait selectChatGPTTool(page, 'web-search');\n// after\nconst page = await opencli.browser.open('https://chatgpt.com');\nawait selectChatGPTTool(page, 'web-search');","handlingStrategy":"type-guard","validationCode":"if (typeof page.nativeClick !== 'function') {\n  throw new Error('Tool selection needs a CDP page with nativeClick support.');\n}","typeGuard":"function supportsToolSelection(page) {\n  return page != null && typeof page.nativeClick === 'function' && typeof page.evaluate === 'function';\n}","tryCatchPattern":"try {\n  await selectChatGPTTool(page, tool);\n} catch (err) {\n  if (err instanceof CommandExecutionError && /native browser click support/.test(err.message)) {\n    page = await opencli.browser.open('https://chatgpt.com');\n    return selectChatGPTTool(page, tool);\n  }\n  throw err;\n}","preventionTips":["Use the OpenCLI CDP page object for all tool automation.","Add nativeClick to test page stubs.","Verify CDP input domains work in remote/headless setups.","Smoke-test tool selection after any driver change."],"tags":["browser-automation","capability-check","chatgpt","cdp"],"backgroundTag":"missing-browser-capability","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}