explorbot 0.1.24 → 0.1.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "explorbot",
3
- "version": "0.1.24",
3
+ "version": "0.1.25",
4
4
  "description": "CLI app built with React Ink, CodeceptJS, and Playwright",
5
5
  "license": "Elastic-2.0",
6
6
  "type": "module",
@@ -127,6 +127,11 @@ export const fileUploadRule = dedent `
127
127
  Works with drag-and-drop upload zones.
128
128
  </file_upload>
129
129
  `;
130
+ export const formRequirementsRule = dedent `
131
+ <form_requirements>
132
+ Before filling a form that persists data (create/update), read each control's requirements (required, type/format, length, placeholder/aria-describedby hints) from <page_aria> and page HTML — call context() if not visible — and enter values that satisfy them. Search/filter/sort forms that only change the view do not need this.
133
+ </form_requirements>
134
+ `;
130
135
  // in rage mode we do not protect from irreversible actions
131
136
  export const protectionRule = dedent `
132
137
  <important>
@@ -260,6 +265,8 @@ export const actionRule = dedent `
260
265
  If locator doesn't work, try CSS or XPath locators.
261
266
  If nothing works, use I.clickXY(x, y) as last resort.
262
267
 
268
+ For checkboxes, prefer I.checkOption/I.uncheckOption over I.click.
269
+
263
270
 
264
271
  ### I.fillField
265
272
 
@@ -346,6 +353,19 @@ export const actionRule = dedent `
346
353
  I.selectOption('form select[name=account]', 'Premium');
347
354
  </example>
348
355
 
356
+ ### I.checkOption / I.uncheckOption
357
+
358
+ Set a checkbox/radio to a definite state — idempotent, never toggles. Use for checkboxes instead of I.click. Run via form(), not click().
359
+
360
+ I.checkOption(<locator>, <context>)
361
+ I.uncheckOption(<locator>, <context>)
362
+
363
+ <example>
364
+ I.checkOption('Subscribe');
365
+ I.checkOption({ role: 'checkbox', text: 'Agree' });
366
+ I.uncheckOption('Subscribe', '.preferences');
367
+ </example>
368
+
349
369
  ### I.attachFile
350
370
 
351
371
  Attaches a file to a file input element.
@@ -14,7 +14,7 @@ import { ErrorPageError } from "../utils/error-page.js";
14
14
  import { HooksRunner } from "../utils/hooks-runner.js";
15
15
  import { createDebug, tag } from "../utils/logger.js";
16
16
  import { loop } from "../utils/loop.js";
17
- import { actionRule, focusedElementRule, locatorRule, multipleTabsRule, protectionRule, sectionContextRule } from "./rules.js";
17
+ import { actionRule, focusedElementRule, formRequirementsRule, locatorRule, multipleTabsRule, protectionRule, sectionContextRule } from "./rules.js";
18
18
  import { TaskAgent } from "./task-agent.js";
19
19
  import { createCodeceptJSTools, createSpecialContextTools } from "./tools.js";
20
20
  const debugLog = createDebug('explorbot:tester');
@@ -691,6 +691,8 @@ export class Tester extends TaskAgent {
691
691
 
692
692
  ${sectionContextRule}
693
693
 
694
+ ${formRequirementsRule}
695
+
694
696
  ${this.provider.getSystemPromptForAgent('tester', this.explorer.getStateManager().getCurrentState()?.url) || ''}
695
697
  `;
696
698
  }
@@ -262,6 +262,7 @@ export function createCodeceptJSTools(explorer, task) {
262
262
 
263
263
  Use cases:
264
264
  - Typing into input fields (I.fillField, I.type)
265
+ - Setting checkboxes/radios to a definite state (I.checkOption, I.uncheckOption)
265
266
  - Working with iframes (switch context with I.switchTo)
266
267
  - Performing multiple form actions in a single batch
267
268
  - Complex interactions requiring sequential commands
@@ -269,6 +270,7 @@ export function createCodeceptJSTools(explorer, task) {
269
270
  Example - filling a form with context (PREFERRED):
270
271
  I.fillField('Username', 'John', '.login-form')
271
272
  I.selectOption('Country', 'USA', '.address-section')
273
+ I.checkOption('Agree', '.terms-section')
272
274
  I.attachFile('input[type="file"]', 'path/to/file', '.upload-section')
273
275
 
274
276
  Example - filling a form with ARIA locators:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "explorbot",
3
- "version": "0.1.24",
3
+ "version": "0.1.25",
4
4
  "description": "CLI app built with React Ink, CodeceptJS, and Playwright",
5
5
  "license": "Elastic-2.0",
6
6
  "type": "module",
package/src/ai/rules.ts CHANGED
@@ -131,6 +131,12 @@ export const fileUploadRule = dedent`
131
131
  </file_upload>
132
132
  `;
133
133
 
134
+ export const formRequirementsRule = dedent`
135
+ <form_requirements>
136
+ Before filling a form that persists data (create/update), read each control's requirements (required, type/format, length, placeholder/aria-describedby hints) from <page_aria> and page HTML — call context() if not visible — and enter values that satisfy them. Search/filter/sort forms that only change the view do not need this.
137
+ </form_requirements>
138
+ `;
139
+
134
140
  // in rage mode we do not protect from irreversible actions
135
141
  export const protectionRule = dedent`
136
142
  <important>
@@ -270,6 +276,8 @@ export const actionRule = dedent`
270
276
  If locator doesn't work, try CSS or XPath locators.
271
277
  If nothing works, use I.clickXY(x, y) as last resort.
272
278
 
279
+ For checkboxes, prefer I.checkOption/I.uncheckOption over I.click.
280
+
273
281
 
274
282
  ### I.fillField
275
283
 
@@ -356,6 +364,19 @@ export const actionRule = dedent`
356
364
  I.selectOption('form select[name=account]', 'Premium');
357
365
  </example>
358
366
 
367
+ ### I.checkOption / I.uncheckOption
368
+
369
+ Set a checkbox/radio to a definite state — idempotent, never toggles. Use for checkboxes instead of I.click. Run via form(), not click().
370
+
371
+ I.checkOption(<locator>, <context>)
372
+ I.uncheckOption(<locator>, <context>)
373
+
374
+ <example>
375
+ I.checkOption('Subscribe');
376
+ I.checkOption({ role: 'checkbox', text: 'Agree' });
377
+ I.uncheckOption('Subscribe', '.preferences');
378
+ </example>
379
+
359
380
  ### I.attachFile
360
381
 
361
382
  Attaches a file to a file input element.
package/src/ai/tester.ts CHANGED
@@ -25,7 +25,7 @@ import { Navigator } from './navigator.ts';
25
25
  import type { Pilot } from './pilot.ts';
26
26
  import { Provider } from './provider.ts';
27
27
  import { Researcher } from './researcher.ts';
28
- import { actionRule, focusedElementRule, locatorRule, multipleTabsRule, protectionRule, sectionContextRule } from './rules.ts';
28
+ import { actionRule, focusedElementRule, formRequirementsRule, locatorRule, multipleTabsRule, protectionRule, sectionContextRule } from './rules.ts';
29
29
  import { TaskAgent } from './task-agent.ts';
30
30
  import { createCodeceptJSTools, createSpecialContextTools } from './tools.ts';
31
31
 
@@ -773,6 +773,8 @@ export class Tester extends TaskAgent implements Agent {
773
773
 
774
774
  ${sectionContextRule}
775
775
 
776
+ ${formRequirementsRule}
777
+
776
778
  ${this.provider.getSystemPromptForAgent('tester', this.explorer.getStateManager().getCurrentState()?.url) || ''}
777
779
  `;
778
780
  }
package/src/ai/tools.ts CHANGED
@@ -307,6 +307,7 @@ export function createCodeceptJSTools(explorer: Explorer, task: Task) {
307
307
 
308
308
  Use cases:
309
309
  - Typing into input fields (I.fillField, I.type)
310
+ - Setting checkboxes/radios to a definite state (I.checkOption, I.uncheckOption)
310
311
  - Working with iframes (switch context with I.switchTo)
311
312
  - Performing multiple form actions in a single batch
312
313
  - Complex interactions requiring sequential commands
@@ -314,6 +315,7 @@ export function createCodeceptJSTools(explorer: Explorer, task: Task) {
314
315
  Example - filling a form with context (PREFERRED):
315
316
  I.fillField('Username', 'John', '.login-form')
316
317
  I.selectOption('Country', 'USA', '.address-section')
318
+ I.checkOption('Agree', '.terms-section')
317
319
  I.attachFile('input[type="file"]', 'path/to/file', '.upload-section')
318
320
 
319
321
  Example - filling a form with ARIA locators: