PluginProbe
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF / trunk
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF vtrunk
2.3.4 2.3.3 2.3.2 2.3.1 2.3.0 2.2.9 2.2.8 trunk 1.10 1.3.3 1.3.4 1.3.5 1.3.5.1 1.3.5.2 1.3.6 1.3.6.1 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.5 All 103 releases
imagify / docs / E2E_TESTING.md

E2E_TESTING.md in Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF trunk, at docs/E2E_TESTING.md

234 lines 7.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 # Imagify — End-to-End Testing
2
3 This document is the canonical reference for the Imagify Playwright E2E test suite. **Read this before writing any new tests.**
4
5 ---
6
7 ## Architecture overview
8
9 | Layer | Path | Purpose |
10 |-------|------|---------|
11 | Config | `Tests/e2e/playwright.config.ts` | Playwright base config (baseURL, reporters, timeouts) |
12 | Fixtures | `Tests/e2e/fixtures/` | Shared helpers: login, WP-CLI wrapper, API key guard |
13 | Page objects | `Tests/e2e/pages/` | One class per major admin surface |
14 | Specs | `Tests/e2e/specs/` | Test files, one per feature area |
15 | Dev scripts | `bin/dev-up.sh`, `bin/dev-down.sh`, `bin/dev-seed.sh` | Local environment lifecycle |
16 | CI | `.github/workflows/e2e.yml` | Automated runs on pull requests |
17
18
19 All tests run against a local WordPress environment managed by `@wordpress/env` (Docker). The environment maps the plugin root directly into the container at `wp-content/plugins/imagify`.
20
21 ---
22
23 ## Admin URLs
24
25 | Surface | URL |
26 |---------|-----|
27 | Settings | `/wp-admin/options-general.php?page=imagify` |
28 | Bulk optimization | `/wp-admin/upload.php?page=imagify-bulk-optimization` |
29 | Custom folders | `/wp-admin/upload.php?page=imagify-files` |
30 | Media library (list) | `/wp-admin/upload.php?mode=list` |
31 | Plugins list | `/wp-admin/plugins.php` |
32
33 ---
34
35 ## Running tests locally
36
37 ### One-time setup
38
39 ```bash
40 # From the repository root
41 bash bin/dev-up.sh # Start wp-env + activate plugin + seed test data
42 cd Tests/e2e
43 npm install
44 npx playwright install chromium
45 ```
46
47 ### Running
48
49 ```bash
50 cd Tests/e2e
51 npm test # Headless, list reporter
52 npm run test:headed # With browser UI visible
53 npm run test:ui # Playwright interactive UI mode
54 npm run report # Open the last HTML report
55 ```
56
57 ### Environment variables
58
59 | Variable | Default | Purpose |
60 |----------|---------|---------|
61 | `IMAGIFY_BASE_URL` | `http://localhost:8888` | Override the WordPress base URL |
62 | `IMAGIFY_ADMIN_USER` | `admin` | WP admin username |
63 | `IMAGIFY_ADMIN_PASS` | `password` | WP admin password |
64 | `IMAGIFY_TESTS_API_KEY` | _(unset)_ | Real Imagify API key — required for optimization tests |
65
66 Set `IMAGIFY_TESTS_API_KEY` to run tests that call the Imagify API. Without it, those tests are automatically skipped.
67
68 ---
69
70 ## Page objects
71
72 Each major admin surface has a Page Object class. Use them instead of raw selectors — they centralize selector maintenance.
73
74 ### `SettingsPage` (`Tests/e2e/pages/settings.ts`)
75
76 ```typescript
77 import { SettingsPage } from '../pages/settings';
78 const settings = new SettingsPage( page );
79 await settings.goto();
80 await settings.setApiKey( process.env.IMAGIFY_TESTS_API_KEY! );
81 ```
82
83 Key members: `apiKeyInput`, `saveButton`, `successNotice`, `goto()`, `setApiKey()`, `getApiKey()`, `expectNoFatalError()`.
84
85 ### `BulkOptimizationPage` (`Tests/e2e/pages/bulk-optimization.ts`)
86
87 ```typescript
88 import { BulkOptimizationPage } from '../pages/bulk-optimization';
89 const bulk = new BulkOptimizationPage( page );
90 await bulk.goto();
91 await expect( bulk.optimizeButton ).toBeVisible();
92 ```
93
94 Key members: `optimizeButton`, `progressBar`, `statsTable`, `goto()`, `expectNoFatalError()`.
95
96 ### `MediaLibraryPage` (`Tests/e2e/pages/media-library.ts`)
97
98 ```typescript
99 import { MediaLibraryPage } from '../pages/media-library';
100 const library = new MediaLibraryPage( page );
101 await library.goto();
102 await expect( library.imagifyColumn ).toBeVisible();
103 ```
104
105 Key members: `imagifyColumn`, `goto()`, `hasImagifyColumn()`, `getFirstAttachmentStatus()`, `expectNoFatalError()`.
106
107 ---
108
109 ## Fixtures
110
111 ### `loginAsAdmin( page )` — `Tests/e2e/fixtures/auth.ts`
112
113 Logs in as the WordPress administrator. Idempotent: skips the login form if a session cookie is already active.
114
115 ```typescript
116 import { loginAsAdmin } from '../fixtures/auth';
117 test.beforeEach( async ( { page } ) => {
118 await loginAsAdmin( page );
119 } );
120 ```
121
122 ### `wpCli( command )` — `Tests/e2e/fixtures/wp-cli.ts`
123
124 Runs a WP-CLI command inside the wp-env `cli` container. Returns stdout as a string.
125
126 ```typescript
127 import { wpCli } from '../fixtures/wp-cli';
128 const value = wpCli( 'option get imagify_settings --format=json' );
129 ```
130
131 ### `hasApiKey()` — `Tests/e2e/fixtures/wp-cli.ts`
132
133 Returns `true` if `IMAGIFY_TESTS_API_KEY` is set. Use with `test.skip` to gate API-dependent tests:
134
135 ```typescript
136 import { hasApiKey } from '../fixtures/wp-cli';
137 test.skip( ! hasApiKey(), 'IMAGIFY_TESTS_API_KEY not set' );
138 ```
139
140 ---
141
142 ## Writing new tests
143
144 ### Determinism rules
145
146 - **Never** use `setTimeout` or `waitForTimeout`. Use web-first assertions (`toBeVisible`, `toHaveValue`, `toHaveURL`, etc.) which have built-in retry.
147 - **Never** assert on volatile values (timestamps, auto-increment IDs) without normalization.
148 - **Always** seed state before tests that depend on specific DB content.
149
150 ### API key guard
151
152 Any test that triggers image optimization through the Imagify API must be guarded:
153
154 ```typescript
155 test( 'Optimizing an image succeeds', async ( { page } ) => {
156 test.skip( ! process.env.IMAGIFY_TESTS_API_KEY, 'IMAGIFY_TESTS_API_KEY not set — skipping live optimization test' );
157 // ... test body
158 } );
159 ```
160
161 ### Adding a new page object
162
163 Create `Tests/e2e/pages/<feature>.ts`:
164
165 ```typescript
166 import { Page, Locator, expect } from '@playwright/test';
167
168 export class FeaturePage {
169 readonly page: Page;
170 // locators...
171
172 constructor( page: Page ) {
173 this.page = page;
174 // initialize locators
175 }
176
177 async goto(): Promise<void> {
178 await this.page.goto( '/wp-admin/...' );
179 await this.page.waitForLoadState( 'networkidle' );
180 }
181
182 async expectNoFatalError(): Promise<void> {
183 await expect( this.page.locator( '.wp-die-message, #error-page' ) ).toHaveCount( 0 );
184 }
185 }
186 ```
187
188 ### Adding a new spec
189
190 Create `Tests/e2e/specs/<feature>.spec.ts`. Follow this template:
191
192 ```typescript
193 import { test, expect } from '@playwright/test';
194 import { loginAsAdmin } from '../fixtures/auth';
195 import { FeaturePage } from '../pages/<feature>';
196
197 test.describe( 'Feature area', () => {
198 test.beforeEach( async ( { page } ) => {
199 await loginAsAdmin( page );
200 } );
201
202 test( 'Something works', async ( { page } ) => {
203 const featurePage = new FeaturePage( page );
204 await featurePage.goto();
205 await featurePage.expectNoFatalError();
206 // assertions...
207 } );
208 } );
209 ```
210
211 ---
212
213 ## CI
214
215 The E2E workflow (`.github/workflows/e2e.yml`) runs on pull requests that touch:
216 - `classes/**`, `inc/**`, `assets/**`, `views/**` — PHP/JS plugin code
217 - `Tests/e2e/**` — test files themselves
218 - `.wp-env.json`, `bin/dev-up.sh`, `bin/dev-seed.sh` — environment config
219 - `composer.json`, `.github/workflows/e2e.yml`
220
221 The `IMAGIFY_TESTS_API_KEY` secret must be set in the GitHub repository settings for API-dependent tests to run. Without it, those tests are automatically skipped and the suite still passes.
222
223 ---
224
225 ## Known coverage gaps
226
227 The following areas are not yet covered by automated E2E tests (good places to contribute):
228
229 - Custom folders optimization workflow
230 - WP-CLI bulk-optimize and bulk-restore commands (use `wpCli()` fixture)
231 - Admin notices (API quota reached, outdated plugin)
232 - Network mode (proxy URL, login/password settings)
233 - Multisite network activation
234