MCPcopy Create free account
hub / github.com/aeroxy/chrome-devtools-cli / build_ctx_object

Function build_ctx_object

src/commands/evaluate.rs:93–168  ·  view source on GitHub ↗

Build the injected `ctx` automation-helper object shared by `run-script` and `adapter`. The returned snippet declares `const ctx = {...}` and is meant to be embedded at the top of an async IIFE, before user code runs. Both call sites reuse it so the helper surface stays in lockstep.

(args_str: &str)

Source from the content-addressed store, hash-verified

91/// at the top of an async IIFE, before user code runs. Both call sites reuse it
92/// so the helper surface stays in lockstep.
93fn build_ctx_object(args_str: &str) -> String {
94 format!(
95 r#"const ctx = {{
96 args: {args_str},
97 wait: async (ms) => new Promise(r => setTimeout(r, ms)),
98 waitForText: async (text, timeout = 30000) => {{
99 const start = Date.now();
100 while (true) {{
101 if (document.body && document.body.innerText.includes(text)) return;
102 if (timeout > 0 && Date.now() - start >= timeout) break;
103 await new Promise(r => setTimeout(r, {POLL_INTERVAL_MS}));
104 }}
105 throw new Error("Timeout waiting for text: " + text);
106 }},
107 waitForSelector: async (selector, timeout = 30000) => {{
108 const start = Date.now();
109 while (true) {{
110 if (document.querySelector(selector)) return;
111 if (timeout > 0 && Date.now() - start >= timeout) break;
112 await new Promise(r => setTimeout(r, {POLL_INTERVAL_MS}));
113 }}
114 throw new Error("Timeout waiting for selector: " + selector);
115 }},
116 click: async (selector) => {{
117 const el = document.querySelector(selector);
118 if (!el) throw new Error("Element not found: " + selector);
119 el.click();
120 }},
121 fill: async (selector, value) => {{
122 const el = document.querySelector(selector);
123 if (!el) throw new Error("Element not found: " + selector);
124 // Look up the native property setter from the element's own
125 // prototype chain (rather than assigning directly) so that
126 // React/Vue-style frameworks, which override the setter to
127 // track state, still observe the update.
128 const setNativeProp = (element, prop, val) => {{
129 let setter;
130 let proto = Object.getPrototypeOf(element);
131 while (proto) {{
132 const desc = Object.getOwnPropertyDescriptor(proto, prop);
133 if (desc) {{
134 setter = desc.set;
135 break;
136 }}
137 proto = Object.getPrototypeOf(proto);
138 }}
139 if (setter) {{
140 setter.call(element, val);
141 }} else {{
142 element[prop] = val;
143 }}
144 }};
145 if (el.type === 'checkbox' || el.type === 'radio') {{
146 // Checkboxes/radios toggle via `checked`, not `value`. A
147 // boolean (or "true"/"false") sets the state directly; any
148 // other value selects the input whose `value` it matches.
149 let checkedVal;
150 if (value === true || value === false) {{

Calls

no outgoing calls