# Create Pom

> |

- **Type:** Skill
- **Install:** `agentstack add skill-agentmantis-test-skills-create-pom`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [agentmantis](https://agentstack.voostack.com/s/agentmantis)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [agentmantis](https://github.com/agentmantis)
- **Source:** https://github.com/agentmantis/test-skills/tree/main/skills/create-pom

## Install

```sh
agentstack add skill-agentmantis-test-skills-create-pom
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Create Page Object Model

Generate a POM class for the specified page following all E2E test conventions.

---

## Workflow

1. **Determine the page name** from the user's request (e.g., "Settings" → `settings.page.ts`)
2. **Check if a POM already exists** for this page in `e2e/poms/`. If so, add methods to the existing POM — do NOT create a second POM for the same page
3. **Identify the base page class** in `e2e/poms/base.page.ts` and extend it
4. **Read the target page** in the application to understand its elements and interactions
5. **Generate the POM file** following the template below
6. **Verify** the file compiles with no TypeScript errors

---

## Rules

- **One page = one POM** — every distinct page/view gets exactly one POM file
- **All POMs extend the base page class** — check `e2e/poms/base.page.ts` for the abstract class
- **Implement `setUp()` and `tearDown()`** — inherited from the base class
- **Reusable helpers belong in `BasePage`** — if a helper method is useful across multiple POMs (e.g., `waitForToast`, `dismissModal`), it must live in `BasePage`, not in a derived POM. Derived POMs should contain only page-specific behavior. If you find yourself writing the same helper in a second POM, promote it to `BasePage` immediately
- **NEVER reference another POM from within a POM** — if a test needs multiple pages, the spec file orchestrates between POMs
- **Detailed JSDoc on every public method** — describe what it does step by step, with `@param` tags
- **Use the selector priority order**: `getByRole()` > `getByLabel()` > `getByText()` > `getByPlaceholder()` > `locator()`

---

## POM Structure

Organise every POM with these clearly separated sections using comment banners:

```typescript
import { Page, Locator, expect } from '@playwright/test';
// TODO: Import your project's base page class
import { BasePage } from './base.page';

export class FeaturePage extends BasePage {
    constructor(page: Page) {
        super(page);
    }

    // ==========================================
    // LIFECYCLE (from BasePage)
    // ==========================================

    /**
     * Navigates to the feature page and cleans up any stale data
     * left by previous failed test runs.
     *
     * Steps:
     * 1. Navigates to /feature via direct URL.
     * 2. Waits for the page heading to be visible.
     * 3. Deletes any items matching the test data pattern.
     */
    async setUp(): Promise {
        // TODO: Implement navigation and cleanup
    }

    /**
     * Cleans up any data created during the test suite.
     *
     * Steps:
     * 1. Navigates to /feature.
     * 2. Deletes all items created by this test run.
     */
    async tearDown(): Promise {
        // TODO: Implement cleanup
    }

    // ==========================================
    // LOCATORS
    // ==========================================

    /** The main heading of the feature page. */
    get heading(): Locator {
        return this.page.getByRole('heading', { name: 'Feature Name' });
    }

    /** The "Create" button that opens the creation modal. */
    get createButton(): Locator {
        return this.page.getByRole('button', { name: /create/i });
    }

    // TODO: Add locators for all interactive elements on this page

    // ==========================================
    // NAVIGATION
    // ==========================================

    /**
     * Navigates directly to the feature page via URL.
     *
     * Steps:
     * 1. Calls page.goto('/feature').
     * 2. Asserts the page heading is visible.
     * 3. Asserts the URL contains '/feature'.
     */
    async navigateToPage(): Promise {
        await this.page.goto('/feature');
        await expect(this.heading).toBeVisible();
        await expect(this.page).toHaveURL(/\/feature/);
    }

    // ==========================================
    // VERIFICATION
    // ==========================================

    /**
     * Verifies an item appears in the list with the expected name.
     *
     * Steps:
     * 1. Locates the item row by name text.
     * 2. Asserts the row is visible.
     *
     * @param name - The expected item name
     */
    async verifyItemExists(name: string): Promise {
        await expect(
            this.page.getByRole('row', { name: new RegExp(name, 'i') })
        ).toBeVisible();
    }

    // ==========================================
    // CREATE
    // ==========================================

    /**
     * Creates a new item via the creation modal.
     *
     * Steps:
     * 1. Clicks the "Create" button to open the modal.
     * 2. Fills in the name field.
     * 3. Clicks "Submit" and waits for the modal to close.
     *
     * @param name - Display name for the new item
     */
    async createItem(name: string): Promise {
        await this.createButton.click();
        const modal = this.page.getByRole('dialog');
        await modal.getByLabel('Name').fill(name);
        await modal.getByRole('button', { name: 'Submit' }).click();
        await expect(modal).toBeHidden();
    }

    // ==========================================
    // EDIT
    // ==========================================

    // TODO: Add edit methods

    // ==========================================
    // DELETE
    // ==========================================

    // TODO: Add delete methods
}
```

---

## JSDoc Requirements

Every public method MUST have a JSDoc comment with:

1. **Summary line** — what the method does
2. **Steps block** — numbered list of what happens when called
3. **@param tags** — for every parameter
4. **@returns tag** — if the method returns a value

This is critical because LLMs read these comments to understand what actions are available and generate test specs from them.

```typescript
/**
 * Updates an existing item's name and value.
 *
 * Steps:
 * 1. Locates the item row by its current name.
 * 2. Clicks the "Edit" button within that row.
 * 3. Clears and fills the name field with the new name.
 * 4. Clears and fills the value field with the new value.
 * 5. Clicks "Save" and waits for the edit modal to close.
 * 6. Waits for the success toast notification to appear.
 *
 * @param currentName - The item's current display name (used to locate the row)
 * @param newName     - The new display name
 * @param newValue    - The new value
 */
async editItem(currentName: string, newName: string, newValue: string): Promise {
```

---

## Naming

- File: `e2e/poms/{feature}.page.ts` (lowercase, kebab-case feature name)
- Class: `{Feature}Page` (PascalCase)
- The feature name must match the corresponding spec and test-data files

See [references/pom-template.md](references/pom-template.md) for the full boilerplate.

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [agentmantis](https://github.com/agentmantis)
- **Source:** [agentmantis/test-skills](https://github.com/agentmantis/test-skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-agentmantis-test-skills-create-pom
- Seller: https://agentstack.voostack.com/s/agentmantis
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
