ci: add wp-env Playwright E2E workflow - #77
Conversation
Free-side fixes for getdokan/tryaura-pro#16 (breakage after the Gemini model upgrade): - Image prompt fidelity: the merchant's instruction now leads the prompt instead of a forced "put the product on a human model" try-on template (finding 2). - Try-on: iterate the response parts to find the image instead of assuming parts[0], handling both inlineData and inline_data (finding 3). - Thumbnail: catch the cross-origin toDataURL() throw, set crossOrigin before src, and add a 15s timeout so it can never hang (finding 4). - Cancel: AbortController threaded through the image fetch and the SDK call; Close/X now cancel instead of being disabled while generating (finding 5). - Model resolution: replace the decommissioned -preview fallback with a live model and validate the saved model against the tryaura_ai_models registry (finding 6). - Rename the imageSize store field to aspectRatio (it holds the aspect ratio). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… text (#65) * feat: Wave 1 image enhancements — negative prompt, aspect ratios, alt text Free-side Wave 1 (Phase 1) enhancements: - Image negative prompt: an editable (Pro-gated) field, injected as prompt text since the Gemini native-image generateContent path has no negativePrompt param (getdokan/tryaura-pro#22). - Aspect ratio: relabel "Image Size" -> "Aspect Ratio" and limit the ratios to the Gemini-documented set (1:1, 2:3, 3:2, 3:4, 4:3, 9:16, 16:9, 21:9); 1:1 free, non-square Pro-gated (getdokan/tryaura-pro#23). - AI alt text: after each image a Gemini text call generates SEO/accessibility alt text into an editable field with Regenerate, saved to the attachment's alt_text on Add-to-Library, with usage logging (getdokan/tryaura-pro#25). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat: Wave 2 image differentiators — scene staging, resolution, reference angles (#68) * feat: Wave 2 image differentiators — scene staging, resolution, reference angles Implements the image side of Wave 2. Issues are tracked in getdokan/tryaura-pro; the video counterparts land in that repo separately. getdokan/tryaura-pro#27 — Expanded background / scene staging - New sceneStaging module: single source of truth shared by the config dropdown and the prompt builder, so options and their scene text cannot drift apart. - Options expanded from Plain/Studio/Natural to add Lifestyle, Marble surface, Wood table, Outdoor and Room/interior. - Each option resolves to a rich scene instruction injected into the prompt. Plain (or an unknown value) resolves to empty, keeping the product on a neutral background. The scene is a separate preference line, so it never overrides the merchant's typed prompt. - Filterable via tryaura.enhancer.background_preferences and tryaura.enhancer.background_scene_instruction. getdokan/tryaura-pro#29 — Image resolution (1K / 2K / 4K) - New Resolution control, sent as imageConfig.imageSize. - 4K routes to gemini-3-pro-image (Nano Banana Pro) regardless of the saved model, overridable via the tryaura.image_4k_model filter. - imageSize is only sent to Gemini 3 models. It is a Gemini 3 feature, and sending it to the older gemini-2.5-flash-image risks rejecting every request for merchants still on that model. getdokan/tryaura-pro#28 — Reference images (image side) - New "Reference angles" strip under the source image so merchants can add extra photos of the real product. - References are sent as additional inlineData parts, raising the effective cap from 3 toward the API limit (14 total parts). - A fidelity hint tells the model the extras are the same product from other angles, filterable via tryaura.ai_enhance_reference_hint. getdokan/tryaura-pro#26 — Template library (free-side hook only) - "Start from a look" is a Pro feature. This adds the non-Pro locked teaser and the tryaura.enhancer.image_template_row injection point; the Pro plugin fills it with the working row. - Store carries templateId so Pro can drive the shared image config. Verified: production build clean; 38 deterministic logic tests pass (scene resolution, 4K routing, imageSize gating, reference encoding/caps); image generation and Virtual Try-On exercised end-to-end in the browser. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: Wave 3 — Edit tab, on-model / ghost-mannequin, cleanup (#69) * feat: Wave 3 — on-model / ghost-mannequin and cleanup tools The two Wave 3 items feasible on BYOK. Both are image features living entirely in the free plugin and use the normal client-side generateContent path. Edit mode (getdokan/tryaura-pro#32) is skipped: the edit/mask APIs are Vertex-only, so its pixel-faithful acceptance criteria cannot be met on the Gemini Developer API. getdokan/tryaura-pro#33 — On-model and ghost-mannequin - New apparelModes module + an "Apparel Output" select: Default / On model / Ghost mannequin. - "On model" was already the enhancer's default when no prompt was typed; this makes it an explicit choice. Ghost mannequin is the new mode — the garment holds its worn 3D shape with no visible person or mannequin — and is Pro-gated (locked chip + upgrade popover), matching the issue. - Both modes append a fidelity clause so only the presentation changes, never the garment. Merchant direction (model type, pose) is honoured. getdokan/tryaura-pro#34 — Cleanup tools - New cleanupPresets module + one-click chips: De-wrinkle, Remove dust & lint, Remove blemishes. Clicking a chip applies the fix and generates immediately; clicking the active chip clears it. - Each preset is a fixed instruction plus a preserve clause that pins the product's shape, colour, logos and text, so only the named defect changes. - The issue allows whole-image edits when Edit mode is absent, which is what this does; the presets can later become Edit-mode quick-edits unchanged. Shared wiring - Prompt precedence in PreviewModal: cleanup > apparel > typed instruction > default try-on. Each is mutually exclusive and none breaks the existing paths. - Both features route to gemini-3-pro-image (the higher-fidelity model) so the product stays faithful, via the tryaura.image_high_fidelity_model filter. - Store carries apparelMode + cleanupPreset; both reset with the modal. Review fix folded in - The block-editor empty-prompt guard (and the Generate button's matching disable) treated a cleanup preset / apparel mode as "no instruction" and blocked generation for Pro users on Gutenberg pages. Both now treat a selected mode/preset as the directive. Found in adversarial review, not tests. Verified: production build clean; 302 deterministic tests across all sub-issues (with corner cases), green. Both features tested against their real modules. Headed UI audit confirmed both controls render. Live generation is pending (project spend cap). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat: Edit tab — targeted edits, absorbing the cleanup tools Adds the feasible-on-BYOK part of Edit mode as a dedicated third "Edit" tab, matching the prototype, and moves the getdokan/tryaura-pro#34 cleanup work into it. Why a separate tab and not a brush: the Gemini Developer API edits conversationally ("describe the region, leave the rest untouched"); it does not take a pixel mask (that path is Vertex-only via editImage/MaskReferenceImage). So the brush/mask from the issue is out of scope; the tab ships Quick edits + an instruction, which is what BYOK supports. See the note on getdokan/tryaura-pro#32. Edit tab (EditConfigInputs, Pro-gated in the free plugin) - Five selectable edit types: Remove text, Recolor, Remove object, Clean up, Swap background. Selecting one is a toggle; the Edit-instruction field adds free-text refinement. The two combine at generation time. - "Clean up" is the getdokan/tryaura-pro#34 cleanup action (wrinkles, dust, blemishes) in one type; the separate cleanupPresets module is removed. - Non-Pro sees a locked teaser (PRO badge + crown + upgrade popover) and no Apply button. Wiring - New Edit tab in ConfigSettings; PreviewModal renders the Original + Output panels for it and adds an edit branch in doGenerate that reuses the existing targeted-edit prompt path, so only the instructed change is applied. - Edits route to gemini-3-pro-image and omit aspect/size constraints so the source framing is preserved. "Add to Media Library" works for edits. - ConfigFooter gains Apply edit / Re-apply labels. Review fixes folded in - Edits no longer carry the multi-image try-on composition hint (it would tell the model to compose a model-wearing-product shot instead of editing). - getdokan/tryaura-pro#29: selecting 2K on an older image model (gemini-2.5-flash-image) silently rendered at 1K, because only 4K forced a Gemini 3 model and imageSize is Gemini-3-only. 2K now upgrades to the default Gemini 3 flash model so the resolution actually applies; 1K and the default model are untouched. Verified: production build clean; 149 deterministic tests (comprehensive, real modules) covering the edit types, combine logic, precedence, the block-editor guard, and the 2K routing fix. No new dependencies; still BYOK + client-side. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: show the Pro crown on the Edit tab for non-Pro users The Edit tab is Pro-gated, so its tab button now carries the Pro crown for non-Pro users (locked: ! hasPro()) — matching the Generate Video tab. Pro users see no crown, same as video. The tab stays clickable so non-Pro can open the locked teaser. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * refactor: shorten enhancer tab labels to Image / Video / Edit The three-tab switcher read "Generate Image" / "Generate Video" / "Edit"; the "Generate" prefix was redundant with the generate button below. Shorten the two tab labels to "Image" and "Video" ("Edit" already matched). The Generate-video action button keeps its full label; the Pro plugin reuses this tab definition, so no Pro change is needed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * refactor: update modal title and adjust styles for consistency * feat: admin Top Bar — logo, version badges, Get Support, help menu (#72) * feat: admin Top Bar with logo, version badges, Get Support and help menu Adds a persistent StorePulse Top Bar to all TryAura admin screens using @wedevs/plugin-ui (TopBar + DropdownMenu). The bar mounts in its own root (#tryaura-admin-header) outside the .tryaura Tailwind scope — so the plugin's importantized utilities can't clobber plugin-ui — and outside .wrap so it spans the full content width. A .wp-header-end notice-catcher hoists the bar above the WordPress admin notices, matching Dokan's dashboard behavior. PHP localizes version, hasPro, and proVersion read from the plugin file headers. Help menu items are extensible via the tryaura.admin.help_menu_items filter. No custom theme / dark mode / Shadow DOM (default plugin-ui tokens). Closes getdokan/tryaura-pro#41. Refs getdokan/tryaura-pro#40. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S5bM5ACrcGFwvVo6jEyVKF * refactor: update Top Bar button size and help icon styling for consistency * fix: stop other plugins' global Tailwind utilities from breaking the Top Bar Plugins like dokan-pro ship plugin-ui's utilities globally in wp-admin scoped to :is(.pui-root, .dokan-layout) — specificity (0,2,0) — sometimes from an older plugin-ui build that lacks the Top Bar's responsive variants (md:h-7.5, md:px-2, ...). Their base utilities (p-0, h-10) then beat the (0,1,0) copies bundled here and squash the version badges into oversized ovals. Re-emit the Top Bar's utilities under the #tryaura-admin-header ID — (1,1,0) + !important — via a standalone Tailwind compilation so the bar wins regardless of what other plugins load. It lives in its own topbar/style.css imported from index.tsx because Tailwind honors only one utilities emission per compilation, and wp-scripts only merges files named style.* into style-index.css. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RsGWnuhsHFrL2GaKE1qc9a * feat: add Pro promotion touchpoints — promo banner, sidebar Upgrade button, plugins screen link (#73) Adds three upgrade touchpoints shown only while TryAura Pro is not active (getdokan/tryaura-pro#42): - Dismissible "Go Pro. Create Without Limits." banner on all dashboard SPA routes; per-user dismissal stored as a timestamp in user meta via a new tryaura/v1/promotion/dismiss-banner endpoint, re-shown after 30 days - "Upgrade" entry in the TryAura admin sidebar styled as a filled button, opening the pricing page in a new tab - Bold "Upgrade to Pro" action link on the All Plugins screen, plus a shortened plugin header description Claude-Session: https://claude.ai/code/session_01UL9nyXmJTkPB7QmT7jTKGF Co-authored-by: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ade button Design tweaks to the Pro promotion touchpoints (getdokan/tryaura-pro#42): - Promo banner: white background with a light border and a yellow (#ffd932) "Upgrade Now" button with black text, replacing the all-yellow card with a black button. - Sidebar Upgrade entry: full-width, centered button (Elementor style) instead of an inline-sized one. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UL9nyXmJTkPB7QmT7jTKGF
The tab group sized to its content, leaving empty space to the right and shifting width between the Pro (no crown badges) and non-Pro states. Adds a fullWidth option to GroupButton that stretches the group to fill its container and splits it evenly across tabs, so the three tabs occupy the whole column consistently — matching the fields below — in both cases. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UL9nyXmJTkPB7QmT7jTKGF
Bumps the version in all four canonical spots ahead of the 2.0.0 release: - package.json (source of truth) - tryaura.php plugin header - inc/Plugin.php $version property - readme.txt Stable tag The `@since PLUGIN_SINCE` placeholders and the .pot header are left to the release pipeline (npm run version / npm run makepot). Claude-Session: https://claude.ai/code/session_01UL9nyXmJTkPB7QmT7jTKGF Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Adds a dokan-lite-style test suite that never spends a Gemini token (docs/adr/0002-token-free-test-strategy.md). PHPUnit (27) — boots real WP + WooCommerce; the try-on Gemini call is stubbed via a pre_http_request filter plus a network guard so nothing can reach the API. Covers every REST controller (settings, generate/try-on, promotion, dashboard/usage, product, video-thumbnail), bulk try-on, container wiring, and the promo-banner 30-day dismissal logic. Playwright E2E on @wordpress/env — one suite, dokan-style @lite/@Pro tags: - @lite (Pro off, 10): dashboard nav, enhancer image generation (browser page.route Gemini stub), image-config field->request combinations, the promo banner / plugins-screen link / sidebar Upgrade, settings save. - @Pro (Pro on, 7): promo touchpoints hidden when Pro is active, video generation via a stubbed Veo operation + fake-URI + a committed 1.7 KB MP4, and video-config combinations. tryaura-pro is mapped into wp-env; the license is simulated in the test-guard mu-plugin (no license server in CI). Run: composer test | (tests/pw) npm run test:lite / npm run test:pro Claude-Session: https://claude.ai/code/session_01UL9nyXmJTkPB7QmT7jTKGF Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Runs the @lite and @Pro suites in one job against @wordpress/env. Builds the plugin first (composer install in dev mode so Mozart emits lib/packages/, then npm run build) because build/, lib/ and vendor/ are gitignored. .wp-env.json maps ../../../tryaura-pro as a workspace sibling, so the job either checks out the Pro repo there (when PRO_REPO_TOKEN is set) or writes a stub plugin header, without which wp-env start aborts. @lite and @Pro run sequentially against a single wp-env instance, each with its own Playwright --output dir so the second run does not wipe the first one's traces. The @Pro step is guarded by !cancelled() so a @lite failure still reports both suites.
📝 WalkthroughWalkthroughAdds a GitHub Actions Playwright pipeline for Lite and optional Pro wp-env testing, shared admin authentication state, Gemini test-key seeding, dynamic wp-env configuration, and CI reports, summaries, diagnostics, and artifacts. ChangesE2E CI pipeline
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant GitHubActions
participant wpEnv
participant Playwright
participant JobSummary
GitHubActions->>wpEnv: Prepare and start Lite or Pro environment
GitHubActions->>Playwright: Run `@lite` and conditional `@pro` suites
Playwright->>JobSummary: Write JSON test results
GitHubActions->>JobSummary: Publish suite summary
GitHubActions->>Playwright: Upload reports and test artifacts
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
The lock was resolved on PHP 8.4 with no platform pin, so it carried doctrine/instantiator 2.1.0 (php ^8.4) and symfony/string 6.4 (php >=8.1). That broke `composer install` on any runner below 8.4 — the E2E job on 8.2 and deploy.yml on 7.4 alike — and would have crashed Mozart even with --ignore-platform-reqs, since Mozart loads symfony/console. Pin config.platform.php to 7.4 (the plugin's declared minimum) and re-lock: instantiator drops to 1.5.0, symfony to 5.4/1.x, phpunit stays 9.6.35, and vendor/composer/platform_check.php now asserts >= 70400. Also gate the spec steps on the wp-env start step succeeding. Previously !cancelled() alone let them run after a failed build, burying the real error under "wp-env: not found".
`npm ci` refused the committed lock: it still carried version 1.0.4 and was missing date-fns@4.4.0, an optional peer that @wedevs/plugin-ui pulls in. Regenerated so the lock matches package.json. Node bumped 20 -> 22 because @wedevs/plugin-ui declares engines.node >= 22.
The workflow carried a Pro path that cannot run: getdokan/tryaura-pro has no plugin source and no PRO_REPO_TOKEN is configured, so the token probe, the Pro checkout, the conditional Pro build and the @Pro step were dead weight. Dropped them along with the per-suite --output dirs, the wp-env stop step (the runner is ephemeral) and the step-outcome guard expressions. 151 lines -> 81. What stays is load-bearing: composer install runs in dev mode because Mozart only then emits lib/packages/, and build/, lib/ and vendor/ are gitignored. The tryaura-pro stub directory stays too — .wp-env.json maps it, and wp-env start aborts when the mapping target is missing. Also seed a fake Gemini API key in global setup. PreviewModal returns early when google.apiKey is empty, so on CI's clean database the enhancer and image-config specs never fired a request and 5 of 10 failed. Only settings-save.spec.ts writes a key and, with workers: 1, it runs after them — those specs passed locally only because the dev database already had one.
The workflow now calls `npm run test:e2e`, which was plain `playwright test` — that pulls in the 7 @Pro specs under tests/e2e/pro/ (17 tests, 10 files). They need the real Pro plugin, and CI only maps a stub, so they would always fail. test:e2e now runs --grep-invert @Pro (10 tests, 7 files: every @lite spec, plus anything added later that is not Pro-only). The full sweep moves to test:all for local use where the Pro plugin is present.
The CI reporter was `github`, which only emits annotations for failures — a passing run left no evidence anything executed, and the excluded `@pro` suite made the green tick look like full coverage. Adds `list` (every test in the build log), `json` (feeds the new job-summary script) and `html` (uploaded as an artifact) reporters, writes a results table to the GitHub job summary that names the suites which did NOT run, and uploads the report on success as well as failure. A run that produces no results now says so explicitly rather than passing silently. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Three related fixes to the wp-env E2E setup, following the dokan-lite layout. Log in once instead of per test. Every spec called loginAsAdmin in beforeEach, so the ~2s wp-login round trip ran 10 times for @lite and 17 for the full suite. A setup project now authenticates once and caches the session; the chromium project starts from it via storageState. @lite drops 43.5s -> 21.6s. The setup test is tagged with BOTH suite tags because --grep filters setup projects too, and a setup dropped by --grep leaves the run unauthenticated — which is also why test:e2e moves from --grep-invert @Pro to --grep @lite. Stop mapping Pro from the default wp-env config. Mapping a directory that does not exist aborts wp-env start, which is why CI wrote a fake plugin header to satisfy it. Now .wp-env.json is lite-only and .wp-env.ci.json adds Pro, with prepare-wp-env.mjs selecting between them based on whether Pro is really on disk — so "Pro absent" is an honest state instead of a stub, and the workflow checks out the private repo when PRO_REPO_TOKEN is available. Pro needs php >=8.0, so its build gets its own PHP setup; the free build keeps 7.4. Report both suites separately. The @lite and @Pro runs each get their own report dir, and their result JSON moves out of test-results/ because Playwright wipes that directory at the start of every run — the @Pro run was deleting the @lite summary. When Pro is not checked out, the job summary says the suite was skipped rather than passing silently. Verified locally both ways: Pro absent (wp-env starts lite-only, 11 passed) and Pro present (@lite 11 passed, then @Pro 8 passed). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
.github/workflows/e2e.yml (2)
24-25: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winAdd
persist-credentials: falseto checkout.Static analysis flags credential persistence here: the checked-out repo retains the
GITHUB_TOKENin git config for the rest of the job, including the untrustednpm ci/npm run buildsteps that follow. Addpersist-credentials: falsesince the workflow doesn't need to push or make further authenticated git calls.🔒 Suggested fix
- name: Checkout code uses: actions/checkout@v4 + with: + persist-credentials: false🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/e2e.yml around lines 24 - 25, Update the checkout step using actions/checkout@v4 to set persist-credentials to false, ensuring the workflow does not retain GITHUB_TOKEN credentials for subsequent build and dependency-installation steps.Source: Linters/SAST tools
14-22: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winConsider declaring explicit least-privilege
permissions.The workflow has no
permissions:block, so the job inherits the repo/org defaultGITHUB_TOKENpermissions (which may be broader thancontents: read). Given this job checks out code and runs third-party install/build scripts onpull_request, scoping permissions explicitly reduces blast radius if a dependency is compromised.🔒 Suggested fix
jobs: e2e: name: Playwright E2E Tests runs-on: ubuntu-latest timeout-minutes: 30 + permissions: + contents: read env:🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/e2e.yml around lines 14 - 22, Add an explicit least-privilege permissions block to the e2e workflow, scoped to the e2e job or workflow, granting only contents read access required by checkout. Keep the existing Playwright E2E Tests job behavior unchanged and do not grant broader write permissions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/e2e.yml:
- Around line 56-67: Update the “Checkout tryaura-pro” action to prevent the
PRO_REPO_TOKEN from being persisted in the checked-out repository’s Git
configuration, while preserving authenticated access to the private repository.
Ensure the token is unavailable on disk before subsequent composer, npm, and
build steps execute.
In `@tests/pw/.wp-env.ci.json`:
- Around line 2-6: Pin the E2E dependencies in the CI WordPress environment
configuration: replace the floating WordPress core repository reference, Basic
Auth master archive, and generic WooCommerce ZIP with immutable release versions
or commit-SHA-based URLs. Keep the existing plugin list and PHP version
unchanged while ensuring all external dependencies resolve reproducibly across
CI runs.
In `@tests/pw/global-setup.ts`:
- Around line 19-29: Update globalSetup around the seed-settings execSync call
so failures are not silently ignored: log the caught error and re-throw it, or
verify tryaura_settings.google.apiKey exists before allowing the suite to start.
Preserve the existing seeding behavior while ensuring missing or failed Gemini
setup aborts global setup.
---
Nitpick comments:
In @.github/workflows/e2e.yml:
- Around line 24-25: Update the checkout step using actions/checkout@v4 to set
persist-credentials to false, ensuring the workflow does not retain GITHUB_TOKEN
credentials for subsequent build and dependency-installation steps.
- Around line 14-22: Add an explicit least-privilege permissions block to the
e2e workflow, scoped to the e2e job or workflow, granting only contents read
access required by checkout. Keep the existing Playwright E2E Tests job behavior
unchanged and do not grant broader write permissions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 7b338d37-adef-45d6-932b-295544b670c0
⛔ Files ignored due to path filters (2)
composer.lockis excluded by!**/*.lockpackage-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (24)
.github/workflows/e2e.yml.gitignorecomposer.jsontests/pw/.wp-env.ci.jsontests/pw/.wp-env.jsontests/pw/global-setup.tstests/pw/package.jsontests/pw/playwright.config.tstests/pw/scripts/ci-summary.mjstests/pw/scripts/prepare-wp-env.mjstests/pw/seed-settings.phptests/pw/tests/e2e/_auth.setup.tstests/pw/tests/e2e/dashboard.spec.tstests/pw/tests/e2e/enhancer.spec.tstests/pw/tests/e2e/image-config.spec.tstests/pw/tests/e2e/plugins-screen.spec.tstests/pw/tests/e2e/pro/promo-hidden.spec.tstests/pw/tests/e2e/pro/video-config.spec.tstests/pw/tests/e2e/pro/video-generation.spec.tstests/pw/tests/e2e/promo-banner.spec.tstests/pw/tests/e2e/settings-save.spec.tstests/pw/tests/e2e/sidebar-upgrade.spec.tstests/pw/tsconfig.jsontests/pw/utils/auth.ts
💤 Files with no reviewable changes (11)
- tests/pw/.wp-env.json
- tests/pw/tests/e2e/plugins-screen.spec.ts
- tests/pw/tests/e2e/promo-banner.spec.ts
- tests/pw/tests/e2e/enhancer.spec.ts
- tests/pw/tests/e2e/dashboard.spec.ts
- tests/pw/tests/e2e/pro/video-generation.spec.ts
- tests/pw/tests/e2e/pro/promo-hidden.spec.ts
- tests/pw/tests/e2e/settings-save.spec.ts
- tests/pw/tests/e2e/sidebar-upgrade.spec.ts
- tests/pw/tests/e2e/pro/video-config.spec.ts
- tests/pw/tests/e2e/image-config.spec.ts
| - name: Checkout tryaura-pro | ||
| if: env.PRO_REPO_TOKEN != '' | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| repository: getdokan/tryaura-pro | ||
| path: .tryaura-pro-src | ||
| token: ${{ env.PRO_REPO_TOKEN }} | ||
|
|
||
| # Pro's composer.json requires php >=8.0, so it cannot be installed | ||
| # with the 7.4 toolchain used for the free plugin (which pins 7.4 to | ||
| # match its own minimum). Only the runner's PHP changes here — wp-env | ||
| # serves both plugins on 8.2 regardless. |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Persisted PRO_REPO_TOKEN credentials in a step that later runs untrusted build scripts.
Same artipacked finding as the main checkout, but with elevated risk: this checkout persists PRO_REPO_TOKEN — a dedicated cross-repo token — into .tryaura-pro-src/.tryaura-pro's git config, which then sits on disk while composer install, npm ci, and npm run build (line 85-87) execute arbitrary scripts from the Pro repo's dependency tree. A malicious or compromised dependency could read and exfiltrate this token.
🔒 Suggested fix
- name: Checkout tryaura-pro
if: env.PRO_REPO_TOKEN != ''
uses: actions/checkout@v4
with:
repository: getdokan/tryaura-pro
path: .tryaura-pro-src
token: ${{ env.PRO_REPO_TOKEN }}
+ persist-credentials: false📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - name: Checkout tryaura-pro | |
| if: env.PRO_REPO_TOKEN != '' | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: getdokan/tryaura-pro | |
| path: .tryaura-pro-src | |
| token: ${{ env.PRO_REPO_TOKEN }} | |
| # Pro's composer.json requires php >=8.0, so it cannot be installed | |
| # with the 7.4 toolchain used for the free plugin (which pins 7.4 to | |
| # match its own minimum). Only the runner's PHP changes here — wp-env | |
| # serves both plugins on 8.2 regardless. | |
| - name: Checkout tryaura-pro | |
| if: env.PRO_REPO_TOKEN != '' | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: getdokan/tryaura-pro | |
| path: .tryaura-pro-src | |
| token: ${{ env.PRO_REPO_TOKEN }} | |
| persist-credentials: false | |
| # Pro's composer.json requires php >=8.0, so it cannot be installed | |
| # with the 7.4 toolchain used for the free plugin (which pins 7.4 to | |
| # match its own minimum). Only the runner's PHP changes here — wp-env | |
| # serves both plugins on 8.2 regardless. |
🧰 Tools
🪛 zizmor (1.28.0)
[warning] 56-67: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/e2e.yml around lines 56 - 67, Update the “Checkout
tryaura-pro” action to prevent the PRO_REPO_TOKEN from being persisted in the
checked-out repository’s Git configuration, while preserving authenticated
access to the private repository. Ensure the token is unavailable on disk before
subsequent composer, npm, and build steps execute.
Source: Linters/SAST tools
| "core": "WordPress/WordPress", | ||
| "phpVersion": "8.2", | ||
| "plugins": [ | ||
| "https://github.com/WP-API/Basic-Auth/archive/master.zip", | ||
| "https://downloads.wordpress.org/plugin/woocommerce.zip" |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== file ==="
cat -n tests/pw/.wp-env.ci.json 2>/dev/null || true
echo "== related wp-env config files =="
git ls-files | rg '(^|/)(wp-env|\.wp-env)(\.ci)?\.json$|package\.json|composer\.json|README|\.github/workflows' || true
echo "== occurrences of wp-env and PHP versions =="
rg -n '"phpVersion"|wp-env|WordPress-API/Basic-Auth|woocommerce\.zip|WordPress/WordPress' -S . --glob '!node_modules' --glob '!dist' --glob '!build' || true
echo "== package manager wp-env scripts =="
python3 - <<'PY'
import json, pathlib
for p in pathlib.Path('.').rglob('package.json'):
if 'node_modules' in p.parts:
continue
try:
data=json.load(open(p))
except Exception:
continue
scripts=data.get('scripts',{})
vals={}
for k,v in scripts.items():
if 'wp-env' in v or 'e2e' in k.lower() or 'playwright' in k.lower():
vals[k]=v
if vals:
print(p)
for k,v in vals.items(): print(f" {k}: {v}")
PYRepository: getdokan/tryAura
Length of output: 6221
🌐 Web query:
WordPress wp-env config core plugin ZIP URL unresolved branch master latest version deterministic
💡 Result:
In the wp-env configuration, using a ZIP URL for core, plugins, or themes is supported [1][2]. However, referencing a branch such as 'master' (e.g., 'WordPress/WordPress#master') via a ZIP URL is not natively possible because ZIP URLs are direct, static links to compressed archives and do not support Git branch referencing or dynamic resolution [1][3][4]. Deterministic behavior in wp-env is achieved by providing specific, immutable identifiers [5]. Here is the distinction between your options: 1. ZIP URLS: These are deterministic only if the URL points to a specific, versioned file (e.g., 'https://wordpress.org/wordpress-6.8.2.zip') [5][6][2]. Using a generic or mutable URL, such as 'latest.zip', is explicitly discouraged because it does not change when the underlying content changes, which can lead to stale cache issues where wp-env fails to recognize that the environment needs to be updated [5]. 2. GitHub Repository References: When using the format 'User/Repo#branch', wp-env performs a Git clone [7][4]. This is not strictly deterministic if you reference a branch like 'master' or 'trunk', as the content at that branch will change over time [1][3]. To achieve determinism with a Git source, you should reference a specific commit SHA or a version tag (e.g., 'WordPress/WordPress#6.8.2') [1][8]. If you need to test 'master' (development) versions, using a Git repository reference is the standard approach, but it will pull the latest state of that branch at the time the environment is created [1][9]. If you require a stable, deterministic environment, use a versioned ZIP URL or a specific Git tag/commit [5].
Citations:
- 1: https://github.com/WordPress/gutenberg/blob/trunk/packages/env/README.md
- 2: Env: Add support for ZIP URL sources. WordPress/gutenberg#20426
- 3: https://www.npmjs.com/package/@wordpress/env
- 4: https://make.wordpress.org/core/2020/03/03/wp-env-simple-local-environments-for-wordpress/
- 5: Use versioned WordPress.org ZIP for wp-env’s default core source WordPress/gutenberg#78942
- 6: @wordpress/env: Add support for more types of sources WordPress/gutenberg#20325
- 7: @wordpress/env: A zero-config, self contained local WordPress environment for development and testing. WordPress/gutenberg#17724
- 8: https://github.com/WordPress/gutenberg/tree/trunk/packages/env
- 9: Add .wp-env.json support to wp-env WordPress/gutenberg#20002
🌐 Web query:
WordPress wp-env core package plugin archive branch zip latest version
💡 Result:
In the WordPress @wordpress/env (wp-env) package, the core, plugin, and theme sources are configured via the.wp-env.json file [1][2]. The tool supports several source types for these fields, including specific branches and ZIP archives [1][2]. Core Configuration If the core field is not specified in.wp-env.json, wp-env defaults to the latest stable WordPress release [1][2]. As of recent updates, this default behavior is implemented by fetching a versioned WordPress.org ZIP file rather than cloning a Git repository, which improves performance by reducing overhead [3]. Supported Source Types You can specify the following formats for the core, plugins, or themes fields in your configuration: 1. ZIP Files: You can point to any publicly accessible WordPress ZIP archive using a URL (e.g., "https://wordpress.org/wordpress-6.8.2.zip") [1][2]. Note that using versioned ZIPs is preferred over generic "latest.zip" URLs to ensure wp-env correctly detects changes and triggers updates to the environment [3]. 2. GitHub Repositories: You can specify a repository in the format "Owner/Repo" [1][2]. You can also append a branch, tag, or commit hash using the # symbol (e.g., "WordPress/WordPress#trunk" or "WordPress/gutenberg#my-branch") [1][2]. If no branch is specified, it defaults to the repository's default branch [1][2]. 3. Local Paths: Relative or absolute paths to local directories can be used for plugins and themes (e.g., "." to mount the current directory) [1][2]. 4. SSH Repositories: SSH URLs can also be used for remote Git sources [1][2]. Environment Updates When you modify your.wp-env.json configuration, wp-env does not automatically reconfigure the environment [4]. To apply changes to sources (such as switching branches or updating a ZIP URL), you must run the following command: wp-env start --update [4] This command forces wp-env to download the updated sources and re-apply the configuration without overwriting existing content in the environment [4].
Citations:
- 1: https://github.com/WordPress/gutenberg/blob/trunk/packages/env/README.md
- 2: https://github.com/WordPress/gutenberg/tree/trunk/packages/env
- 3: Use versioned WordPress.org ZIP for wp-env’s default core source WordPress/gutenberg#78942
- 4: https://developer.wordpress.org/block-editor/reference-guides/packages/packages-env/
🌐 Web query:
wordpress org plugin downloader PHP 7.4 EOL plugin versions compatibility wordpress 6.9 PHP 7.4
💡 Result:
WordPress 6.9 is fully compatible with PHP 7.4 [1]. However, it is critical to note that PHP 7.4 reached its official end-of-life (EOL) on November 28, 2022, and no longer receives security updates from the PHP project [2][3][4][5]. While WordPress Core continues to support PHP 7.4 for backward compatibility purposes, this support is intended to allow older sites to function while planning their migration [1][6]. WordPress officially recommends using PHP 8.3 or greater for better performance and security [6]. Key points regarding PHP 7.4 and WordPress 6.9: 1. Security Risk: Running PHP 7.4 exposes your site to known security vulnerabilities because the version is EOL and unpatched [3][6]. 2. WordPress Support Policy: WordPress maintains support for PHP 7.4 to ensure backward compatibility [1][6], but actively encourages users to upgrade to the latest supported versions of PHP [7][6]. 3. Compatibility: As of WordPress 6.9, the core software is fully compatible with PHP 7.4 through 8.5 [1][8]. 4. Recommendation: You should upgrade to a currently supported PHP version (PHP 8.2 or higher as of July 2026) as soon as possible to maintain a secure environment [9][6]. Plugin compatibility depends on individual plugin authors, as they are not required to follow the same backward compatibility constraints as WordPress Core. If your site relies on older plugins, those plugins may have their own minimum PHP requirements that are higher than 7.4, or they may contain code that is incompatible with the newer PHP versions recommended for security [1][8]. Always check the documentation for each plugin to verify its specific PHP compatibility [6].
Citations:
- 1: https://make.wordpress.org/hosting/handbook/server-environment/
- 2: https://www.php.net/eol.php/
- 3: https://endoflife.ai/php/7.4
- 4: https://php.watch/versions/7.4/releases
- 5: https://www.zend.com/blog/planning-php-7-4-eol
- 6: https://wordpress.org/about/requirements/
- 7: https://make.wordpress.org/core/2025/11/21/php-8-5-support-in-wordpress-6-9/
- 8: https://make.wordpress.org/core/handbook/references/php-compatibility-and-wordpress-versions/
- 9: https://www.php.net/supported-versions.php
🌐 Web query:
WordPress wp-env config core default branch clone WordPress/WordPress
💡 Result:
In the wp-env configuration file (.wp-env.json), the core field allows you to specify a WordPress installation source [1][2]. If you provide a GitHub repository string, such as "WordPress/WordPress", you can optionally append a branch or tag using the # delimiter [1][3]. If you specify a repository but do not provide a branch or tag (e.g., "core": "WordPress/WordPress"), wp-env will automatically fall back to the repository's default branch [1][3]. For example: { "core": "WordPress/WordPress#trunk" } The above configuration would clone the trunk branch of the WordPress/WordPress repository [1][4]. If you were to use "core": "WordPress/WordPress", it would clone the default branch of that repository [1][3]. Note that when no core source is specified in the configuration (the default behavior), wp-env uses a versioned ZIP file from WordPress.org rather than a Git clone to optimize performance [5]. Explicitly providing a GitHub repository string in the core field forces wp-env to treat it as a Git source [1][3].
Citations:
- 1: https://github.com/WordPress/gutenberg/blob/trunk/packages/env/README.md
- 2: https://developer.wordpress.org/block-editor/reference-guides/packages/packages-env/
- 3: https://github.com/WordPress/gutenberg/tree/trunk/packages/env
- 4: https://www.npmjs.com/package/@wordpress/env
- 5: Use versioned WordPress.org ZIP for wp-env’s default core source WordPress/gutenberg#78942
Pin the E2E WordPress dependencies.
core: WordPress/WordPress clones the repo default branch, Basic Auth uses archive/master.zip, and WooCommerce uses the generic plugin ZIP; these external sources can change between CI runs. Pin them to immutable core/plugin versions or commit SHAs for reproducible E2E results.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tests/pw/.wp-env.ci.json` around lines 2 - 6, Pin the E2E dependencies in the
CI WordPress environment configuration: replace the floating WordPress core
repository reference, Basic Auth master archive, and generic WooCommerce ZIP
with immutable release versions or commit-SHA-based URLs. Keep the existing
plugin list and PHP version unchanged while ensuring all external dependencies
resolve reproducibly across CI runs.
| // Ensure a Gemini API key exists — PreviewModal refuses to call Gemini without | ||
| // one, so on a clean/CI DB the enhancer and image-config specs would have no | ||
| // request to intercept. The seeded key is fake; every call is still stubbed. | ||
| try { | ||
| execSync( | ||
| 'npx wp-env run tests-cli wp eval-file wp-content/plugins/tryaura/tests/pw/seed-settings.php', | ||
| { stdio: 'ignore' } | ||
| ); | ||
| } catch ( e ) { | ||
| // best effort — the enhancer specs will surface a missing key clearly | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== files =="
git ls-files | rg '(^|/)(global-setup\.ts|seed-settings\.php|package\.json|playwright|pw|tests/.*)' | sed -n '1,200p'
echo "== target file =="
if [ -f tests/pw/global-setup.ts ]; then
cat -n tests/pw/global-setup.ts
fi
echo "== seed-settings =="
if [ -f wp-content/plugins/tryaura/tests/pw/seed-settings.php ]; then
cat -n wp-content/plugins/tryaura/tests/pw/seed-settings.php
elif [ "$(git ls-files | grep 'seed-settings\.php$' | head -n1)" ]; then
f="$(git ls-files | grep 'seed-settings\.php$' | head -n1)"
echo "-- found at $f --"
cat -n "$f"
fi
echo "== usages of google.apiKey / tryaura_settings =="
rg -n "google\.apiKey|tryaura_settings|PreviewModal|Preview|enhancer=image-config|image-config" -S --glob '!node_modules' --glob '!dist' --glob '!build' . | sed -n '1,240p'
echo "== package scripts =="
if [ -f package.json ]; then
jq '.scripts' package.json
fiRepository: getdokan/tryAura
Length of output: 11056
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== PreviewModal key bail paths =="
rg -n "tryaura_settings|google|apiKey|new GoogleGenAI|route\(|page\.route" src/admin/enhancer/PreviewModal.tsx | sed -n '1,220p'
echo "== Read relevant PreviewModal sections =="
sed -n '290,360p' src/admin/enhancer/PreviewModal.tsx
sed -n '360,470p' src/admin/enhancer/PreviewModal.tsx
sed -n '600,720p' src/admin/enhancer/PreviewModal.tsx
sed -n '720,840p' src/admin/enhancer/PreviewModal.tsx
sed -n '880,920p' src/admin/enhancer/PreviewModal.tsx
echo "== Tests around seed/spec expectations =="
sed -n '1,140p' tests/pw/tests/e2e/enhancer.spec.ts
sed -n '1,160p' tests/pw/tests/e2e/image-config.spec.ts
sed -n '1,140p' tests/pw/tests/e2e/settings-save.spec.ts
echo "== Playwright config workers/env =="
cat -n tests/pw/playwright.config.ts | sed -n '1,220p'
echo "== Script failure model =="
node - <<'JS'
function globalSetup(exitCode=0) {
try {
if (exitCode !== 0) throw new Error('seed failed');
return 'continues';
} catch (e) {
// best effort ignored
return 'continues';
}
}
console.log(JSON.stringify({
whenSeedSucceeds: globalSetup(0),
whenSeedFails: globalSetup(1),
}, null, 2));
JSRepository: getdokan/tryAura
Length of output: 24395
Do not silently ignore Gemini seed failures.
globalSetup catches any failure from seed-settings.php and continues under workers: 1, so CI can still pass into specs that expect a key. Re-throw after logging, or verify that tryaura_settings.google.apiKey is present before starting the suite.
🧰 Tools
🪛 ast-grep (0.45.0)
[warning] Importing child_process exposes a command-execution surface; ensure any command/argument built from input is validated, and prefer execFile/spawn with an argument array over exec.
Context: import { execSync } from 'child_process';
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(detect-child-process-typescript)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tests/pw/global-setup.ts` around lines 19 - 29, Update globalSetup around the
seed-settings execSync call so failures are not silently ignored: log the caught
error and re-throw it, or verify tryaura_settings.google.apiKey exists before
allowing the suite to start. Preserve the existing seeding behavior while
ensuring missing or failed Gemini setup aborts global setup.
Summary
Adds
.github/workflows/e2e.yml— runs the Playwright suite fromtests/pw/against@wordpress/envon every PR, on pushes tomain, and manually viaworkflow_dispatch(suite:both/lite/pro).Both tagged suites run in a single job, against one wp-env instance:
composer install(dev mode — Mozart emitslib/packages/) +npm ci && npm run build;build/,lib/,vendor/are gitignored, so nothing works without this.wp-env.jsonmaps../../../tryaura-pro(a sibling of the workspace). Checks outgetdokan/tryaura-prothere whenPRO_REPO_TOKENis set, otherwise writes a stub plugin header — a missing directory makeswp-env startabort even for@litenpm run test:litethennpm run test:pro, each with its own--outputdirwp-env logs tests --no-watch, plus Playwright traces/screenshots uploaded as artifactsNotes
@prostep is guarded by!cancelled(), so a@litefailure still reports both suites in one run.test:litedeactivatestryaura-pro,test:proactivates it.@prois skipped until thePRO_REPO_TOKENsecret is added (a repo-scoped token forgetdokan/tryaura-pro). Note that repo currently has no plugin source, so the Pro run needs that code landed before it can pass."core": "WordPress/WordPress"in.wp-env.jsonclones the full WP git history on every run — pinning it (e.g.WordPress/WordPress#6.8) would cut several minutes off CI. Left as-is here.Test plan
@litePRO_REPO_TOKEN, re-run, confirm@proexecutesSummary by CodeRabbit
New Features
Bug Fixes