Skill240 repo starsupdated 20d ago
testdriver:reusable-code
Build maintainable test suites with reusable code patterns
Install in Claude Code
Copygit clone --depth 1 https://github.com/testdriverai/testdriverai /tmp/testdriver-reusable-code && cp -r /tmp/testdriver-reusable-code/ai/skills/testdriver-reusable-code ~/.claude/skills/testdriver-reusable-codeThen start a new Claude Code session; the skill loads automatically.
Definition
SKILL.md
<!-- Generated from reusable-code.mdx. DO NOT EDIT. -->
As your test suite grows, you'll want to extract common patterns into reusable code. This keeps tests DRY, readable, and easy to maintain.
## Helper Functions
The simplest approach is extracting common actions into helper functions. Create a `helpers/` directory for shared utilities:
```javascript test/helpers/auth.js
export async function login(testdriver, { email, password }) {
const emailInput = await testdriver.find('email input');
await emailInput.click();
await testdriver.type(email);
const passwordInput = await testdriver.find('password input');
await passwordInput.click();
await testdriver.type(password);
const loginButton = await testdriver.find('login button');
await loginButton.click();
const result = await testdriver.assert('user is logged in');
return result;
}
export async function logout(testdriver) {
const userMenu = await testdriver.find('user menu');
await userMenu.click();
const logoutButton = await testdriver.find('logout button');
await logoutButton.click();
}
```
<Warning>
**Avoid hardcoding dynamic values in element descriptions.** Element selectors should describe the *type* of element, not specific content that might change.
**❌ Bad:** `await testdriver.find('profile name TestDriver in the top right')`
**✅ Good:** `await testdriver.find('user profile name in the top right')`
Hardcoded values like usernames, product names, or prices will cause tests to fail when the data changes. Use generic descriptions that work regardless of the specific content displayed.
</Warning>
Now import and use these helpers in any test:
```javascript test/checkout.test.mjs
import { describe, expect, it } from "vitest";
import { TestDriver } from "testdriverai/vitest/hooks";
import { login } from './helpers/auth.js';
describe("Checkout", () => {
it("should complete checkout as logged in user", async (context) => {
const testdriver = TestDriver(context);
await testdriver.provision.chrome({
url: 'https://shop.example.com',
});
// Use the helper
await login(testdriver, {
email: 'user@example.com',
password: 'password123'
});
// Continue with checkout steps...
const cartButton = await testdriver.find('cart button');
await cartButton.click();
});
});
```
## Page Objects
For larger test suites, the Page Object pattern encapsulates all interactions with a specific page or component:
```javascript test/pages/LoginPage.js
export class LoginPage {
constructor(testdriver) {
this.td = testdriver;
}
async enterEmail(email) {
const input = await this.td.find('email input');
await input.click();
await this.td.type(email);
}
async enterPassword(password) {
const input = await this.td.find('password input');
await input.click();
await this.td.type(password);
}
async submit() {
const button = await this.td.find('submit button');
await button.click();
}
async login(email, password) {
await this.enterEmail(email);
await this.enterPassword(password);
await this.submit();
}
async assertError(message) {
return await this.td.assert(`error message shows "${message}"`);
}
async assertLoggedIn() {
return await this.td.assert('user dashboard is visible');
}
}
```
Use the page object in your tests:
```javascript test/auth.test.mjs
import { describe, expect, it } from "vitest";
import { TestDriver } from "testdriverai/vitest/hooks";
import { LoginPage } from './pages/LoginPage.js';
describe("Authentication", () => {
it("should show error for invalid credentials", async (context) => {
const testdriver = TestDriver(context);
await testdriver.provision.chrome({
url: 'https://app.example.com/login',
});
const loginPage = new LoginPage(testdriver);
await loginPage.login('invalid@test.com', 'wrongpassword');
const hasError = await loginPage.assertError('Invalid credentials');
expect(hasError).toBeTruthy();
});
it("should redirect to dashboard on success", async (context) => {
const testdriver = TestDriver(context);
await testdriver.provision.chrome({
url: 'https://app.example.com/login',
});
const loginPage = new LoginPage(testdriver);
await loginPage.login('valid@test.com', 'correctpassword');
const isLoggedIn = await loginPage.assertLoggedIn();
expect(isLoggedIn).toBeTruthy();
});
});
```
## Shared Test Fixtures
Create reusable fixtures for common test setup scenarios:
```javascript test/fixtures/index.js
export const testUsers = {
admin: { email: 'admin@example.com', password: 'admin123' },
regular: { email: 'user@example.com', password: 'user123' },
guest: { email: 'guest@example.com', password: 'guest123' },
};
export const testUrls = {
staging: 'https://staging.example.com',
production: 'https://example.com',
};
export async function setupAuthenticatedSession(testdriver, user = testUsers.regular) {
const emailInput = await testdriver.find('email input');
await emailInput.click();
await testdriver.type(user.email);
const passwordInput = await testdriver.find('password input');
await passwordInput.click();
await testdriver.type(user.password);
const loginButton = await testdriver.find('login button');
await loginButton.click();
await testdriver.assert('user is logged in');
}
```
```javascript test/admin.test.mjs
import { describe, expect, it } from "vitest";
import { TestDriver } from "testdriverai/vitest/hooks";
import { testUsers, testUrls, setupAuthenticatedSession } from './fixtures/index.js';
describe("Admin Panel", () => {
it("should access admin settings", async (context) => {
const testdriver = TestDriver(context);
await testdriver.provision.chrome({
url: `${testUrls.staging}/login`,
});
await setupAuthenticatedSession(testdriver, testUsers.admin);
const setMore from this repository
testdriver:aiSkill
Execute natural language tasks using AI
testdriver:assertSkill
Make AI-powered assertions about screen state
testdriver:aws-setupSkill
Deploy TestDriver on your AWS infrastructure using CloudFormation
testdriver:cacheSkill
Speed up tests with screenshot-based caching
testdriver:cachingSkill
1.7x faster test execution with intelligent caching and optimization
testdriver:captchaSkill
Solve captchas using 2captcha service
testdriver:ci-cdSkill
Run TestDriver tests in CI/CD with parallel execution and cross-platform support
testdriver:clickSkill
Click at specific coordinates or on elements