From fa2eaf7919567a3b442c7a319f530adf74f52c5e Mon Sep 17 00:00:00 2001 From: bfintal Date: Tue, 11 Aug 2026 19:27:09 +0800 Subject: [PATCH] Expand Playwright e2e coverage for free gaps and premium bulk. Add settings, upload surfaces, post-upload stats, and freemium specs, plus a premium suite and harness so upload/settings regressions are caught in CI. --- .gitignore | 1 + AGENTS.md | 5 +- e2e/fixtures/sample-large.jpg | Bin 0 -> 132462 bytes e2e/fixtures/sample.png | Bin 0 -> 18726 bytes e2e/playground-blueprint.premium.json | 19 ++ e2e/readme.md | 83 +++++++-- e2e/test-utils/index.ts | 16 ++ e2e/test-utils/media.ts | 175 +++++++++++++++++-- e2e/test-utils/settings.ts | 83 +++++++++ e2e/tests/freemium.spec.ts | 80 +++++++++ e2e/tests/post-upload-stats.spec.ts | 44 +++++ e2e/tests/premium/bulk-optimizer.spec.ts | 139 +++++++++++++++ e2e/tests/premium/settings-unlocked.spec.ts | 44 +++++ e2e/tests/settings.spec.ts | 100 +++++++++++ e2e/tests/upload-surfaces.spec.ts | 184 ++++++++++++++++++++ package.json | 2 + playwright.config.js | 1 + playwright.premium.config.js | 59 +++++++ src/admin/class-admin.php | 4 +- 19 files changed, 1004 insertions(+), 35 deletions(-) create mode 100644 e2e/fixtures/sample-large.jpg create mode 100644 e2e/fixtures/sample.png create mode 100644 e2e/playground-blueprint.premium.json create mode 100644 e2e/test-utils/settings.ts create mode 100644 e2e/tests/freemium.spec.ts create mode 100644 e2e/tests/post-upload-stats.spec.ts create mode 100644 e2e/tests/premium/bulk-optimizer.spec.ts create mode 100644 e2e/tests/premium/settings-unlocked.spec.ts create mode 100644 e2e/tests/settings.spec.ts create mode 100644 e2e/tests/upload-surfaces.spec.ts create mode 100644 playwright.premium.config.js diff --git a/.gitignore b/.gitignore index 9e8c0ae..6ede1b8 100644 --- a/.gitignore +++ b/.gitignore @@ -34,6 +34,7 @@ Thumbs.db wp-auth.json e2e/.auth/ playwright-report/ +playwright-report-premium/ test-results/ blob-report/ .playwright-browsers/ diff --git a/AGENTS.md b/AGENTS.md index ef7b116..0add2ca 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -51,8 +51,11 @@ Roadmap / version targeting: [org project #12](https://github.com/orgs/gambitph/ ### Testing Playwright for UI / e2e (`e2e/`, `@wp-playground/cli` — no Docker). -Run with `npm run test:e2e` (or `npm run test:debug` for the UI) after `npm run build:e2e`. +Run free with `npm run test:e2e` after `npm run build:e2e`. +With `pro__premium_only/` mounted, run premium with `npm run test:e2e:premium` after `npm run build:e2e:premium`. See [`e2e/readme.md`](./e2e/readme.md). +Free-repo CI runs the free suite only. +Premium-repo CI runs free then premium. There is no PHPUnit suite today - prefer Playwright for regressions that matter to upload and settings flows. ## Free / premium diff --git a/e2e/fixtures/sample-large.jpg b/e2e/fixtures/sample-large.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5dba7824ccbd73053cb24596e5cdbf00ffc18d2c GIT binary patch literal 132462 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

>qoZ;peu#1IKO_&zUu6#r*yX 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 H{QLYLLAXM3 literal 0 HcmV?d00001 diff --git a/e2e/fixtures/sample.png b/e2e/fixtures/sample.png new file mode 100644 index 0000000000000000000000000000000000000000..98d89b2bfb52a9a04adefad6503c773adc8fd122 GIT binary patch literal 18726 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 e;^oKB;r|1jwf66-+kYAW0000 'activated',\n\t'install_id' => 'e2e-install-id',\n\t'activation_params' => [\n\t\t'uid' => $uid,\n\t\t'license_key' => 'e2e-license-key',\n\t],\n\t'install_data' => [\n\t\t'license_plan_name' => 'premium',\n\t\t'install_public_key' => 'e2e-public',\n\t\t'install_secret_key' => 'e2e-secret',\n\t],\n], false );\n" + } + ] +} diff --git a/e2e/readme.md b/e2e/readme.md index f33492e..20a6019 100644 --- a/e2e/readme.md +++ b/e2e/readme.md @@ -1,7 +1,8 @@ # E2E Testing -Cimo's end-to-end tests verify that client-side upload interception actually -converts JPEG uploads to WebP across the main WordPress admin surfaces. +Cimo's end-to-end tests verify client-side upload interception, settings, +post-upload stats, freemium chrome, and (when premium is mounted) bulk +optimization across WordPress admin. WordPress is provided by [`@wp-playground/cli`](https://www.npmjs.com/package/@wp-playground/cli) (WASM PHP + SQLite, **no Docker**). Playwright's `webServer` boots it @@ -11,15 +12,22 @@ automatically before the suite runs. Just Node **20+** — no Docker, Composer, or separate WordPress install. +For **premium** specs you also need `pro__premium_only/` checked out under +the free plugin root (clone `bfintal/cimo-premium` into that directory). +Playground mounts the plugin tree as a real directory, so a symlink that +points outside the mount will not expose premium files inside WASM PHP. + ## Usage +### Free suite + Build the plugin assets first (Playground mounts this repo; enqueue needs `build/`): ```bash npm run build:e2e ``` -Run e2e tests (Playground starts on port `9410` if nothing is already listening): +Run free e2e tests (Playground starts on port `9410` if nothing is already listening): ```bash npm run test:e2e @@ -31,22 +39,50 @@ or with the Playwright UI: npm run test:debug ``` -Locally, `playwright.config.js` reuses an already-running Playground on port -`9410` when present (fast repeat runs). In CI it always boots fresh. If a stale +### Premium suite + +```bash +# Mount premium (once), e.g.: +# ln -sfn /path/to/cimo-premium pro__premium_only + +npm run build:e2e:premium +npm run test:e2e:premium +``` + +Premium uses port `9411`, `playwright.premium.config.js`, and +`e2e/playground-blueprint.premium.json` (seeds a mock Freemius `premium` plan). + +After premium builds, restore the free build type if you need free packaging: + +```bash +node scripts/update-build-type.js free +``` + +Locally, Playwright reuses an already-running Playground on the suite's port +when present (fast repeat runs). In CI it always boots fresh. If a stale instance is misbehaving after editing PHP/JS that Playground mounted at boot, -kill whatever is listening on `9410` and re-run. +kill whatever is listening on that port and re-run. -Optional overrides (defaults are set in `playwright.config.js`): +Optional overrides (defaults differ per config): ``` -WP_PORT=9410 +WP_PORT=9410 # free; premium config defaults to 9411 WP_BASE_URL=http://127.0.0.1:9410 WP_USERNAME=admin WP_PASSWORD=password ``` +## CI + +| Repo | Workflow | Suites | +|------|----------|--------| +| Free (`gambitph/Cimo`) | `.github/workflows/e2e-tests.yml` | Free only (`build:e2e` → `test:e2e`) | +| Premium (`bfintal/cimo-premium`) | `pro__premium_only/.github/workflows/e2e-tests.yml` | Free then premium (checks out free as root + premium as `pro__premium_only/`) | + ## What is covered +### Free + | Surface | Flow | |---------|------| | Image block | Upload button → JPG → WebP | @@ -54,16 +90,33 @@ WP_PASSWORD=password | Block editor | Drop JPG on canvas → WebP image block | | Page sidebar | Drop JPG on Featured Image → WebP | | Media → Add New | File picker → JPG → WebP in library | +| Settings | Load/save, quality + max dimension affect upload | +| Media Library grid | Drop → WebP | +| Media modal | Select Files → WebP | +| PNG / multi-file | Convert to WebP | +| Progress modal | Cancel when visible | +| Post-upload | Sidebar stats + attachment meta box | +| Freemium | Disabled premium controls, bulk upsell, plugins links | + +### Premium (`e2e/tests/premium/`) + +| Surface | Flow | +|---------|------| +| Settings | Gated controls enabled; working bulk UI (not upsell) | +| Bulk optimizer | Progress, complete 4 images under timeout, stop mid-run | ## Files | Path | Role | | --- | --- | -| `../playwright.config.js` | Boots `@wp-playground/cli` as Playwright's `webServer`; auth/`baseURL`/storage state | -| `playground-blueprint.json` | Logs in as `admin`, activates Cimo | +| `../playwright.config.js` | Free suite; Playground on 9410; ignores `tests/premium/` | +| `../playwright.premium.config.js` | Premium suite; Playground on 9411 | +| `playground-blueprint.json` | Login + activate Cimo (free) | +| `playground-blueprint.premium.json` | Activate + seed Freemius premium plan | | `config/global-setup.js` | Cookie-authenticates via `RequestUtils.setup()`, persists `storageState` | -| `test-utils/` | Shared fixtures + upload/drop helpers | -| `tests/*.spec.ts` | Browser-driven upload interception specs | +| `test-utils/` | Shared fixtures + upload/settings/drop helpers | +| `tests/*.spec.ts` | Free browser specs | +| `tests/premium/*.spec.ts` | Premium browser specs | | `.auth/` | Gitignored; written by global setup | ## Troubleshooting @@ -71,9 +124,11 @@ WP_PASSWORD=password - **`browserType.launch: Executable doesn't exist`** — run `npx playwright install chromium` once per machine. - **Stale plugin behaviour after editing PHP** — Playground snapshots the - mount at boot. Stop the process on port `9410` and re-run. + mount at boot. Stop the process on the suite port and re-run. - **Composer/settings never appear / `cimoSettings` missing** — run - `npm run build:e2e` so `build/admin/` exists for enqueue. + `npm run build:e2e` (or `build:e2e:premium`) so `build/admin/` exists for enqueue. +- **Premium suite missing Bulk Optimizer** — ensure `pro__premium_only/` is present, + `CIMO_BUILD` is `premium`, and the Freemius seed in the premium blueprint applied. ## Dev Notes diff --git a/e2e/test-utils/index.ts b/e2e/test-utils/index.ts index 8af27bb..183e892 100644 --- a/e2e/test-utils/index.ts +++ b/e2e/test-utils/index.ts @@ -1,12 +1,28 @@ export { test, expect } from './test' export { SAMPLE_JPG, + SAMPLE_PNG, + SAMPLE_LARGE_JPG, dropFile, + dropFiles, waitForCimoReady, waitForCimoEditorIframeReady, dismissEditorOverlays, getMaxMediaId, getMediaCreatedAfter, + getMediaById, deletePage, expectNewMediaIsWebp, + expectNewMediaCount, + uploadSampleViaMediaNew, + expectCimoSidebarStats, + expectCimoMetaBox, + openAttachmentInLibraryModal, } from './media' +export { + saveCimoOptions, + gotoCimoSettings, + saveSettingsUi, + getCimoSettings, + reloadCimoRuntime, +} from './settings' diff --git a/e2e/test-utils/media.ts b/e2e/test-utils/media.ts index 96035a5..8e6d5cb 100644 --- a/e2e/test-utils/media.ts +++ b/e2e/test-utils/media.ts @@ -8,33 +8,46 @@ import type { RequestUtils } from '@wordpress/e2e-test-utils-playwright' /** JPEG fixture used by upload interception tests. */ export const SAMPLE_JPG = path.resolve( __dirname, '../fixtures/sample.jpg' ) +/** Small PNG fixture for format conversion tests. */ +export const SAMPLE_PNG = path.resolve( __dirname, '../fixtures/sample.png' ) + +/** Large JPEG (2000×1500) for max-dimension / progress tests. */ +export const SAMPLE_LARGE_JPG = path.resolve( + __dirname, + '../fixtures/sample-large.jpg' +) + +type DropFileSpec = { + path: string; + mimeType?: string; +} + /** - * Dispatch dragenter → dragover → drop with a real File payload. + * Dispatch dragenter → dragover → drop with one or more real File payloads. * Needed for Cimo's capture-phase drop interceptor (and Gutenberg DropZone). */ -export async function dropFile( +export async function dropFiles( target: Locator, - filePath: string = SAMPLE_JPG, - mimeType: string = 'image/jpeg' + files: DropFileSpec[] ) { - const buffer = fs.readFileSync( filePath ) - const fileName = path.basename( filePath ) - // A plain array of byte values (rather than a base64 string, which also - // requires `fetch()`/`atob()` that can run afoul of the block editor - // iframe's CSP) serializes reliably as the evaluateHandle arg. - const bytes = Array.from( buffer ) - - // Note: Locator#evaluateHandle calls pageFunction as (element, arg), not - // just (arg) — the element itself is unused here, but the parameter is - // required so `arg` correctly receives our payload. + const payloads = files.map( ( file ) => { + const buffer = fs.readFileSync( file.path ) + return { + data: Array.from( buffer ), + name: path.basename( file.path ), + type: file.mimeType || 'application/octet-stream', + } + } ) + const dataTransfer = await target.evaluateHandle( - ( element, { data, name, type } ) => { - const file = new File( [ new Uint8Array( data ) ], name, { type } ) + ( element, filePayloads ) => { const dt = new DataTransfer() - dt.items.add( file ) + for ( const { data, name, type } of filePayloads ) { + dt.items.add( new File( [ new Uint8Array( data ) ], name, { type } ) ) + } return dt }, - { data: bytes, name: fileName, type: mimeType } + payloads ) await target.dispatchEvent( 'dragenter', { dataTransfer } ) @@ -42,6 +55,18 @@ export async function dropFile( await target.dispatchEvent( 'drop', { dataTransfer } ) } +/** + * Dispatch dragenter → dragover → drop with a real File payload. + * Needed for Cimo's capture-phase drop interceptor (and Gutenberg DropZone). + */ +export async function dropFile( + target: Locator, + filePath: string = SAMPLE_JPG, + mimeType: string = 'image/jpeg' +) { + await dropFiles( target, [ { path: filePath, mimeType } ] ) +} + /** * Wait until Cimo's admin script has localized settings (interceptors are ready). */ @@ -91,10 +116,16 @@ export async function waitForCimoEditorIframeReady( page: Page ) { }, undefined, { timeout: 30_000 } ) } -type MediaItem = { +export type MediaItem = { id: number; mime_type: string; source_url: string; + media_details?: { + width?: number; + height?: number; + filesize?: number; + cimo?: Record; + }; } /** @@ -109,6 +140,7 @@ export async function listMediaNewestFirst( per_page: 100, orderby: 'id', order: 'desc', + context: 'edit', }, } ) as MediaItem[] } @@ -182,3 +214,108 @@ export async function expectNewMediaIsWebp( expect( newest.source_url ).toMatch( /\.webp(\?|$)/i ) return newest } + +/** + * Assert that N new WebP media items were uploaded after `afterId`. + */ +export async function expectNewMediaCount( + requestUtils: RequestUtils, + afterId: number, + count: number, + options: { timeout?: number; mime?: string } = {} +) { + const timeout = options.timeout ?? 90_000 + const mime = options.mime ?? 'image/webp' + + await expect.poll( + async () => { + const created = await getMediaCreatedAfter( requestUtils, afterId ) + return created.filter( ( item ) => item.mime_type === mime ).length + }, + { + timeout, + message: `Expected ${ count } new ${ mime } attachments after upload`, + } + ).toBe( count ) + + return ( await getMediaCreatedAfter( requestUtils, afterId ) ) + .filter( ( item ) => item.mime_type === mime ) +} + +/** + * Upload via Media → Add New file picker and wait for WebP conversion. + */ +export async function uploadSampleViaMediaNew( + page: Page, + requestUtils: RequestUtils, + filePath: string = SAMPLE_JPG, + mimeType: string = 'image/jpeg' +) { + await page.goto( '/wp-admin/media-new.php' ) + await waitForCimoReady( page ) + const afterId = await getMaxMediaId( requestUtils ) + + const fileInput = page.locator( + '.media-upload-form input[type="file"], #async-upload, input[name="async-upload"]' + ).first() + await expect( fileInput ).toBeAttached( { timeout: 15_000 } ) + await fileInput.setInputFiles( filePath ) + + if ( mimeType.startsWith( 'image/' ) && mimeType !== 'image/webp' ) { + return await expectNewMediaIsWebp( requestUtils, afterId ) + } + + await expect.poll( async () => { + return ( await getMediaCreatedAfter( requestUtils, afterId ) ).length + }, { timeout: 60_000 } ).toBeGreaterThan( 0 ) + + return ( await getMediaCreatedAfter( requestUtils, afterId ) )[ 0 ] +} + +/** + * Fetch a single media item (edit context includes media_details). + */ +export async function getMediaById( + requestUtils: RequestUtils, + id: number +): Promise { + return await requestUtils.rest( { + path: `/wp/v2/media/${ id }`, + params: { context: 'edit' }, + } ) as MediaItem +} + +/** + * Assert Cimo sidebar stats are visible in the open media modal. + */ +export async function expectCimoSidebarStats( page: Page ) { + const root = page.locator( '.media-modal .cimo-media-manager-metadata' ).first() + await expect( root ).toBeVisible( { timeout: 30_000 } ) + await expect( root.locator( '.cimo-converted' ) ).toContainText( /WebP/i ) + await expect( root.locator( '.cimo-compression-savings' ) ).toBeVisible() + return root +} + +/** + * Assert the attachment edit screen meta box shows Cimo optimization data. + */ +export async function expectCimoMetaBox( page: Page ) { + const box = page.locator( '#cimo-data-meta-box' ) + await expect( box ).toBeVisible( { timeout: 15_000 } ) + await expect( box ).not.toContainText( /Cimo did not optimize this attachment/i ) + await expect( box.locator( '.cimo-converted, .cimo-compression-savings' ).first() ).toBeVisible( { + timeout: 15_000, + } ) + return box +} + +/** + * Open an attachment in the Media Library grid modal. + */ +export async function openAttachmentInLibraryModal( page: Page, mediaId: number ) { + await page.goto( '/wp-admin/upload.php' ) + const attachment = page.locator( `.attachment[data-id="${ mediaId }"]` ) + await expect( attachment ).toBeVisible( { timeout: 30_000 } ) + await attachment.click() + await expect( page.locator( '.media-modal' ) ).toBeVisible( { timeout: 15_000 } ) +} diff --git a/e2e/test-utils/settings.ts b/e2e/test-utils/settings.ts new file mode 100644 index 0000000..44f5c19 --- /dev/null +++ b/e2e/test-utils/settings.ts @@ -0,0 +1,83 @@ +import type { Page } from '@playwright/test' +import { expect } from '@playwright/test' +import type { Admin, RequestUtils } from '@wordpress/e2e-test-utils-playwright' + +import { waitForCimoReady } from './media' + +export type CimoOptions = { + webp_quality?: number; + max_image_dimension?: number; + disable_wp_scaling?: number; + smart_optimization?: number; + optimize_all_media?: number; + [ key: string ]: unknown; +} + +/** + * Merge partial options into stored `cimo_options` via REST. + */ +export async function saveCimoOptions( + requestUtils: RequestUtils, + partial: CimoOptions +) { + const settings = await requestUtils.rest( { + path: '/wp/v2/settings', + } ) as { cimo_options?: CimoOptions } + + const current = settings.cimo_options || {} + await requestUtils.rest( { + method: 'POST', + path: '/wp/v2/settings', + data: { + cimo_options: { + ...current, + ...partial, + }, + }, + } ) +} + +/** + * Open Settings → Cimo and wait for the React settings app. + */ +export async function gotoCimoSettings( admin: Admin, page: Page ) { + await admin.visitAdminPage( 'options-general.php', 'page=cimo-settings' ) + await expect( page.locator( '#cimo-admin-settings' ) ).toBeVisible( { + timeout: 30_000, + } ) + await expect( page.locator( '.cimo-admin-settings-wrap' ) ).toBeVisible( { + timeout: 30_000, + } ) +} + +/** + * Click Save Changes and wait for the success notice. + */ +export async function saveSettingsUi( page: Page ) { + const saveButton = page.locator( '.cimo-save-button' ) + await expect( saveButton ).toBeVisible() + await saveButton.click() + await expect( page.getByText( 'Settings saved successfully!' ) ).toBeVisible( { + timeout: 15_000, + } ) +} + +/** + * Read localized `window.cimoSettings` after the upload runtime has loaded. + */ +export async function getCimoSettings( page: Page ) { + await waitForCimoReady( page ) + return await page.evaluate( () => { + return ( window as Window & { + cimoSettings?: Record; + } ).cimoSettings || {} + } ) +} + +/** + * Open an admin surface that enqueues `cimo-script` so localized settings refresh. + */ +export async function reloadCimoRuntime( page: Page ) { + await page.goto( '/wp-admin/media-new.php' ) + await waitForCimoReady( page ) +} diff --git a/e2e/tests/freemium.spec.ts b/e2e/tests/freemium.spec.ts new file mode 100644 index 0000000..96c03cd --- /dev/null +++ b/e2e/tests/freemium.spec.ts @@ -0,0 +1,80 @@ +import { + test, + expect, + gotoCimoSettings, +} from '../test-utils' + +test.describe.configure( { timeout: 90_000 } ) + +test.describe( 'Freemium admin chrome', () => { + test( 'premium settings controls stay disabled with Premium labels', async ( { + admin, + page, + } ) => { + await gotoCimoSettings( admin, page ) + + const optimizeAll = page.getByRole( 'checkbox', { + name: /Optimize All Media Uploads/i, + } ) + await expect( optimizeAll ).toBeDisabled() + + const smartOpt = page.getByRole( 'checkbox', { + name: /Smart Optimization/i, + } ) + await expect( smartOpt ).toBeDisabled() + + await expect( page.locator( '.cimo-premium-tag' ).first() ).toBeVisible() + await expect( page.locator( '#bulk-optimization' ) ).toBeVisible() + await expect( page.locator( '.cimo-bulk-optimizer-upsell' ) ).toBeVisible() + await expect( + page.getByRole( 'link', { name: /Bulk Optimize with Premium/i } ) + ).toBeVisible() + await expect( + page.locator( '.cimo-bulk-optimize-button-view-images' ) + ).toBeDisabled() + + await expect( page.locator( '.cimo-premium-feature-label' ).first() ).toBeVisible() + } ) + + test( 'plugins screen exposes Settings and Upgrade links', async ( { + admin, + page, + } ) => { + await admin.visitAdminPage( 'plugins.php' ) + const row = page.locator( 'tr[data-slug="cimo-image-optimizer"], tr[data-plugin*="cimo.php"]' ).first() + await expect( row ).toBeVisible( { timeout: 30_000 } ) + await expect( row.getByRole( 'link', { name: 'Settings', exact: true } ) ).toBeVisible() + await expect( row.getByRole( 'link', { name: 'Upgrade', exact: true } ) ).toBeVisible() + } ) + + test( 'activation notice can be dismissed when present', async ( { + admin, + page, + requestUtils, + } ) => { + // Re-seed the activation transient via a no-op REST round-trip is not available; + // Playground activates Cimo at boot, so the notice may still be present. + await admin.visitAdminPage( 'index.php' ) + + const notice = page.locator( '.cimo-activation-notice' ) + const visible = await notice.isVisible().catch( () => false ) + if ( ! visible ) { + // Force show by re-setting the transient through a temporary plugin option + // is not exposed; soft-pass when already dismissed in this Playground instance. + test.info().annotations.push( { + type: 'note', + description: 'Activation notice not visible (already dismissed or transient expired)', + } ) + return + } + + await notice.locator( '.cimo-activation-dismiss' ).click() + await expect( notice ).toBeHidden( { timeout: 10_000 } ) + + await admin.visitAdminPage( 'index.php' ) + await expect( page.locator( '.cimo-activation-notice' ) ).toHaveCount( 0 ) + + // Keep requestUtils referenced so the fixture stays available if we extend seeding later. + expect( requestUtils ).toBeTruthy() + } ) +} ) diff --git a/e2e/tests/post-upload-stats.spec.ts b/e2e/tests/post-upload-stats.spec.ts new file mode 100644 index 0000000..ee54ff4 --- /dev/null +++ b/e2e/tests/post-upload-stats.spec.ts @@ -0,0 +1,44 @@ +import { + test, + expect, + uploadSampleViaMediaNew, + openAttachmentInLibraryModal, + expectCimoSidebarStats, + expectCimoMetaBox, +} from '../test-utils' + +test.describe.configure( { timeout: 120_000 } ) + +test.describe( 'Post-upload Cimo stats', () => { + test.beforeEach( async ( { requestUtils } ) => { + await requestUtils.deleteAllMedia() + } ) + + test.afterEach( async ( { requestUtils } ) => { + await requestUtils.deleteAllMedia() + } ) + + test( 'media modal sidebar shows optimization stats', async ( { + page, + requestUtils, + } ) => { + const media = await uploadSampleViaMediaNew( page, requestUtils ) + + await openAttachmentInLibraryModal( page, media.id ) + await expectCimoSidebarStats( page ) + } ) + + test( 'attachment edit meta box shows optimization stats after reload', async ( { + page, + requestUtils, + } ) => { + const media = await uploadSampleViaMediaNew( page, requestUtils ) + + // Reload attachment edit so PHP meta box reads persisted `_wp_attachment_metadata.cimo`. + await page.goto( `/wp-admin/post.php?post=${ media.id }&action=edit` ) + await expectCimoMetaBox( page ) + + await page.reload() + await expectCimoMetaBox( page ) + } ) +} ) diff --git a/e2e/tests/premium/bulk-optimizer.spec.ts b/e2e/tests/premium/bulk-optimizer.spec.ts new file mode 100644 index 0000000..71bbec0 --- /dev/null +++ b/e2e/tests/premium/bulk-optimizer.spec.ts @@ -0,0 +1,139 @@ +import { + test, + expect, + gotoCimoSettings, + saveCimoOptions, + SAMPLE_JPG, + SAMPLE_LARGE_JPG, +} from '../../test-utils' + +test.describe.configure( { timeout: 180_000 } ) + +async function seedUnoptimizedImages( requestUtils, count = 4 ) { + const files = [ SAMPLE_JPG, SAMPLE_LARGE_JPG, SAMPLE_JPG, SAMPLE_LARGE_JPG ] + const uploaded = [] + for ( let i = 0; i < count; i++ ) { + uploaded.push( await requestUtils.uploadMedia( files[ i % files.length ] ) ) + } + return uploaded +} + +async function waitForBulkIdle( page ) { + const button = page.locator( '.cimo-bulk-optimize-button' ) + await expect( button ).not.toHaveClass( /is-optimizing/, { timeout: 120_000 } ) + await expect( button ).not.toContainText( /Stop Optimization/i, { + timeout: 30_000, + } ) +} + +async function readUnoptimizedCount( page ) { + const bulkButton = page.locator( '.cimo-bulk-optimize-button' ) + await expect( bulkButton ).toContainText( /Bulk Optimize \(\d+\)/, { + timeout: 30_000, + } ) + const label = await bulkButton.innerText() + return Number( ( label.match( /\((\d+)\)/ ) || [] )[ 1 ] || 0 ) +} + +test.describe( 'Premium bulk optimizer', () => { + test.beforeEach( async ( { requestUtils } ) => { + await saveCimoOptions( requestUtils, { + disable_thumbnail_generation: 1, + disable_wp_scaling: 1, + } ) + await requestUtils.deleteAllMedia() + } ) + + test.afterEach( async ( { requestUtils } ) => { + await requestUtils.deleteAllMedia() + } ) + + test( 'bulk optimize completes with progress updates', async ( { + admin, + page, + requestUtils, + } ) => { + const seeded = await seedUnoptimizedImages( requestUtils, 4 ) + expect( seeded ).toHaveLength( 4 ) + + await gotoCimoSettings( admin, page ) + + const progressText = page.locator( '.cimo-bulk-optimizer-progress-bar-text' ) + await expect( progressText ).toBeVisible( { timeout: 30_000 } ) + + const total = await readUnoptimizedCount( page ) + expect( total ).toBeGreaterThanOrEqual( 4 ) + + const bulkButton = page.locator( '.cimo-bulk-optimize-button' ) + await page.locator( '.cimo-bulk-optimize-button-view-images' ).click() + await expect( page.locator( '.cimo-bulk-optimizer-image-list' ) ).toBeVisible() + await expect( page.getByText( new RegExp( `Unoptimized \\(${ total }\\)` ) ) ).toBeVisible() + + const startedAt = Date.now() + await bulkButton.click() + + await expect( bulkButton ).toHaveClass( /is-optimizing/ ) + await expect( bulkButton ).toContainText( /Stop Optimization/i ) + await expect( + page.locator( '.cimo-bulk-optimizer-optimization-in-progress' ) + ).toBeVisible() + + await expect.poll( + async () => { + const text = await progressText.innerText() + const match = text.match( /(\d+)\s+of\s+(\d+)\s+optimized/i ) + if ( ! match ) { + return 0 + } + return Number( match[ 1 ] ) + }, + { + timeout: 90_000, + message: 'Expected bulk progress to advance', + } + ).toBeGreaterThan( 0 ) + + await waitForBulkIdle( page ) + + const elapsedMs = Date.now() - startedAt + expect( elapsedMs ).toBeLessThan( 120_000 ) + + await expect( progressText ).toContainText( + new RegExp( `${ total } of ${ total } optimized|100%`, 'i' ) + ) + await expect( bulkButton ).toBeDisabled() + await expect( page.getByText( new RegExp( `Optimized \\(${ total }\\)` ) ) ).toBeVisible() + await expect( page.getByText( /Unoptimized \(0\)/ ) ).toBeVisible() + } ) + + test( 'stop optimization leaves remaining unoptimized items', async ( { + admin, + page, + requestUtils, + } ) => { + await seedUnoptimizedImages( requestUtils, 4 ) + await gotoCimoSettings( admin, page ) + + const total = await readUnoptimizedCount( page ) + expect( total ).toBeGreaterThanOrEqual( 4 ) + + const bulkButton = page.locator( '.cimo-bulk-optimize-button' ) + await bulkButton.click() + await expect( bulkButton ).toContainText( /Stop Optimization/i ) + + await bulkButton.click() + await waitForBulkIdle( page ) + + const label = await bulkButton.innerText() + if ( /Bulk Optimize/.test( label ) ) { + const remaining = Number( ( label.match( /\((\d+)\)/ ) || [] )[ 1 ] || 0 ) + expect( remaining ).toBeGreaterThan( 0 ) + } else { + test.info().annotations.push( { + type: 'note', + description: 'All items finished before stop could take effect', + } ) + await expect( bulkButton ).toBeDisabled() + } + } ) +} ) diff --git a/e2e/tests/premium/settings-unlocked.spec.ts b/e2e/tests/premium/settings-unlocked.spec.ts new file mode 100644 index 0000000..4ddd9a1 --- /dev/null +++ b/e2e/tests/premium/settings-unlocked.spec.ts @@ -0,0 +1,44 @@ +import { + test, + expect, + gotoCimoSettings, + SAMPLE_JPG, +} from '../../test-utils' + +test.describe.configure( { timeout: 120_000 } ) + +test.describe( 'Premium settings unlocked', () => { + test( 'premium build enables gated controls and working bulk UI', async ( { + admin, + page, + requestUtils, + } ) => { + await requestUtils.deleteAllMedia() + await requestUtils.uploadMedia( SAMPLE_JPG ) + + await gotoCimoSettings( admin, page ) + + await expect( page.locator( '.cimo-admin-settings-wrap.cimo-is-premium' ) ).toBeVisible() + + const optimizeAll = page.getByRole( 'checkbox', { + name: /Optimize All Media Uploads/i, + } ) + await expect( optimizeAll ).toBeEnabled() + + const smartOpt = page.getByRole( 'checkbox', { + name: /Smart Optimization/i, + } ) + await expect( smartOpt ).toBeEnabled() + + await expect( page.locator( '.cimo-bulk-optimizer-upsell' ) ).toHaveCount( 0 ) + + const bulkButton = page.locator( '.cimo-bulk-optimize-button' ) + await expect( bulkButton ).toBeVisible( { timeout: 30_000 } ) + await expect( bulkButton ).toContainText( /Bulk Optimize \(\d+\)/ ) + await expect( bulkButton ).not.toContainText( /with Premium/i ) + + await expect( + page.locator( '.cimo-bulk-optimize-button-view-images' ) + ).toBeEnabled() + } ) +} ) diff --git a/e2e/tests/settings.spec.ts b/e2e/tests/settings.spec.ts new file mode 100644 index 0000000..018f26f --- /dev/null +++ b/e2e/tests/settings.spec.ts @@ -0,0 +1,100 @@ +import { + test, + expect, + SAMPLE_LARGE_JPG, + gotoCimoSettings, + saveCimoOptions, + saveSettingsUi, + getCimoSettings, + reloadCimoRuntime, + uploadSampleViaMediaNew, + getMediaById, +} from '../test-utils' + +test.describe.configure( { timeout: 120_000 } ) + +test.describe( 'Cimo settings', () => { + test.beforeEach( async ( { requestUtils } ) => { + await requestUtils.deleteAllMedia() + await saveCimoOptions( requestUtils, { + webp_quality: 80, + max_image_dimension: 0, + disable_wp_scaling: 1, + } ) + } ) + + test.afterEach( async ( { requestUtils } ) => { + await requestUtils.deleteAllMedia() + await saveCimoOptions( requestUtils, { + webp_quality: 80, + max_image_dimension: 0, + disable_wp_scaling: 1, + } ) + } ) + + test( 'settings page loads with stats and image controls', async ( { + admin, + page, + } ) => { + await gotoCimoSettings( admin, page ) + + await expect( page.locator( '#cimo-stats' ) ).toBeVisible() + await expect( page.getByText( 'Total Storage Saved' ) ).toBeVisible() + await expect( page.getByRole( 'heading', { name: 'General Settings' } ) ).toBeVisible() + await expect( page.getByRole( 'heading', { name: 'Image Optimization Settings' } ) ).toBeVisible() + await expect( page.locator( '.cimo-webp-quality-range-control' ) ).toBeVisible() + await expect( page.getByLabel( 'Maximum Image Dimension' ) ).toBeVisible() + await expect( page.locator( '.cimo-save-button' ) ).toBeVisible() + } ) + + test( 'saving quality and max dimension updates runtime and upload', async ( { + admin, + page, + requestUtils, + } ) => { + await saveCimoOptions( requestUtils, { + webp_quality: 55, + max_image_dimension: 800, + disable_wp_scaling: 1, + } ) + + await gotoCimoSettings( admin, page ) + await expect( page.getByLabel( 'Maximum Image Dimension' ) ).toHaveValue( '800' ) + + // UI save smoke: tweak max dimension and persist via Save Changes. + await page.getByLabel( 'Maximum Image Dimension' ).fill( '640' ) + await saveSettingsUi( page ) + + await reloadCimoRuntime( page ) + const settings = await getCimoSettings( page ) + expect( Number( settings.webpQuality ) ).toBe( 55 ) + expect( Number( settings.maxImageDimension ) ).toBe( 640 ) + + const media = await uploadSampleViaMediaNew( + page, + requestUtils, + SAMPLE_LARGE_JPG + ) + const details = await getMediaById( requestUtils, media.id ) + const width = details.media_details?.width || 0 + const height = details.media_details?.height || 0 + expect( Math.max( width, height ) ).toBeLessThanOrEqual( 640 ) + expect( details.mime_type ).toBe( 'image/webp' ) + } ) + + test( 'Recommended and Reset presets update image controls', async ( { + admin, + page, + } ) => { + await gotoCimoSettings( admin, page ) + + const imageSection = page.locator( '.cimo-settings-section' ).filter( { + has: page.getByRole( 'heading', { name: 'Image Optimization Settings' } ), + } ) + await imageSection.getByRole( 'button', { name: 'Recommended' } ).click() + await expect( page.getByLabel( 'Maximum Image Dimension' ) ).toHaveValue( '1920' ) + + await imageSection.getByRole( 'button', { name: 'Reset to Default' } ).click() + await expect( page.getByLabel( 'Maximum Image Dimension' ) ).toHaveValue( '' ) + } ) +} ) diff --git a/e2e/tests/upload-surfaces.spec.ts b/e2e/tests/upload-surfaces.spec.ts new file mode 100644 index 0000000..1b7aa65 --- /dev/null +++ b/e2e/tests/upload-surfaces.spec.ts @@ -0,0 +1,184 @@ +import { + test, + expect, + SAMPLE_JPG, + SAMPLE_PNG, + SAMPLE_LARGE_JPG, + dropFile, + dropFiles, + waitForCimoReady, + waitForCimoEditorIframeReady, + dismissEditorOverlays, + getMaxMediaId, + deletePage, + expectNewMediaIsWebp, + expectNewMediaCount, +} from '../test-utils' + +test.describe.configure( { timeout: 120_000 } ) + +test.describe( 'Additional upload surfaces', () => { + let pageId: number | null = null + + test.beforeEach( async ( { requestUtils } ) => { + await requestUtils.deleteAllMedia() + } ) + + test.afterEach( async ( { requestUtils } ) => { + if ( pageId ) { + await deletePage( requestUtils, pageId ) + pageId = null + } + await requestUtils.deleteAllMedia() + } ) + + async function openNewPage( admin, editor, page, requestUtils ) { + const draft = await requestUtils.createPage( { + title: 'Cimo Upload Surfaces E2E', + status: 'draft', + content: '

Cimo e2e

', + } ) + pageId = draft.id + + await admin.visitAdminPage( + 'post.php', + `post=${ pageId }&action=edit` + ) + await editor.setPreferences( 'core/edit-post', { + welcomeGuide: false, + fullscreenMode: false, + } ) + await editor.setPreferences( 'core', { + enableChoosePatternModal: false, + } ) + await dismissEditorOverlays( page ) + await waitForCimoReady( page ) + await waitForCimoEditorIframeReady( page ) + } + + test( 'Media Library grid drop converts JPG to WebP', async ( { + page, + requestUtils, + } ) => { + await page.goto( '/wp-admin/upload.php' ) + await waitForCimoReady( page ) + const afterId = await getMaxMediaId( requestUtils ) + + // Drop directly on `.uploader-window` so Cimo's allowlist match succeeds + // even when the overlay is not display:block yet. + const dropTarget = page.locator( '.uploader-window' ).first() + await expect( dropTarget ).toBeAttached( { timeout: 15_000 } ) + await dropFile( dropTarget ) + + const media = await expectNewMediaIsWebp( requestUtils, afterId ) + await expect( + page.locator( `.attachment[data-id="${ media.id }"]` ) + ).toBeVisible( { timeout: 30_000 } ) + } ) + + test( 'Media Library Select Files converts JPG to WebP', async ( { + page, + requestUtils, + } ) => { + await page.goto( '/wp-admin/upload.php' ) + await waitForCimoReady( page ) + const afterId = await getMaxMediaId( requestUtils ) + + // Grid view exposes the classic plupload "Select Files" input (`.moxie-shim` + // / browser uploader), which is the non-drop select-files interception path. + const fileInput = page.locator( + '.uploader-inline input[type="file"], .moxie-shim input[type="file"], input#async-upload, .media-upload-form input[type="file"]' + ).first() + await expect( fileInput ).toBeAttached( { timeout: 15_000 } ) + await fileInput.setInputFiles( SAMPLE_JPG ) + + const media = await expectNewMediaIsWebp( requestUtils, afterId ) + await expect( + page.locator( `.attachment[data-id="${ media.id }"]` ) + ).toBeVisible( { timeout: 30_000 } ) + } ) + + test( 'PNG upload converts to WebP', async ( { + page, + requestUtils, + } ) => { + await page.goto( '/wp-admin/media-new.php' ) + await waitForCimoReady( page ) + const afterId = await getMaxMediaId( requestUtils ) + + const fileInput = page.locator( + '.media-upload-form input[type="file"], #async-upload, input[name="async-upload"]' + ).first() + await fileInput.setInputFiles( SAMPLE_PNG ) + + const media = await expectNewMediaIsWebp( requestUtils, afterId ) + expect( media.source_url ).toMatch( /\.webp(\?|$)/i ) + } ) + + test( 'multi-file drop converts all JPGs to WebP', async ( { + page, + requestUtils, + } ) => { + await page.goto( '/wp-admin/media-new.php' ) + await waitForCimoReady( page ) + const afterId = await getMaxMediaId( requestUtils ) + + const dropTarget = page.locator( '.media-upload-form, .uploader-inline' ).first() + await expect( dropTarget ).toBeVisible( { timeout: 15_000 } ) + await dropFiles( dropTarget, [ + { path: SAMPLE_JPG, mimeType: 'image/jpeg' }, + { path: SAMPLE_LARGE_JPG, mimeType: 'image/jpeg' }, + ] ) + + const created = await expectNewMediaCount( requestUtils, afterId, 2 ) + expect( created ).toHaveLength( 2 ) + for ( const item of created ) { + expect( item.mime_type ).toBe( 'image/webp' ) + } + } ) + + test( 'progress modal cancel stops optimization', async ( { + page, + requestUtils, + } ) => { + await page.goto( '/wp-admin/media-new.php' ) + await waitForCimoReady( page ) + const afterId = await getMaxMediaId( requestUtils ) + + page.once( 'dialog', async ( dialog ) => { + await dialog.accept() + } ) + + const fileInput = page.locator( + '.media-upload-form input[type="file"], #async-upload, input[name="async-upload"]' + ).first() + // Large file + progressDelay should surface the modal long enough to cancel. + await fileInput.setInputFiles( SAMPLE_LARGE_JPG ) + + const modal = page.locator( '.cimo-progress-modal' ) + const appeared = await modal + .waitFor( { state: 'visible', timeout: 5_000 } ) + .then( () => true ) + .catch( () => false ) + + test.skip( + ! appeared, + 'Progress modal did not appear before conversion finished (too fast on this host)' + ) + + await page.locator( '.cimo-progress-close' ).click() + await expect( modal ).toBeHidden( { timeout: 10_000 } ) + + // Cancel may leave zero new attachments or an unconverted original. + await page.waitForTimeout( 2_000 ) + const created = await requestUtils.rest( { + path: '/wp/v2/media', + params: { per_page: 10, orderby: 'id', order: 'desc' }, + } ) as Array<{ id: number; mime_type: string }> + const newer = created.filter( ( item ) => item.id > afterId ) + for ( const item of newer ) { + // If anything uploaded after cancel, it should not be a mid-flight Cimo failure crash. + expect( item.mime_type ).toMatch( /^image\// ) + } + } ) +} ) diff --git a/package.json b/package.json index abbe211..8a95e84 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "build:premium": "cd pro__premium_only && npm run build", "start:premium": "cd pro__premium_only && npm run start", "build:e2e": "node scripts/update-build-type.js free && wp-scripts build", + "build:e2e:premium": "node scripts/update-build-type.js premium && npx wp-scripts build --config pro__premium_only/webpack.config.js", "lint:js": "wp-scripts lint-js", "lint:js:fix": "wp-scripts lint-js --fix", "lint:css": "wp-scripts lint-style", @@ -24,6 +25,7 @@ "sync-version": "node scripts/sync-version.js", "test": "npm run test:e2e", "test:e2e": "playwright test", + "test:e2e:premium": "playwright test -c playwright.premium.config.js", "test:debug": "playwright test --ui" }, "browserslist": [ diff --git a/playwright.config.js b/playwright.config.js index 06347af..169a14a 100644 --- a/playwright.config.js +++ b/playwright.config.js @@ -29,6 +29,7 @@ const PLAYGROUND_BLUEPRINT = path.join( __dirname, 'e2e/playground-blueprint.jso module.exports = defineConfig( { testDir: './e2e/tests', + testIgnore: [ '**/premium/**' ], globalSetup: require.resolve( './e2e/config/global-setup.js' ), fullyParallel: false, forbidOnly: !! process.env.CI, diff --git a/playwright.premium.config.js b/playwright.premium.config.js new file mode 100644 index 0000000..2056c0d --- /dev/null +++ b/playwright.premium.config.js @@ -0,0 +1,59 @@ +/** + * Playwright config for Cimo's premium e2e suite. + * + * Requires `pro__premium_only/` on disk and a prior `npm run build:e2e:premium`. + * Uses a separate Playground port/blueprint that seeds a mock Freemius premium plan. + */ +const path = require( 'path' ) +const { defineConfig, devices } = require( '@playwright/test' ) + +const PORT = process.env.WP_PORT || '9411' +const baseURL = process.env.WP_BASE_URL || `http://127.0.0.1:${ PORT }` +process.env.WP_BASE_URL = baseURL +process.env.WP_USERNAME = process.env.WP_USERNAME || 'admin' +process.env.WP_PASSWORD = process.env.WP_PASSWORD || 'password' + +const STORAGE_STATE_PATH = path.join( __dirname, 'e2e/.auth/admin.premium.json' ) +process.env.STORAGE_STATE_PATH = STORAGE_STATE_PATH + +const PLAYGROUND_BLUEPRINT = path.join( + __dirname, + 'e2e/playground-blueprint.premium.json' +) + +module.exports = defineConfig( { + testDir: './e2e/tests/premium', + globalSetup: require.resolve( './e2e/config/global-setup.js' ), + fullyParallel: false, + forbidOnly: !! process.env.CI, + retries: process.env.CI ? 1 : 0, + workers: 1, + timeout: 120_000, + reporter: process.env.CI + ? [ [ 'github' ], [ 'html', { open: 'never' } ] ] + : [ [ 'list' ], [ 'html', { outputFolder: 'playwright-report-premium', open: 'never' } ] ], + reportSlowTests: null, + webServer: { + command: [ + 'npx @wp-playground/cli server', + '--mount=.:/wordpress/wp-content/plugins/cimo', + `--blueprint=${ PLAYGROUND_BLUEPRINT }`, + '--php=8.2', + `--port=${ PORT }`, + ].join( ' ' ), + port: Number( PORT ), + reuseExistingServer: ! process.env.CI, + timeout: 180 * 1000, + stdout: 'pipe', + stderr: 'pipe', + }, + use: { + baseURL, + storageState: STORAGE_STATE_PATH, + ignoreHTTPSErrors: true, + screenshot: 'only-on-failure', + trace: 'retain-on-failure', + video: 'retain-on-failure', + ...devices[ 'Desktop Chrome' ], + }, +} ) diff --git a/src/admin/class-admin.php b/src/admin/class-admin.php index 135893f..4a64a64 100644 --- a/src/admin/class-admin.php +++ b/src/admin/class-admin.php @@ -259,10 +259,12 @@ public function enqueue_admin_scripts( $hook ) { // Enqueue JavaScript $script_asset = include $build_dir . 'admin-page.asset.php'; + // Depend on cimo-script so premium filters (BulkOptimizer, buildType peers) + // register before admin-settings.js evaluates applyFilters at module load. wp_enqueue_script( 'cimo-admin-page', $build_url . 'admin-page.js', - array_merge( $script_asset['dependencies'], $dependencies['js'] ), + array_merge( $script_asset['dependencies'], $dependencies['js'], [ 'cimo-script' ] ), $script_asset['version'], true );