testdriver-agent
How the TestDriver agent behaves on GitHub issues, pull requests, and @mentions
Scroll pages and elements
Claude Code
$ npx -y skills add testdriverai/testdriverai --skill testdriver-scroll --agent claude-code
Codex
$ npx skills add testdriverai/testdriverai --skill testdriver-scroll -a codex -y
Cursor
$ npx skills add testdriverai/testdriverai --skill testdriver-scroll -a cursor -y
Gemini CLI
$ npx skills add testdriverai/testdriverai --skill testdriver-scroll -a gemini-cli -y
GitHub Copilot
$ npx skills add testdriverai/testdriverai --skill testdriver-scroll -a github-copilot -y
OpenCode
$ npx skills add testdriverai/testdriverai --skill testdriver-scroll -a opencode -y
Windsurf
$ npx skills add testdriverai/testdriverai --skill testdriver-scroll -a windsurf -y
name: testdriver:scroll description: Scroll pages and elements
<!-- Generated from scroll.mdx. DO NOT EDIT. -->
Scroll the page or the active element in any direction with the mouse wheel or the keyboard.
<Warning> **Focus Requirements**
A scroll needs focus on the page or on a frame. If an input field or another interactive element has focus, scroll commands can fail. Before you scroll, put the focus on the page:
**If the scroll still does not work**, use the Page Down or Page Up keys directly:
await testdriver.pressKeys(['pagedown']); // Scroll down await testdriver.pressKeys(['pageup']); // Scroll up
</Warning>
await testdriver.scroll(direction, options)
<ParamField path="direction" type="string" default="down"> Direction to scroll: `'up'`, `'down'` </ParamField>
<ParamField path="options" type="object"> <Expandable title="properties"> <ParamField path="amount" type="number" default="300"> Amount to scroll in pixels </ParamField> </Expandable> </ParamField>
`Promise<void>`
// Scroll down (default)
await testdriver.scroll();
// Scroll down 5 clicks
await testdriver.scroll('down', { amount: 5 });
// Scroll up
await testdriver.scroll('up');
// Scroll up 2 clicks
await testdriver.scroll('up', { amount: 2 });// Scroll right
await testdriver.scroll('right', { amount: 3 });
// Scroll left
await testdriver.scroll('left', { amount: 3 });// Mouse wheel scroll (default)
await testdriver.scroll('down', { amount: 3 });
// For keyboard-based scrolling, use pressKeys instead
await testdriver.pressKeys(['pagedown']);<Check> **Make sure that the page has focus before you scroll**
// After typing in an input, unfocus it first
await testdriver.find('email input').click();
await testdriver.type('user@example.com');
// Click elsewhere or press Escape before scrolling
await testdriver.pressKeys(['escape']);
// Or click a non-interactive area
// await testdriver.find('page background').click();
// Now scroll will work properly
await testdriver.scroll('down');
// If scroll still doesn't work, use Page Down directly
// await testdriver.pressKeys(['pagedown']);</Check>
<Check> **Control the scroll distance with the options object**
// For web pages, mouse scroll works well
await testdriver.scroll('down', { amount: 3 });
// For desktop apps or when mouse doesn't work, use keyboard
await testdriver.pressKeys(['pagedown']);</Check>
<Warning> **The keyboard scroll uses Page Down and Page Up**
A keyboard scroll usually moves one "page" each time. This can be more than the click amount that you set. It is more compatible than a mouse scroll, but it is less precise. </Warning>
<AccordionGroup> <Accordion title="Infinite Scroll">
// Scroll multiple times for infinite scroll
for (let i = 0; i < 5; i++) {
await testdriver.scroll('down', { amount: 5 });
await new Promise(r => setTimeout(r, 1000)); // Wait for load
}</Accordion>
<Accordion title="Horizontal Gallery">
// Navigate horizontal carousel
await testdriver.scroll('right', { amount: 3 });
await new Promise(r => setTimeout(r, 500));
const nextImage = await testdriver.find('next image in carousel');
await nextImage.click();</Accordion> </AccordionGroup>
import { beforeAll, afterAll, describe, it } from 'vitest';
import TestDriver from 'testdriverai';
describe('Scrolling', () => {
let testdriver;
beforeAll(async () => {
client = new TestDriver(process.env.TD_API_KEY);
await testdriver.auth();
await testdriver.connect();
});
afterAll(async () => {
await testdriver.disconnect();
});
it('should scroll to find elements', async () => {
await testdriver.focusApplication('Google Chrome');
// Scroll down the page
await testdriver.scroll('down', { amount: 5 });
// Click footer link
const privacyLink = await testdriver.find('Privacy Policy link');
await privacyLink.click();
await testdriver.assert('privacy policy page is displayed');
});
it('should handle infinite scroll', async () => {
await testdriver.focusApplication('Google Chrome');
// Scroll multiple times to load content
for (let i = 0; i < 3; i++) {
await testdriver.scroll('down', { amount: 5 });
await new Promise(r => setTimeout(r, 1500)); // Wait for load
}
// Verify content loaded
await testdriver.assert('more than 10 items are visible');
});
});How the TestDriver agent behaves on GitHub issues, pull requests, and @mentions
Deploy TestDriver on your AWS infrastructure using CloudFormation
How TestDriver learns your app and caches what it discovers for instant, deterministic replays
Produce the "Playwright 1.xx API Review" artifact for a range of commits - the public API additions and the breaking or behavior…
Write, refine, run, and QA promptfoo evaluation suites: promptfooconfig.yaml, prompts, providers, vars, tests, assertions,…
DeepEval evaluation workflow for AI agents and LLM applications. TRIGGER when the user wants to evaluate or improve an AI agent,…