GitHub·· 7 天前AI 评分28
po-generator:用 AI 自动生成 Playwright Page Object 的 CLI 工具
miroslavmyrha/po-generator
AI 导读
开源 CLI 工具 po-generator 可从 Web 应用自动爬取全部 URL,通过 OpenAI 兼容 API 调用 LLM 分析页面交互元素并生成稳定的 Playwright Page Object 与测试文件。
正文
CLI tool for automated Page Object generation from web applications using AI.
Crawls your application, analyzes pages with AI (via OpenAI-compatible API), and generates Playwright Page Objects automatically.
Features
- Automatic crawling - Discovers all URLs in your application
- AI-powered analysis - Uses LLM to identify interactive elements and generate stable selectors
- Multi-framework support - Vuetify, Symfony (Stimulus/Bootstrap), or generic websites
- Modal detection - Automatically finds and analyzes modal dialogs
- TypeScript output - Generates typed Page Objects
- Interactive review - Decide which pages become Page Objects
- Test generation - AI generates Playwright test files from Page Objects
Installation
Global installation (recommended)
git clone https://github.com/miroslavmyrha/po-generator.git
cd po-generator
bun install
bun linkNow you can use po-gen command anywhere:
po-gen --help po-gen init po-gen run
Local installation
git clone https://github.com/miroslavmyrha/po-generator.git
cd po-generator
bun install
node --import tsx bin/po-gen.ts --helpConfiguration
Copy the example environment file and configure:
cp .env.example .env
Or run the interactive setup:
po-gen init
Environment Variables
# Application PO_GEN_BASE_URL=http://localhost:5173 PO_GEN_FRAMEWORK=generic # vuetify | symfony | generic # Authentication (optional) PO_GEN_AUTH_ENABLED=true PO_GEN_LOGIN_URL=/login PO_GEN_USERNAME=your@email.com PO_GEN_PASSWORD=yourpassword PO_GEN_SUCCESS_URL=/dashboard # AI API (OpenAI-compatible, e.g., Open WebUI, Ollama) PO_GEN_AI_URL=http://localhost:3000/api/v1 PO_GEN_AI_KEY=sk-xxx PO_GEN_AI_MODEL=llama3 # Output PO_GEN_OUTPUT_DIR=./output
Usage
Full workflow
po-gen run
This will:
- Crawl - Find all URLs in your application
- Scan - AI analyzes each page for interactive elements
- Review - Interactively decide which pages need Page Objects
- Generate - Create TypeScript/JavaScript Page Objects
- Test-gen - AI generates Playwright test files for each Page Object
Individual commands
# Initialize configuration po-gen init # Crawl application and create sitemap po-gen crawl # AI scan for elements po-gen scan # Interactive review of AI decisions po-gen review # Generate Page Objects po-gen generate # Generate Playwright tests from Page Objects po-gen test-gen
Command options
# Scan with specific framework po-gen scan --framework symfony # Skip interactive review po-gen run --skip-review # Skip test generation in full workflow po-gen run --skip-tests # Generate TypeScript files po-gen generate --typescript # Scan specific page only po-gen scan --page /dashboard # Show help for any command po-gen crawl --help
Output Structure
output/
├── sitemap.json # All discovered URLs
├── scanned/ # AI analysis per page
│ ├── dashboard.json
│ └── users.json
├── decisions.json # Page Object decisions
├── pages/ # Generated Page Objects
│ ├── dashboard-page.ts
│ ├── users-page.ts
│ └── index.ts
└── tests/ # Generated Playwright tests
├── dashboard.spec.ts
└── users.spec.ts
Generated Page Object Example
import { Page, Locator } from '@playwright/test'; /** * Page Object for /dashboard * Main dashboard with user management * * @generated Automatically generated by po-generator */ export class DashboardPage { page: Page; url: string; constructor(page: Page) { this.page = page; this.url = '/dashboard'; /** Search input field */ this.searchField = page.locator('.v-text-field:has-text("Search") input'); /** Add new user button */ this.addUserBtn = page.locator('.v-btn:has-text("Add User")'); /** Data table with users */ this.dataTable = page.locator('.v-data-table'); } async goto() { await this.page.goto(this.url); await this.page.waitForLoadState('networkidle'); } async fillSearchField(value: string) { await this.searchField.locator('input').fill(value); } async clickAddUserBtn() { await this.addUserBtn.click(); } }
Generated Test Example
import { test, expect } from '@playwright/test'; import { DashboardPage } from '../pages/dashboard-page'; test.describe('Dashboard Page Tests', () => { test('should search for users', async ({ page }) => { const dashboardPage = new DashboardPage(page); await dashboardPage.goto(); await dashboardPage.fillSearchField('John'); await expect(page.locator('.v-data-table')).toBeVisible(); }); test('should open add user dialog', async ({ page }) => { const dashboardPage = new DashboardPage(page); await dashboardPage.goto(); await dashboardPage.clickAddUserBtn(); await expect(page.locator('.v-dialog')).toBeVisible(); }); });
Framework Support
Vuetify
- Recognizes all Vuetify 3 components (v-btn, v-text-field, v-select, v-dialog, etc.)
- Proper selectors for Vuetify's DOM structure
Symfony
- Stimulus controllers and actions (
data-controller,data-action) - Turbo frames and streams
- Bootstrap components
- Embedded Vue.js components
Generic
- Standard HTML elements (button, input, select, a)
- Common patterns (forms, modals, tables)
- JavaScript event handlers
AI API Compatibility
Works with any OpenAI-compatible API:
- Open WebUI
- Ollama (with OpenAI compatibility)
- LM Studio
- OpenAI API
- Azure OpenAI
Development
# Run tests bun run test # Type check bun run typecheck
License
MIT
来源:GitHub · github.com