Created
January 6, 2026 10:33
-
-
Save pliablepixels/5f6570bce208b1ea9f18ac69ab9b8e94 to your computer and use it in GitHub Desktop.
Test driven approach
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ## 👤 User | |
| The full walkthrough tests are surfacial. If I want to write human readable instructions on the flow (I want it to go step by step into each screen and test functionality of items), and use that human redable instructions to generate code for e2e tests, what is the best approach? | |
| --- | |
| ## 🤖 Claude | |
| Great question! For human-readable test specifications that generate E2E tests, here are the best approaches for your Playwright setup: | |
| ## Recommended Approaches | |
| ### 1. **BDD with Gherkin + Playwright** (Most Human-Readable) | |
| **Install:** | |
| ```bash | |
| npm install -D @cucumber/cucumber @playwright/test playwright-bdd | |
| ``` | |
| **Write scenarios in `.feature` files:** | |
| ```gherkin | |
| # tests/features/monitor-management.feature | |
| Feature: Monitor Management | |
| As a ZoneMinder user | |
| I want to view and manage my monitors | |
| So that I can monitor my security cameras | |
| Scenario: View live monitor feed | |
| Given I am logged into zmNg | |
| And I have at least one monitor configured | |
| When I navigate to the Monitors page | |
| Then I should see a list of all monitors | |
| And each monitor should show its current status | |
| Scenario: Download monitor snapshot | |
| Given I am on the Monitors page | |
| And I can see "Front Door" monitor | |
| When I click on "Front Door" monitor | |
| And I click the "Download Snapshot" button | |
| Then a snapshot image should be downloaded | |
| And the filename should contain "Front_Door" | |
| Scenario: View monitor properties | |
| Given I am viewing the "Front Door" monitor | |
| When I click the "Properties" button | |
| Then I should see the monitor details dialog | |
| And I should see the monitor ID | |
| And I should see the monitor resolution | |
| And I should see the streaming URL | |
| ``` | |
| **Generate step definitions:** | |
| ```typescript | |
| // tests/steps/monitor-steps.ts | |
| import { Given, When, Then } from '@cucumber/cucumber'; | |
| import { expect } from '@playwright/test'; | |
| Given('I am logged into zmNg', async function() { | |
| await this.page.goto('/'); | |
| // Use existing auth setup | |
| }); | |
| Given('I have at least one monitor configured', async function() { | |
| // API call or check | |
| }); | |
| When('I navigate to the Monitors page', async function() { | |
| await this.page.getByRole('link', { name: 'Monitors' }).click(); | |
| await expect(this.page).toHaveURL(/.*monitors/); | |
| }); | |
| Then('I should see a list of all monitors', async function() { | |
| await expect(this.page.getByTestId('monitor-grid')).toBeVisible(); | |
| }); | |
| ``` | |
| --- | |
| ### 2. **Markdown Test Plans → Code** (Simpler Alternative) | |
| **Write test plans in markdown:** | |
| ```markdown | |
| # tests/test-plans/monitor-workflow.md | |
| ## Test: View and Interact with Monitors | |
| ### Prerequisites | |
| - User is logged in | |
| - At least 2 monitors configured (Front Door, Backyard) | |
| ### Steps | |
| 1. **Navigate to Monitors page** | |
| - Click "Monitors" in sidebar | |
| - Verify URL contains "/monitors" | |
| - Verify page title is "Monitors" | |
| 2. **Verify monitor list loads** | |
| - Count visible monitor cards | |
| - Expect at least 2 monitors shown | |
| - Verify "Front Door" monitor is visible | |
| - Verify "Backyard" monitor is visible | |
| 3. **Check monitor status indicators** | |
| - Verify each monitor shows online/offline status | |
| - Verify each monitor shows stream preview | |
| 4. **Download snapshot from monitor** | |
| - Click on "Front Door" monitor card | |
| - Wait for live view to load | |
| - Click "Download Snapshot" button | |
| - Verify download started | |
| - Verify filename matches pattern: `Front_Door_*.jpg` | |
| 5. **View monitor properties** | |
| - Click "Properties" icon on "Front Door" | |
| - Wait for properties dialog to open | |
| - Verify monitor ID is displayed | |
| - Verify resolution (e.g., "1920x1080") | |
| - Verify streaming URL contains "/cgi-bin/nph-zms" | |
| - Close properties dialog | |
| ### Expected Results | |
| - All monitors load successfully | |
| - Snapshot downloads correctly | |
| - Properties show accurate information | |
| ``` | |
| **Use AI to convert to tests** (or use a script): | |
| ```typescript | |
| // tests/monitors-workflow.spec.ts | |
| import { test, expect } from '@playwright/test'; | |
| test.describe('Monitor Workflow', () => { | |
| test.beforeEach(async ({ page }) => { | |
| // Prerequisites | |
| await page.goto('/monitors'); | |
| // Assume authenticated via global setup | |
| }); | |
| test('View and interact with monitors', async ({ page }) => { | |
| // Step 1: Navigate to Monitors page | |
| await page.getByRole('link', { name: 'Monitors' }).click(); | |
| await expect(page).toHaveURL(/.*monitors/); | |
| await expect(page.getByRole('heading', { name: 'Monitors' })).toBeVisible(); | |
| // Step 2: Verify monitor list loads | |
| const monitorCards = page.locator('[data-testid="monitor-card"]'); | |
| await expect(monitorCards).toHaveCount(2, { timeout: 10000 }); | |
| await expect(page.getByText('Front Door')).toBeVisible(); | |
| await expect(page.getByText('Backyard')).toBeVisible(); | |
| // Step 3: Check monitor status indicators | |
| // ... continue implementation | |
| }); | |
| }); | |
| ``` | |
| --- | |
| ### 3. **Enhanced Comments in Tests** (Minimal Change) | |
| Add detailed comments to existing test structure: | |
| ```typescript | |
| // tests/monitor-management.spec.ts | |
| import { test, expect } from '@playwright/test'; | |
| test.describe('Monitor Management - Complete Workflow', () => { | |
| /** | |
| * TEST SCENARIO: View Live Monitor Feed | |
| * | |
| * GIVEN: User is logged into zmNg with configured monitors | |
| * WHEN: User navigates to Monitors page | |
| * THEN: | |
| * - Monitor list is displayed | |
| * - Each monitor shows name, status, and preview | |
| * - Live streams are loading | |
| */ | |
| test('should display monitor list with live previews', async ({ page }) => { | |
| // STEP 1: Navigate to Monitors page | |
| await page.goto('/monitors'); | |
| // STEP 2: Wait for monitors to load | |
| const monitorGrid = page.locator('[data-testid="monitor-grid"]'); | |
| await expect(monitorGrid).toBeVisible({ timeout: 10000 }); | |
| // STEP 3: Verify monitor count | |
| const monitors = page.locator('[data-testid="monitor-card"]'); | |
| const count = await monitors.count(); | |
| expect(count).toBeGreaterThan(0); | |
| // STEP 4: Verify each monitor has required elements | |
| for (let i = 0; i < count; i++) { | |
| const monitor = monitors.nth(i); | |
| await expect(monitor.locator('[data-testid="monitor-name"]')).toBeVisible(); | |
| await expect(monitor.locator('[data-testid="monitor-status"]')).toBeVisible(); | |
| } | |
| }); | |
| }); | |
| ``` | |
| --- | |
| ## My Recommendation for Your Project | |
| **Use a hybrid approach:** | |
| 1. **Create test plans in markdown** (`tests/test-plans/`) | |
| - Easy to review with non-technical stakeholders | |
| - Can be version controlled | |
| - Serves as documentation | |
| 2. **Use Playwright's built-in features** with detailed test descriptions: | |
| ```typescript | |
| test.describe('Monitor Management', () => { | |
| test('User can view live monitor feed and download snapshot', async ({ page }) => { | |
| await test.step('Navigate to Monitors page', async () => { | |
| await page.getByRole('link', { name: 'Monitors' }).click(); | |
| }); | |
| await test.step('Verify monitor list loads', async () => { | |
| await expect(page.getByTestId('monitor-grid')).toBeVisible(); | |
| }); | |
| await test.step('Click on Front Door monitor', async () => { | |
| await page.getByText('Front Door').click(); | |
| }); | |
| await test.step('Download snapshot', async () => { | |
| const downloadPromise = page.waitForEvent('download'); | |
| await page.getByRole('button', { name: 'Download Snapshot' }).click(); | |
| const download = await downloadPromise; | |
| expect(download.suggestedFilename()).toMatch(/Front_Door.*\.jpg/); | |
| }); | |
| }); | |
| }); | |
| ``` | |
| 3. **Add test IDs to UI components** for reliable selectors: | |
| ```tsx | |
| // In your components | |
| <div data-testid="monitor-card"> | |
| <h3 data-testid="monitor-name">{monitor.name}</h3> | |
| <span data-testid="monitor-status">{monitor.status}</span> | |
| </div> | |
| ``` | |
| **Would you like me to:** | |
| 1. Set up BDD/Gherkin with Playwright? | |
| 2. Create a markdown test plan template? | |
| 3. Show you how to use `test.step()` to make existing tests more readable? | |
| 4. Add data-testid attributes to key UI components? | |
| --- | |
| ## 👤 User | |
| Lets do all of the above but in a new branch | |
| --- | |
| ## 🤖 Claude | |
| I'll set up a comprehensive E2E testing framework with BDD, test plans, and improved test structure in a new branch. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment