diff --git a/.distignore b/.distignore index 654ec1e06..6dff08655 100644 --- a/.distignore +++ b/.distignore @@ -9,6 +9,8 @@ Gruntfile.js webpack.config.js tests/ node_modules/ +playwright-report/ +test-results/ none package-lock.json package.json diff --git a/.github/workflows/copilot-review-on-comment.yml b/.github/workflows/copilot-review-on-comment.yml index 742642f96..e1a3accde 100644 --- a/.github/workflows/copilot-review-on-comment.yml +++ b/.github/workflows/copilot-review-on-comment.yml @@ -1,11 +1,13 @@ name: Copilot review on comment on: + pull_request_target: + types: [opened] issue_comment: types: [created] jobs: review: - uses: wpeverest/.github/.github/workflows/copilot-review-on-comment.yml@master + uses: themegrill/.github/.github/workflows/copilot-review-on-comment.yml@master secrets: BOT_TOKEN: ${{ secrets.BOT_TOKEN }} diff --git a/.github/workflows/evf-PR-test.yml b/.github/workflows/evf-PR-test.yml index 5f73fa9bf..4652471a7 100644 --- a/.github/workflows/evf-PR-test.yml +++ b/.github/workflows/evf-PR-test.yml @@ -31,10 +31,16 @@ jobs: git config --global user.email "$MY_EMAIL" git config --global user.name "$MY_USERNAME" - - name: Use Node.js 12.x + # Node 20, not 12: @playwright/test (a devDependency since the E2E suite + # landed) declares `engines.node >= 20`, and package.json now declares the + # same minimum. npm 6 only WARNs on an engine mismatch rather than failing, + # so Node 12 installed fine — but it left CI running a Node the project no + # longer claims to support. 20.x is what .github/workflows/pr-build-zip.yml + # already uses. + - name: Use Node.js 20.x uses: actions/setup-node@v2 with: - node-version: 12.x + node-version: 20.x - name: Setup PHP v7.4 uses: shivammathur/setup-php@v2 diff --git a/.github/workflows/pr-build-zip.yml b/.github/workflows/pr-build-zip.yml new file mode 100644 index 000000000..a37e08c06 --- /dev/null +++ b/.github/workflows/pr-build-zip.yml @@ -0,0 +1,42 @@ +name: Build Testable ZIP + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + branches: [develop] + workflow_dispatch: + +jobs: + zip: + uses: themegrill/.github/.github/workflows/pr-build-zip.yml@master + with: + node-version: '20.x' + php-version: '8.2' + package-manager: npm + # `npm run build` runs this repo's own bin/build-zip.sh, which is a + # fully self-contained release script: it does its own + # `npm install --legacy-peer-deps`, its own `composer install` (with a + # PHP-version fix pending in a separate PR to that script), its own JS + # build, and its own rsync+zip -- producing everest-forms.zip at the + # repo root already. This workflow's own install/composer steps would + # just be redundant, wasted work duplicating what the script already + # does, so they're skipped/no-op'd here rather than fighting it. + # Can't skip this like composer-install: `npm run build` is literally + # `cross-env ./bin/build-zip.sh`, and cross-env has to already be + # resolvable from node_modules/.bin before that command can even + # start -- build-zip.sh's own internal npm install happens too late + # to help with that (confirmed for real: skipping this outright hit + # "cross-env: not found"). --legacy-peer-deps for the same reason as + # documented on the build-zip.sh fix -- @ajna/pagination's peer + # dependency conflict blocks a plain `npm ci` here too. + install-command: npm ci --legacy-peer-deps + composer-install: false + build-command: npm run build + zip-glob: 'everest-forms.zip' + artifacts-bucket: themegrill-pr-artifacts + public-base-url: https://themegrill-pr-artifacts.s3.amazonaws.com + s3-region: us-east-1 + secrets: + BOT_TOKEN: ${{ secrets.BOT_TOKEN }} + ARTIFACTS_KEY: ${{ secrets.ARTIFACTS_KEY }} + ARTIFACTS_SECRET: ${{ secrets.ARTIFACTS_SECRET }} diff --git a/.github/workflows/qa-suite.yml b/.github/workflows/qa-suite.yml new file mode 100644 index 000000000..4efd78cd8 --- /dev/null +++ b/.github/workflows/qa-suite.yml @@ -0,0 +1,39 @@ +# Written by `/claudegrill:setup`. Safe to edit — it is a plain caller. +# +# THIS IS THE ONLY PR CHECK MOST PRODUCTS NEED. No ANTHROPIC_API_KEY, no agent, +# runner minutes only. +# +# It works without AI because the developer already wrote the spec: they ran +# /claudegrill:verify-fix locally, write-spec added a @fresh spec to their +# branch, and they committed it with the fix. By the time CI sees the PR the +# regression is already a deterministic assertion. +# +# ONE job, on pull requests only. Nothing runs on a schedule: the team's model is +# a local /claudegrill:verify-fix while the fix is being written, and the e2e +# suite on the PR. No cron, no nightly, no WordPress-core watcher. +# +# `scope: changed` narrows a run to the areas the diff maps to. That is safe by +# construction — a changed file matching no `area_paths` pattern in +# .themegrill-qa/suite.json falls back to the full tier, so an unmapped change +# costs runner time, never coverage. +# +# Worth knowing, since nothing else runs the suite now: a spec whose area is +# never touched by any PR will not execute. Set `scope: full` below if you would +# rather every PR run the whole @fresh tier. + +name: QA suite + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + workflow_dispatch: + +jobs: + # The only check. Scoped, fast, runs on every PR including drafts. + pr: + uses: ThemeGrill/claudegrill/.github/workflows/suite.yml@main + with: + product_slug: everest-forms + product_type: plugin + scope: changed + diff --git a/.gitignore b/.gitignore index 6c0fc0cfd..00ac87e10 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,10 @@ phpunit-watcher.yml /release/ /.idea/ + +# claudegrill local credentials +.themegrill-qa/.env.local + +# playwright run artefacts +playwright-report/ +test-results/ diff --git a/.themegrill-qa/.docs-cache/_wp-json_wp_v2_doc_category_per_page_100__fields_id_name_slug_count_parent.txt b/.themegrill-qa/.docs-cache/_wp-json_wp_v2_doc_category_per_page_100__fields_id_name_slug_count_parent.txt new file mode 100644 index 000000000..cc9830263 --- /dev/null +++ b/.themegrill-qa/.docs-cache/_wp-json_wp_v2_doc_category_per_page_100__fields_id_name_slug_count_parent.txt @@ -0,0 +1 @@ +[{"id":2,"count":7,"name":"Account Management","slug":"account-management","parent":0},{"id":48,"count":14,"name":"Advanced","slug":"advanced","parent":0},{"id":47,"count":4,"name":"Anti-Spam and Security","slug":"anti-spam-and-security","parent":0},{"id":35,"count":0,"name":"Basic Debugging Steps","slug":"basic-debugging-steps","parent":0},{"id":44,"count":6,"name":"CRMs","slug":"crms","parent":0},{"id":43,"count":2,"name":"Design","slug":"design","parent":0},{"id":26,"count":4,"name":"Developer's Doc","slug":"developers-doc","parent":0},{"id":3,"count":0,"name":"Everest Forms Add-ons","slug":"everest-forms-add-ons","parent":0},{"id":4,"count":10,"name":"Everest Forms Pro","slug":"everest-forms-pro","parent":0},{"id":56,"count":6,"name":"Form Customization and User Experience","slug":"form-customization-and-user-experience","parent":0},{"id":5,"count":19,"name":"Form Fields","slug":"form-fields","parent":0},{"id":17,"count":13,"name":"Frequently Asked Questions","slug":"faq","parent":0},{"id":6,"count":6,"name":"Getting Started with Form","slug":"getting-started-with-form","parent":0},{"id":7,"count":4,"name":"Getting Started with Plugin","slug":"getting-started","parent":0},{"id":8,"count":4,"name":"Global Settings","slug":"global-settings","parent":0},{"id":9,"count":43,"name":"How To?","slug":"tutorials","parent":0},{"id":10,"count":6,"name":"Individual Form Settings","slug":"individual-form-settings","parent":0},{"id":57,"count":5,"name":"Integrations","slug":"integrations","parent":0},{"id":51,"count":17,"name":"Marketing","slug":"marketing","parent":0},{"id":61,"count":7,"name":"New Payment Gateways","slug":"new-payment-gateways","parent":0},{"id":42,"count":5,"name":"Page Builder Compatibility","slug":"page-builder-compatibility","parent":0},{"id":45,"count":6,"name":"Payment Gateways ( Old )","slug":"payment-gateways","parent":0},{"id":59,"count":3,"name":"Tools","slug":"tools","parent":0},{"id":11,"count":2,"name":"Translation","slug":"translation","parent":0},{"id":12,"count":6,"name":"Troubleshooting","slug":"troubleshooting","parent":0}] \ No newline at end of file diff --git a/.themegrill-qa/.docs-cache/_wp-json_wp_v2_docs_per_page_100_page_1__fields_id_slug_link_title_content_doc_category.txt b/.themegrill-qa/.docs-cache/_wp-json_wp_v2_docs_per_page_100_page_1__fields_id_slug_link_title_content_doc_category.txt new file mode 100644 index 000000000..12fb74cd5 --- /dev/null +++ b/.themegrill-qa/.docs-cache/_wp-json_wp_v2_docs_per_page_100_page_1__fields_id_slug_link_title_content_doc_category.txt @@ -0,0 +1 @@ +[{"id":5955,"slug":"style-customizer","link":"https:\/\/docs.everestforms.net\/docs\/style-customizer\/","title":{"rendered":"Style Customizer"},"content":{"rendered":"
The Style Customizer lets you change how your form looks \u2014 colors, fonts, spacing, borders, and button style \u2014 without writing any CSS. It’s built directly into the form builder’s Style<\/strong> tab, with a live preview that updates as you make changes.<\/p>\n This article covers the current Style Customizer. If you styled a form before this update, don’t worry \u2014 your existing look carries over automatically the first time you open the Style tab. See Migrating an Older Form<\/strong> below.<\/p>\n The Style tab is split into two panes:<\/p>\n Note:<\/strong> Nothing is saved until you click Save<\/strong> in the top-right corner. Switching to another tab (e.g. Fields) while you have unsaved style changes will ask you to confirm before leaving.<\/p><\/blockquote>\n At the top of the Design list, click Colors<\/strong> to open the palette screen. It has two parts:<\/p>\n Note (Free plan):<\/strong> Two presets \u2014 Classic<\/strong> and Monochrome<\/strong> \u2014 are available on the Free plan. All other presets shown are Pro; selecting one will prompt you to upgrade. Editing Your Palette’s colors directly is also a Pro feature. See Free vs Pro below.<\/p><\/blockquote>\n If this form was styled before this update:<\/strong> whatever custom palette it used to have shows up right at the front of the Presets grid, marked with a purple Custom<\/strong> badge \u2014 it isn’t hidden or lost. Click it to keep using it exactly as before. If you no longer need it, Pro plans can remove it with the delete icon on the card. What you can’t<\/em> do anymore is rename it or edit its colors in place \u2014 that “create\/edit a saved palette” workflow has been retired. To move it forward instead: apply it (or it may already be applied, showing as your current Your Palette), then use the Your Palette<\/strong> editor above (Pro) to adjust any of its six colors directly \u2014 you’re editing your form’s live colors at that point, not the old saved entry, so there’s nothing to “fix” beyond that.<\/p>\n Below Pre-defined, click any of the six elements to open its settings:<\/p>\n Background color and image, corner rounding, overall width, and the form’s font family.<\/p>\n Typography (size, weight, color, style) for Label<\/strong>, Sublabel<\/strong>, Description<\/strong>, and Section Title<\/strong> text \u2014 switch between them using the tabs at the top of the panel.<\/p>\n Styling for text boxes, dropdowns, textareas, date pickers, and the file upload area, with separate Normal<\/strong> and Focus<\/strong> states.<\/p>\n One shared style for every “pick a choice” field \u2014 radio buttons, checkboxes, Yes\/No, image choices, star\/scale ratings, Likert rows, and payment pickers (including the Subscription Plan card). Includes:<\/p>\n Styling for the Submit button (and Multi-Part navigation\/upload buttons, which follow it), with separate Normal<\/strong> and Hover<\/strong> states.<\/p>\n Styling for the success, error, and validation messages shown to visitors after they submit the form. (Pro)<\/em><\/p>\n Instead of hunting through the panels, click directly on any part of the form in the live preview \u2014 a label, a button, an input, a choice field \u2014 and the Design panel automatically navigates to that element’s specific settings, with the element itself outlined in the preview so you always know what you’re editing.<\/p>\n Tip:<\/strong> Hover over an element in the preview first; it highlights so you know exactly what you’re about to click before you commit.<\/p><\/blockquote>\n Toggle Apply Theme Style<\/strong> (below Pre-defined) to let your active WordPress theme style the form instead of Everest Forms’ own default look. Your color, spacing, and font choices above still apply on top of either.<\/p>\n Click Template<\/strong> at the top of the Design list to browse ready-made looks and apply one in a single click. It has the same two-part layout as Colors:<\/p>\n Note:<\/strong> Applying a template replaces your current colors, fonts, and spacing with the template’s own \u2014 it’s a starting point you can still fine-tune afterward.<\/p><\/blockquote>\n If this form was styled before this update:<\/strong> any custom template you’d saved for it shows up first in the Presets grid, marked Custom<\/strong> \u2014 same treatment as a custom palette (see above). Click it to reapply, or Pro plans can delete it with the card’s delete icon. It can no longer be renamed or edited as a saved entry \u2014 to build on it, apply it and then adjust the result with the Design Elements panels (Form, Text, Inputs, Choices, Button, Messages) below; those changes apply to your form directly and show up live in Your Template above.<\/p>\n Click Custom CSS<\/strong> under Advanced to write your own CSS. This is applied site-wide \u2014 the same Additional CSS used across every form on your site, not just this one \u2014 so a rule you add here will show up wherever it applies, on any form.<\/p>\nWhere to Find It<\/h2>\n
\n
<\/figure>\n
<\/figure>\nThe Style Tab Layout<\/h2>\n
\n
<\/figure>\nColor Palette<\/h2>\n
\n
<\/figure>\nDesign Elements<\/h2>\n
Form<\/h3>\n
Text<\/h3>\n
Inputs<\/h3>\n
Choices<\/h3>\n
\n
Button<\/h3>\n
Messages<\/h3>\n
Click-to-Edit in the Live Preview<\/h2>\n
<\/figure>\nApply Theme Style<\/h2>\n
Undo, Redo, and Reset<\/h2>\n
\n
Templates<\/h2>\n
\n
<\/figure>\nCustom CSS<\/h2>\n
<\/figure>\nFree vs Pro<\/h2>\n