npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

pompidou

v1.0.1

Published

CLI tool to auto-generate strongly-typed Page Object Models from Angular components for multiple test frameworks

Downloads

9

Readme

Pompidou

A powerful CLI tool and library that auto-generates strongly-typed Page Object Models (POMs) from Angular components for multiple languages and test frameworks.

Supported Languages

| Language | Framework | File Extension | |----------|-----------|----------------| | TypeScript | Playwright | .po.ts | | TypeScript | Cypress | .po.ts | | TypeScript | WebdriverIO | .po.ts | | Java | Selenium | .java | | Java | Playwright | .java | | C# | Playwright | .cs | | C# | Selenium | .cs | | Python | Playwright | .py | | Python | Selenium | .py |

Features

  • 🔍 Automatic Discovery: Scans your Angular project for *.component.ts files
  • 🎯 Element Mapping: Extracts elements with data-testid attributes from HTML templates
  • 🔗 Typed Transitions: Parses @pom-return JSDoc tags for typed navigation between POMs
  • 🌍 Multi-Language: Generates POMs in TypeScript, Java, C#, or Python
  • 🛠️ Templating Engine: Uses Handlebars for customizable code generation
  • Fail-Fast: Strict validation with clear, actionable error messages
  • 📦 Publishable Package: Structured as a valid npm package

Installation

npm install pompidou --save-dev
# or
yarn add pompidou --dev

Quick Start

CLI Usage

# TypeScript + Playwright (default)
npx pompidou ./src/app ./e2e/page-objects

# Java + Selenium
npx pompidou ./src/app ./src/test/java/pages -l java-selenium -p com.myapp.pages

# C# + Playwright
npx pompidou ./src/app ./Tests/Pages -l csharp-playwright -p MyApp.Tests.Pages

# Python + Selenium
npx pompidou ./src/app ./tests/pages -l python-selenium

# List all supported languages
npx pompidou list-languages

Scan for missing locators

Run a static scan to verify that components are annotated correctly and that common display/input elements have the locator attribute (default data-testid):

npx pompidou scan ./src/app --locator data-testid --verbose

The scan prints a summary and per-component issues. Exit code is 0 when no issues are found, 2 when issues exist.

Programmatic Usage

import { generate, generateMultiLanguage } from 'pompidou';

// TypeScript + Playwright (default)
const summary = await generate({
  sourceDir: './src/app',
  outputDir: './e2e/page-objects',
  generateIndex: true,
});

// Java + Selenium
const javaSummary = await generateMultiLanguage({
  sourceDir: './src/app',
  outputDir: './src/test/java/pages',
  language: 'java-selenium',
  package: 'com.myapp.pages',
});

console.log(`Generated ${summary.successCount} POMs`);

How It Works

1. Element Mapping

Add data-testid attributes to your Angular templates:

<!-- login.component.html -->
<form>
  <input data-testid="username-input" type="text" />
  <input data-testid="password-input" type="password" />
  <button data-testid="submit-btn">Login</button>
</form>

2. Typed Transitions

Use the @pom-return JSDoc tag to define typed navigation:

// login.component.ts
@Component({
  selector: 'app-login',
  templateUrl: './login.component.html'
})
export class LoginComponent {
  /**
   * Performs login action
   * @pom-return {DashboardPO}
   */
  login(username: string, password: string): void {
    this.authService.login(username, password).subscribe(() => {
      this.router.navigate(['/dashboard']);
    });
  }
}

Generated Output

TypeScript + Playwright

import { Page, Locator } from '@playwright/test';
import { DashboardPO } from './dashboard.po';

export class LoginPO {
  protected readonly page: Page;

  constructor(page: Page) {
    this.page = page;
  }

  getUsernameInput(): Locator {
    return this.page.locator('[data-testid="username-input"]');
  }

  getPasswordInput(): Locator {
    return this.page.locator('[data-testid="password-input"]');
  }

  getSubmitBtn(): Locator {
    return this.page.locator('[data-testid="submit-btn"]');
  }

  async login(username: string, password: string): Promise<DashboardPO> {
    // TODO: Implement action logic
    return new DashboardPO(this.page);
  }
}

Java + Selenium

package com.myapp.pages;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;

public class LoginPO {
    protected final WebDriver driver;

    @FindBy(css = "[data-testid='username-input']")
    private WebElement usernameInput;

    @FindBy(css = "[data-testid='password-input']")
    private WebElement passwordInput;

    @FindBy(css = "[data-testid='submit-btn']")
    private WebElement submitBtn;

    public LoginPO(WebDriver driver) {
        this.driver = driver;
        PageFactory.initElements(driver, this);
    }

    public WebElement getUsernameInput() {
        return usernameInput;
    }

    public DashboardPO login(String username, String password) {
        // TODO: Implement action logic
        return new DashboardPO(driver);
    }
}

C# + Playwright

using Microsoft.Playwright;

namespace MyApp.Tests.Pages
{
    public class LoginPO
    {
        protected readonly IPage Page;

        public LoginPO(IPage page)
        {
            Page = page;
        }

        public ILocator GetUsernameInput() => Page.Locator("[data-testid='username-input']");

        public async Task<DashboardPO> LoginAsync(string username, string password)
        {
            // TODO: Implement action logic
            return new DashboardPO(Page);
        }
    }
}

CLI Options

Usage: pompidou [options] <source> <output>

Arguments:
  source                      Source directory containing Angular components
  output                      Output directory for generated POM files

Options:
  -V, --version               output the version number
  -l, --language <lang>       Target language and framework (default: "typescript-playwright")
  -p, --package <name>        Package/namespace for generated code
  -b, --base-class <name>     Base class name for POMs
  -s, --suffix <suffix>       Suffix for POM class names (default: "PO")
  -i, --index                 Generate index barrel file (default: false)
  -f, --force                 Overwrite existing files (default: false)
  --include <patterns...>     File patterns to include
  --exclude <patterns...>     File patterns to exclude
  --templates <dir>           Custom templates directory
  --strict                    Fail on unknown POM references (default: true)
  --no-strict                 Allow unknown POM references
  -v, --verbose               Enable verbose logging (default: false)
  -h, --help                  display help for command

Commands:
  list-languages              List all supported output languages

Custom Templates

You can provide custom Handlebars templates to customize the generated code:

pompidou ./src/app ./output --templates ./my-templates

Template directory structure:

my-templates/
├── typescript-playwright/
│   ├── page-object.hbs
│   └── index.hbs
├── java-selenium/
│   └── page-object.hbs
└── csharp-playwright/
    └── page-object.hbs

Template Data

Templates receive the following data:

interface TemplateData {
  className: string;           // POM class name
  sourceClassName: string;     // Angular component class name
  sourceFilePath: string;      // Source file path
  baseClass?: string;          // Base class to extend
  package?: string;            // Package/namespace
  imports: TemplateImport[];   // Import statements
  elements: TemplateElement[]; // Element getters
  actions: TemplateAction[];   // Action methods
  config: LanguageConfig;      // Language configuration
}

Available Helpers

  • Naming: pascalCase, camelCase, snakeCase, kebabCase, screamingSnakeCase
  • Conditionals: eq, neq, gt, gte, lt, lte, and, or, not
  • Arrays: first, last, length, isEmpty, isNotEmpty, join
  • Types: javaType, csharpType, pythonType
  • Documentation: javadoc, xmldoc, pydoc

Error Handling

The generator follows a fail-fast philosophy with clear, actionable error messages:

❌ Error during generation:

Validation failed with 2 error(s):
  1. [UNKNOWN_POM_REFERENCE] Method 'goToProfile' in 'login.component.ts' 
     references unknown POM 'ProfilePO'. Available POMs: LoginPO, DashboardPO.
  
  2. [INVALID_TEST_ID] Invalid data-testid '   ' in template 'login.component.html': 
     data-testid cannot be empty.

Error Types

| Error | Description | |-------|-------------| | SourceDirectoryNotFoundError | Source directory doesn't exist | | NoComponentsFoundError | No *.component.ts files found | | TemplateNotFoundError | Template file referenced but missing | | InvalidTestIdError | Invalid data-testid value | | InvalidPomReturnTagError | Malformed @pom-return tag | | UnknownPOMReferenceError | References non-existent POM class |

API Reference

generate(config, options?)

Main function for TypeScript + Playwright output.

generateMultiLanguage(config, options?)

Multi-language generation using templates.

getSupportedLanguages()

Returns list of supported language/framework combinations.

scanComponents(config)

Scans for Angular components without generating POMs.

TemplateEngine

Direct access to the templating engine for custom integrations.

Contributing

Contributions are welcome! To add a new language:

  1. Create a new directory in src/templates/
  2. Add page-object.hbs template
  3. Add language config to LANGUAGE_CONFIGS in types.ts
  4. Add tests

License

MIT License - see the LICENSE file for details.