Skip to content

Commit 8402bf5

Browse files
committed
chore: Add execute_script to code generator
1 parent 9864253 commit 8402bf5

3 files changed

Lines changed: 44 additions & 5 deletions

File tree

src/recording/code-generator.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ function generateStep(step: RecordedStep, history: SessionHistory): string {
4848
return `const browser = await remote(${indentJson(config)});`;
4949
}
5050
case 'close_session':
51-
return 'await browser.deleteSession();';
51+
return '// Session closed';
5252
case 'navigate':
5353
return `await browser.url('${escapeStr(p.url)}');`;
5454
case 'click_element':
@@ -71,12 +71,22 @@ function generateStep(step: RecordedStep, history: SessionHistory): string {
7171
return `await browser.$('${escapeStr(p.sourceSelector)}').dragAndDrop(browser.$('${escapeStr(p.targetSelector)}'));`;
7272
}
7373
return `await browser.$('${escapeStr(p.sourceSelector)}').dragAndDrop({ x: ${p.x}, y: ${p.y} });`;
74+
case 'execute_script': {
75+
const scriptCode = `'${escapeStr(p.script)}'`;
76+
const scriptArgs = (p.args as unknown[])?.length ? `, ${indentJson(p.args)}` : '';
77+
return `await browser.execute(${scriptCode}${scriptArgs});`;
78+
}
7479
default:
7580
return `// [unknown tool] ${step.tool}`;
7681
}
7782
}
7883

7984
export function generateCode(history: SessionHistory): string {
80-
const steps = history.steps.map(step => generateStep(step, history)).join('\n');
81-
return `import { remote } from 'webdriverio';\n\n${steps}`;
85+
const steps = history.steps
86+
.map(step => generateStep(step, history))
87+
.join('\n')
88+
.split('\n')
89+
.map(line => ` ${line}`)
90+
.join('\n');
91+
return `import { remote } from 'webdriverio';\n\ntry {\n${steps}\n} finally {\n await browser.deleteSession();\n}`;
8292
}

src/server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ registerTool(rotateDeviceToolDefinition, rotateDeviceTool);
130130
registerTool(hideKeyboardToolDefinition, hideKeyboardTool);
131131
registerTool(setGeolocationToolDefinition, setGeolocationTool);
132132

133-
registerTool(executeScriptToolDefinition, executeScriptTool);
133+
registerTool(executeScriptToolDefinition, withRecording('execute_script', executeScriptTool));
134134
registerTool(getElementsToolDefinition, getElementsTool);
135135

136136
registerResource(sessionsIndexResource);

tests/recording/code-generator.test.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,14 @@ function makeHistory(steps: Partial<RecordedStep>[]): SessionHistory {
3535
}
3636

3737
describe('generateCode - header', () => {
38-
it('wraps output in remote() setup', () => {
38+
it('wraps output in remote() setup with try/finally and deleteSession', () => {
3939
const code = generateCode(makeHistory([]));
4040
expect(code).toContain("import { remote } from 'webdriverio';");
4141
expect(code).toContain('browserName');
42+
expect(code).toContain('try {');
43+
expect(code).toContain('} finally {');
44+
expect(code).toContain(' await browser.deleteSession();');
45+
expect(code).toContain('}');
4246
});
4347

4448
it('generates start_session (browser) using history.capabilities', () => {
@@ -177,6 +181,31 @@ describe('generateCode - tool mappings', () => {
177181
expect(code).toContain("await browser.execute('mobile: swipe', { direction: 'up' });");
178182
});
179183

184+
it('execute_script → browser.execute with single-quoted script string', () => {
185+
const code = generateCode(makeHistory([{
186+
tool: 'execute_script',
187+
params: { script: 'return document.title' },
188+
}]));
189+
expect(code).toContain("await browser.execute('return document.title');");
190+
});
191+
192+
it('execute_script escapes backslashes in script string', () => {
193+
const code = generateCode(makeHistory([{
194+
tool: 'execute_script',
195+
params: { script: "return document.querySelector('[data-\\\\x]')" },
196+
}]));
197+
expect(code).toContain("await browser.execute('return document.querySelector(\\'[data-\\\\\\\\x]\\')');");
198+
});
199+
200+
it('execute_script with args → browser.execute with args array', () => {
201+
const code = generateCode(makeHistory([{
202+
tool: 'execute_script',
203+
params: { script: 'arguments[0].click()', args: ['#btn'] },
204+
}]));
205+
expect(code).toContain("await browser.execute('arguments[0].click()',");
206+
expect(code).toContain('"#btn"');
207+
});
208+
180209
it('drag_and_drop (selector form) → $().dragAndDrop($())', () => {
181210
const code = generateCode(makeHistory([{
182211
tool: 'drag_and_drop',

0 commit comments

Comments
 (0)