Skip to content

miroslavmyrha/po-generator

Repository files navigation

po-generator

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 link

Now 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 --help

Configuration

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:

  1. Crawl - Find all URLs in your application
  2. Scan - AI analyzes each page for interactive elements
  3. Review - Interactively decide which pages need Page Objects
  4. Generate - Create TypeScript/JavaScript Page Objects
  5. 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:

Development

# Run tests
bun run test

# Type check
bun run typecheck

License

MIT

About

CLI tool for automated Page Object generation using AI

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors