sitesmith: playwright e2e suite (locked/cap/bonus/build+patch)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,7 @@
|
|||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"test": "playwright test tests/site-builder.spec.ts --reporter=list",
|
"test": "playwright test tests/site-builder.spec.ts --reporter=list",
|
||||||
"test:headed": "playwright test tests/site-builder.spec.ts --reporter=list --headed",
|
"test:headed": "playwright test tests/site-builder.spec.ts --reporter=list --headed",
|
||||||
|
"test:e2e:sitesmith": "playwright test tests/sitesmith.spec.ts --reporter=list",
|
||||||
"test:unit": "vitest run",
|
"test:unit": "vitest run",
|
||||||
"test:unit:watch": "vitest"
|
"test:unit:watch": "vitest"
|
||||||
},
|
},
|
||||||
|
|||||||
72
craft/tests/sitesmith.spec.ts
Normal file
72
craft/tests/sitesmith.spec.ts
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
import { test, expect } from '@playwright/test';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sitesmith E2E. Requires staging users pre-created on whp-staging:
|
||||||
|
* - sitesmith_disabled (no entitlement)
|
||||||
|
* - sitesmith_enabled (sitesmith_enabled=1, cap=50, 0 used)
|
||||||
|
* - sitesmith_capped (sitesmith_enabled=1, cap=2, 2 used)
|
||||||
|
* - sitesmith_bonus (sitesmith_enabled=0, bonus=2)
|
||||||
|
*
|
||||||
|
* Env:
|
||||||
|
* PLAYWRIGHT_BASE_URL=https://192.168.1.105:8080
|
||||||
|
* SITESMITH_TEST_PASSWORD=...
|
||||||
|
*/
|
||||||
|
|
||||||
|
const BASE = process.env.PLAYWRIGHT_BASE_URL || 'http://192.168.1.105:8080';
|
||||||
|
const PWD = process.env.SITESMITH_TEST_PASSWORD || 'changeme';
|
||||||
|
|
||||||
|
async function login(page: any, username: string) {
|
||||||
|
await page.goto(BASE);
|
||||||
|
// WHP login uses input[name="user"], not input[name="username"]
|
||||||
|
await page.fill('input[name="user"]', username);
|
||||||
|
await page.fill('input[name="password"]', PWD);
|
||||||
|
await page.click('button[type="submit"], input[type="submit"]');
|
||||||
|
await page.waitForURL('**/index.php**');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function openSiteBuilder(page: any) {
|
||||||
|
await page.goto(`${BASE}/?page=site-builder`);
|
||||||
|
await page.click('a:has-text("Open Editor")');
|
||||||
|
}
|
||||||
|
|
||||||
|
test('locked: disabled user sees upgrade banner', async ({ page }) => {
|
||||||
|
await login(page, 'sitesmith_disabled');
|
||||||
|
await openSiteBuilder(page);
|
||||||
|
await page.click('button:has-text("Sitesmith")');
|
||||||
|
await expect(page.getByText('Sitesmith is a paid addon')).toBeVisible();
|
||||||
|
await expect(page.getByRole('link', { name: /Upgrade your plan/ })).toBeVisible();
|
||||||
|
await expect(page.locator('textarea[placeholder*="Upgrade"]')).toBeDisabled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('cap reached: enabled but at cap', async ({ page }) => {
|
||||||
|
await login(page, 'sitesmith_capped');
|
||||||
|
await openSiteBuilder(page);
|
||||||
|
await page.click('button:has-text("Sitesmith")');
|
||||||
|
await expect(page.getByText(/Monthly cap reached/)).toBeVisible();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('bonus: bonus credits allow chat when disabled', async ({ page }) => {
|
||||||
|
await login(page, 'sitesmith_bonus');
|
||||||
|
await openSiteBuilder(page);
|
||||||
|
await page.click('button:has-text("Sitesmith")');
|
||||||
|
await expect(page.locator('textarea[placeholder*="Describe"]')).toBeEnabled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('full build → patch preserves manual edit', async ({ page }) => {
|
||||||
|
test.setTimeout(180_000);
|
||||||
|
await login(page, 'sitesmith_enabled');
|
||||||
|
await openSiteBuilder(page);
|
||||||
|
await page.click('button:has-text("Sitesmith")');
|
||||||
|
await page.fill('textarea[placeholder*="Describe"]', 'Two-page site for a small bakery. Friendly tone. Hero with cupcakes.');
|
||||||
|
await page.click('button:has-text("→")');
|
||||||
|
await expect(page.getByText('Replace your entire site?')).toBeVisible({ timeout: 90_000 });
|
||||||
|
await page.click('button:has-text("Replace site")');
|
||||||
|
await expect(page.locator('h1').first()).toBeVisible({ timeout: 30_000 });
|
||||||
|
await page.locator('h1').first().click();
|
||||||
|
await page.keyboard.press('Control+A');
|
||||||
|
await page.keyboard.type('Custom Manual Edit');
|
||||||
|
await page.fill('textarea[placeholder*="Describe"]', 'add a 3-tier pricing section');
|
||||||
|
await page.click('button:has-text("→")');
|
||||||
|
await expect(page.locator('h1:has-text("Custom Manual Edit")')).toBeVisible({ timeout: 90_000 });
|
||||||
|
await expect(page.getByText(/pricing/i)).toBeVisible();
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user