From cc412fb075b32cb0eb5edbc30390ecb7f96c3db9 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Wed, 24 Dec 2025 14:42:24 +0000 Subject: [PATCH 01/19] Blocks: Use apiVersion 3 --- includes/blocks/broadcasts/block.json | 2 +- .../blocks/form-builder-field-custom/block.json | 2 +- includes/blocks/form-builder-field-email/block.json | 2 +- includes/blocks/form-builder-field-name/block.json | 2 +- includes/blocks/form-builder/block.json | 2 +- includes/blocks/form/block.json | 2 +- includes/blocks/formtrigger/block.json | 2 +- includes/blocks/product/block.json | 2 +- tests/EndToEnd.suite.yml | 1 - .../forms/blocks-shortcodes/PageBlockFormCest.php | 2 ++ tests/Support/Helper/WPGutenberg.php | 13 ++++++++----- tests/Support/Helper/WPMetabox.php | 8 +++++++- 12 files changed, 25 insertions(+), 15 deletions(-) diff --git a/includes/blocks/broadcasts/block.json b/includes/blocks/broadcasts/block.json index 966fdea87..650a77901 100644 --- a/includes/blocks/broadcasts/block.json +++ b/includes/blocks/broadcasts/block.json @@ -1,6 +1,6 @@ { "$schema": "https://schemas.wp.org/trunk/block.json", - "apiVersion": 2, + "apiVersion": 3, "name": "convertkit/broadcasts", "title": "Kit Broadcasts", "category": "kit", diff --git a/includes/blocks/form-builder-field-custom/block.json b/includes/blocks/form-builder-field-custom/block.json index 17e329ccd..a5ab5b7fe 100644 --- a/includes/blocks/form-builder-field-custom/block.json +++ b/includes/blocks/form-builder-field-custom/block.json @@ -1,6 +1,6 @@ { "$schema": "https://schemas.wp.org/trunk/block.json", - "apiVersion": 2, + "apiVersion": 3, "name": "convertkit/form-builder-field-custom", "title": "Kit Form Builder: Custom Field", "category": "kit", diff --git a/includes/blocks/form-builder-field-email/block.json b/includes/blocks/form-builder-field-email/block.json index 837c06cb3..209e6e373 100644 --- a/includes/blocks/form-builder-field-email/block.json +++ b/includes/blocks/form-builder-field-email/block.json @@ -1,6 +1,6 @@ { "$schema": "https://schemas.wp.org/trunk/block.json", - "apiVersion": 2, + "apiVersion": 3, "name": "convertkit/form-builder-field-email", "title": "Kit Form Builder: Email Field", "category": "kit", diff --git a/includes/blocks/form-builder-field-name/block.json b/includes/blocks/form-builder-field-name/block.json index 8e3d5f212..b8a6a1b01 100644 --- a/includes/blocks/form-builder-field-name/block.json +++ b/includes/blocks/form-builder-field-name/block.json @@ -1,6 +1,6 @@ { "$schema": "https://schemas.wp.org/trunk/block.json", - "apiVersion": 2, + "apiVersion": 3, "name": "convertkit/form-builder-field-name", "title": "Kit Form Builder: Name Field", "category": "kit", diff --git a/includes/blocks/form-builder/block.json b/includes/blocks/form-builder/block.json index 204b305b9..edacd8a45 100644 --- a/includes/blocks/form-builder/block.json +++ b/includes/blocks/form-builder/block.json @@ -1,6 +1,6 @@ { "$schema": "https://schemas.wp.org/trunk/block.json", - "apiVersion": 2, + "apiVersion": 3, "name": "convertkit/form-builder", "title": "Kit Form Builder", "category": "kit", diff --git a/includes/blocks/form/block.json b/includes/blocks/form/block.json index 8b677bb10..35c9727c9 100644 --- a/includes/blocks/form/block.json +++ b/includes/blocks/form/block.json @@ -1,6 +1,6 @@ { "$schema": "https://schemas.wp.org/trunk/block.json", - "apiVersion": 2, + "apiVersion": 3, "name": "convertkit/form", "title": "Kit Form", "category": "kit", diff --git a/includes/blocks/formtrigger/block.json b/includes/blocks/formtrigger/block.json index fa7158caa..b9ea5e4a2 100644 --- a/includes/blocks/formtrigger/block.json +++ b/includes/blocks/formtrigger/block.json @@ -1,6 +1,6 @@ { "$schema": "https://schemas.wp.org/trunk/block.json", - "apiVersion": 2, + "apiVersion": 3, "name": "convertkit/formtrigger", "title": "Kit Form Trigger", "category": "kit", diff --git a/includes/blocks/product/block.json b/includes/blocks/product/block.json index cdf8e35e9..27fc0d9e5 100644 --- a/includes/blocks/product/block.json +++ b/includes/blocks/product/block.json @@ -1,6 +1,6 @@ { "$schema": "https://schemas.wp.org/trunk/block.json", - "apiVersion": 2, + "apiVersion": 3, "name": "convertkit/product", "title": "Kit Product", "category": "kit", diff --git a/tests/EndToEnd.suite.yml b/tests/EndToEnd.suite.yml index 9bc855a5a..a485010f1 100644 --- a/tests/EndToEnd.suite.yml +++ b/tests/EndToEnd.suite.yml @@ -55,7 +55,6 @@ modules: capabilities: "goog:chromeOptions": args: - - "--headless" - "--disable-gpu" - "--disable-dev-shm-usage" - "--disable-software-rasterizer" diff --git a/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormCest.php b/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormCest.php index 1940355cb..8066b839e 100644 --- a/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormCest.php +++ b/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormCest.php @@ -42,6 +42,8 @@ public function testFormBlockWithValidFormParameter(EndToEndTester $I) title: 'Kit: Page: Form: Block: Valid Form Param' ); + // @TODO. + // Configure metabox's Form setting = None, ensuring we only test the block in Gutenberg. $I->configureMetaboxSettings( $I, diff --git a/tests/Support/Helper/WPGutenberg.php b/tests/Support/Helper/WPGutenberg.php index fd5781988..3c60987f3 100644 --- a/tests/Support/Helper/WPGutenberg.php +++ b/tests/Support/Helper/WPGutenberg.php @@ -10,11 +10,8 @@ class WPGutenberg extends \Codeception\Module { /** - * Helper method to switch to the Gutenberg editor Iframe. - * Use this method if all blocks use the Block API v3, - * as this means Gutenberg will be served in an Iframe. - * At present, we use v2 to provide backwards compatibility - * down to WordPress 5.6: + * Helper method to switch to the Gutenberg editor Iframe + * when all blocks use the Block API v3: * https://developer.wordpress.org/block-editor/reference-guides/block-api/block-api-versions/ * * @since 2.7.7 @@ -41,8 +38,14 @@ public function addGutenbergPage($I, $postType = 'page', $title = 'Gutenberg Tit $I->amOnAdminPage('post-new.php?post_type=' . $postType); $I->waitForElementVisible('body.post-new-php'); + // Switch to the Gutenberg IFrame. + $I->switchToGutenbergEditor($I); + // Define the Title. $I->fillField('.editor-post-title__input', $title); + + // Switch back to main window. + $I->switchToIFrame(); } /** diff --git a/tests/Support/Helper/WPMetabox.php b/tests/Support/Helper/WPMetabox.php index 22269da2c..958b4d4f3 100644 --- a/tests/Support/Helper/WPMetabox.php +++ b/tests/Support/Helper/WPMetabox.php @@ -20,8 +20,11 @@ class WPMetabox extends \Codeception\Module */ public function configureMetaboxSettings($I, $metabox, $configuration) { + // Expand the Meta Boxes panel. + $I->click('Meta Boxes', '.edit-post-meta-boxes-main'); + // Check that the metabox exists. - $I->seeElementInDOM('#' . $metabox); + $I->waitForElementVisible('#' . $metabox); // Apply configuration. foreach ($configuration as $field => $attributes) { @@ -44,5 +47,8 @@ public function configureMetaboxSettings($I, $metabox, $configuration) break; } } + + // Collapse the Meta Boxes panel. + $I->click('Meta Boxes', '.edit-post-meta-boxes-main'); } } From c6bb07f3a4c9b04160bf26eee65bac68968c0b74 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Mon, 5 Jan 2026 16:36:09 +0800 Subject: [PATCH 02/19] Register v3 or v2 blocks --- includes/blocks/v2/broadcasts/block.json | 75 +++++++++++++++++++ .../v2/form-builder-field-custom/block.json | 57 ++++++++++++++ .../v2/form-builder-field-email/block.json | 54 +++++++++++++ .../v2/form-builder-field-name/block.json | 54 +++++++++++++ includes/blocks/v2/form-builder/block.json | 72 ++++++++++++++++++ includes/blocks/v2/form/block.json | 39 ++++++++++ includes/blocks/v2/formtrigger/block.json | 50 +++++++++++++ includes/blocks/v2/product/block.json | 50 +++++++++++++ .../blocks/{ => v3}/broadcasts/block.json | 0 .../form-builder-field-custom/block.json | 0 .../form-builder-field-email/block.json | 0 .../form-builder-field-name/block.json | 0 .../blocks/{ => v3}/form-builder/block.json | 0 includes/blocks/{ => v3}/form/block.json | 0 .../blocks/{ => v3}/formtrigger/block.json | 0 includes/blocks/{ => v3}/product/block.json | 0 includes/class-convertkit-gutenberg.php | 17 ++++- 17 files changed, 467 insertions(+), 1 deletion(-) create mode 100644 includes/blocks/v2/broadcasts/block.json create mode 100644 includes/blocks/v2/form-builder-field-custom/block.json create mode 100644 includes/blocks/v2/form-builder-field-email/block.json create mode 100644 includes/blocks/v2/form-builder-field-name/block.json create mode 100644 includes/blocks/v2/form-builder/block.json create mode 100644 includes/blocks/v2/form/block.json create mode 100644 includes/blocks/v2/formtrigger/block.json create mode 100644 includes/blocks/v2/product/block.json rename includes/blocks/{ => v3}/broadcasts/block.json (100%) rename includes/blocks/{ => v3}/form-builder-field-custom/block.json (100%) rename includes/blocks/{ => v3}/form-builder-field-email/block.json (100%) rename includes/blocks/{ => v3}/form-builder-field-name/block.json (100%) rename includes/blocks/{ => v3}/form-builder/block.json (100%) rename includes/blocks/{ => v3}/form/block.json (100%) rename includes/blocks/{ => v3}/formtrigger/block.json (100%) rename includes/blocks/{ => v3}/product/block.json (100%) diff --git a/includes/blocks/v2/broadcasts/block.json b/includes/blocks/v2/broadcasts/block.json new file mode 100644 index 000000000..966fdea87 --- /dev/null +++ b/includes/blocks/v2/broadcasts/block.json @@ -0,0 +1,75 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 2, + "name": "convertkit/broadcasts", + "title": "Kit Broadcasts", + "category": "kit", + "description": "Displays a list of your Kit broadcasts.", + "keywords": [ "convertkit", "kit", "broadcasts", "posts" ], + "textdomain": "convertkit", + "attributes": { + "display_grid": { + "type": "boolean" + }, + "date_format": { + "type": "string" + }, + "display_image": { + "type": "boolean" + }, + "display_description": { + "type": "boolean" + }, + "display_read_more": { + "type": "boolean" + }, + "read_more_label": { + "type": "string" + }, + "limit": { + "type": "number" + }, + "page": { + "type": "number" + }, + "paginate": { + "type": "boolean" + }, + "paginate_label_prev": { + "type": "string" + }, + "paginate_label_next": { + "type": "string" + }, + "style": { + "type": "object" + }, + "backgroundColor": { + "type": "string" + }, + "textColor": { + "type": "string" + }, + "is_gutenberg_example": { + "type": "boolean", + "default": false + } + }, + "supports": { + "className": true, + "color": { + "link": true, + "background": true, + "text": true + }, + "typography": { + "fontSize": true, + "lineHeight": true + }, + "spacing": { + "margin": true, + "padding": true + } + }, + "editorScript": "convertkit-gutenberg" +} \ No newline at end of file diff --git a/includes/blocks/v2/form-builder-field-custom/block.json b/includes/blocks/v2/form-builder-field-custom/block.json new file mode 100644 index 000000000..17e329ccd --- /dev/null +++ b/includes/blocks/v2/form-builder-field-custom/block.json @@ -0,0 +1,57 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 2, + "name": "convertkit/form-builder-field-custom", + "title": "Kit Form Builder: Custom Field", + "category": "kit", + "description": "Adds a text field to the Kit Form Builder, whose value is stored in a Kit custom field.", + "keywords": [ + "convertkit", + "kit", + "custom", + "field" + ], + "textdomain": "convertkit", + "parent": [ "convertkit/form-builder" ], + "attributes": { + "label": { + "type": "string" + }, + "custom_field": { + "type": "string" + }, + "fontSize": { + "type": "string" + }, + "style": { + "type": "object" + }, + "backgroundColor": { + "type": "string" + }, + "textColor": { + "type": "string" + }, + "is_gutenberg_example": { + "type": "boolean", + "default": false + } + }, + "supports": { + "align": true, + "className": true, + "color": { + "background": true, + "text": true + }, + "typography": { + "fontSize": true, + "lineHeight": true + }, + "spacing": { + "margin": true, + "padding": true + } + }, + "editorScript": "convertkit-gutenberg" +} \ No newline at end of file diff --git a/includes/blocks/v2/form-builder-field-email/block.json b/includes/blocks/v2/form-builder-field-email/block.json new file mode 100644 index 000000000..837c06cb3 --- /dev/null +++ b/includes/blocks/v2/form-builder-field-email/block.json @@ -0,0 +1,54 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 2, + "name": "convertkit/form-builder-field-email", + "title": "Kit Form Builder: Email Field", + "category": "kit", + "description": "Adds an email field to the Kit Form Builder.", + "keywords": [ + "convertkit", + "kit", + "email", + "field" + ], + "textdomain": "convertkit", + "parent": [ "convertkit/form-builder" ], + "attributes": { + "label": { + "type": "string" + }, + "fontSize": { + "type": "string" + }, + "style": { + "type": "object" + }, + "backgroundColor": { + "type": "string" + }, + "textColor": { + "type": "string" + }, + "is_gutenberg_example": { + "type": "boolean", + "default": false + } + }, + "supports": { + "align": true, + "className": true, + "color": { + "background": true, + "text": true + }, + "typography": { + "fontSize": true, + "lineHeight": true + }, + "spacing": { + "margin": true, + "padding": true + } + }, + "editorScript": "convertkit-gutenberg" +} \ No newline at end of file diff --git a/includes/blocks/v2/form-builder-field-name/block.json b/includes/blocks/v2/form-builder-field-name/block.json new file mode 100644 index 000000000..8e3d5f212 --- /dev/null +++ b/includes/blocks/v2/form-builder-field-name/block.json @@ -0,0 +1,54 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 2, + "name": "convertkit/form-builder-field-name", + "title": "Kit Form Builder: Name Field", + "category": "kit", + "description": "Adds a name field to the Kit Form Builder.", + "keywords": [ + "convertkit", + "kit", + "name", + "field" + ], + "textdomain": "convertkit", + "parent": [ "convertkit/form-builder" ], + "attributes": { + "label": { + "type": "string" + }, + "fontSize": { + "type": "string" + }, + "style": { + "type": "object" + }, + "backgroundColor": { + "type": "string" + }, + "textColor": { + "type": "string" + }, + "is_gutenberg_example": { + "type": "boolean", + "default": false + } + }, + "supports": { + "align": true, + "className": true, + "color": { + "background": true, + "text": true + }, + "typography": { + "fontSize": true, + "lineHeight": true + }, + "spacing": { + "margin": true, + "padding": true + } + }, + "editorScript": "convertkit-gutenberg" +} \ No newline at end of file diff --git a/includes/blocks/v2/form-builder/block.json b/includes/blocks/v2/form-builder/block.json new file mode 100644 index 000000000..204b305b9 --- /dev/null +++ b/includes/blocks/v2/form-builder/block.json @@ -0,0 +1,72 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 2, + "name": "convertkit/form-builder", + "title": "Kit Form Builder", + "category": "kit", + "description": "Build a subscription form that inherits your site's styles.", + "keywords": [ + "form", + "embed", + "subscriber", + "email", + "convertkit" + ], + "textdomain": "convertkit", + "attributes": { + "redirect": { + "type": "string" + }, + "store_entries": { + "type": "boolean" + }, + "display_form_if_subscribed": { + "type": "boolean" + }, + "text_if_subscribed": { + "type": "string" + }, + "form_id": { + "type": "string" + }, + "tag_id": { + "type": "string" + }, + "sequence_id": { + "type": "string" + }, + "fontSize": { + "type": "string" + }, + "style": { + "type": "object" + }, + "backgroundColor": { + "type": "string" + }, + "textColor": { + "type": "string" + }, + "is_gutenberg_example": { + "type": "boolean", + "default": false + } + }, + "supports": { + "align": true, + "className": true, + "color": { + "background": true, + "text": true + }, + "typography": { + "fontSize": true, + "lineHeight": true + }, + "spacing": { + "margin": true, + "padding": true + } + }, + "editorScript": "convertkit-gutenberg" +} \ No newline at end of file diff --git a/includes/blocks/v2/form/block.json b/includes/blocks/v2/form/block.json new file mode 100644 index 000000000..8b677bb10 --- /dev/null +++ b/includes/blocks/v2/form/block.json @@ -0,0 +1,39 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 2, + "name": "convertkit/form", + "title": "Kit Form", + "category": "kit", + "description": "Displays a Kit Form.", + "keywords": [ + "form", + "embed", + "subscriber", + "email", + "convertkit" + ], + "textdomain": "convertkit", + "attributes": { + "form": { + "type": "string" + }, + "is_gutenberg_example": { + "type": "boolean", + "default": false + } + }, + "supports": { + "align": true, + "className": true, + "color": { + "link": false, + "background": true, + "text": false + }, + "spacing": { + "margin": true, + "padding": true + } + }, + "editorScript": "convertkit-gutenberg" +} \ No newline at end of file diff --git a/includes/blocks/v2/formtrigger/block.json b/includes/blocks/v2/formtrigger/block.json new file mode 100644 index 000000000..fa7158caa --- /dev/null +++ b/includes/blocks/v2/formtrigger/block.json @@ -0,0 +1,50 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 2, + "name": "convertkit/formtrigger", + "title": "Kit Form Trigger", + "category": "kit", + "description": "Displays a modal, sticky bar or slide in form to display when the button is pressed.", + "keywords": [ "convertkit", "kit", "form" ], + "textdomain": "convertkit", + "attributes": { + "form": { + "type": "string" + }, + "text": { + "type": "string" + }, + "fontSize": { + "type": "string" + }, + "style": { + "type": "object" + }, + "backgroundColor": { + "type": "string" + }, + "textColor": { + "type": "string" + }, + "is_gutenberg_example": { + "type": "boolean", + "default": false + } + }, + "supports": { + "className": true, + "color": { + "background": true, + "text": true + }, + "typography": { + "fontSize": true, + "lineHeight": true + }, + "spacing": { + "margin": true, + "padding": true + } + }, + "editorScript": "convertkit-gutenberg" +} \ No newline at end of file diff --git a/includes/blocks/v2/product/block.json b/includes/blocks/v2/product/block.json new file mode 100644 index 000000000..cdf8e35e9 --- /dev/null +++ b/includes/blocks/v2/product/block.json @@ -0,0 +1,50 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 2, + "name": "convertkit/product", + "title": "Kit Product", + "category": "kit", + "description": "Displays a button to purchase a Kit product.", + "keywords": [ "convertkit", "kit", "product" ], + "textdomain": "convertkit", + "attributes": { + "product": { + "type": "string" + }, + "text": { + "type": "string" + }, + "fontSize": { + "type": "string" + }, + "style": { + "type": "object" + }, + "backgroundColor": { + "type": "string" + }, + "textColor": { + "type": "string" + }, + "is_gutenberg_example": { + "type": "boolean", + "default": false + } + }, + "supports": { + "className": true, + "color": { + "background": true, + "text": true + }, + "typography": { + "fontSize": true, + "lineHeight": true + }, + "spacing": { + "margin": true, + "padding": true + } + }, + "editorScript": "convertkit-gutenberg" +} \ No newline at end of file diff --git a/includes/blocks/broadcasts/block.json b/includes/blocks/v3/broadcasts/block.json similarity index 100% rename from includes/blocks/broadcasts/block.json rename to includes/blocks/v3/broadcasts/block.json diff --git a/includes/blocks/form-builder-field-custom/block.json b/includes/blocks/v3/form-builder-field-custom/block.json similarity index 100% rename from includes/blocks/form-builder-field-custom/block.json rename to includes/blocks/v3/form-builder-field-custom/block.json diff --git a/includes/blocks/form-builder-field-email/block.json b/includes/blocks/v3/form-builder-field-email/block.json similarity index 100% rename from includes/blocks/form-builder-field-email/block.json rename to includes/blocks/v3/form-builder-field-email/block.json diff --git a/includes/blocks/form-builder-field-name/block.json b/includes/blocks/v3/form-builder-field-name/block.json similarity index 100% rename from includes/blocks/form-builder-field-name/block.json rename to includes/blocks/v3/form-builder-field-name/block.json diff --git a/includes/blocks/form-builder/block.json b/includes/blocks/v3/form-builder/block.json similarity index 100% rename from includes/blocks/form-builder/block.json rename to includes/blocks/v3/form-builder/block.json diff --git a/includes/blocks/form/block.json b/includes/blocks/v3/form/block.json similarity index 100% rename from includes/blocks/form/block.json rename to includes/blocks/v3/form/block.json diff --git a/includes/blocks/formtrigger/block.json b/includes/blocks/v3/formtrigger/block.json similarity index 100% rename from includes/blocks/formtrigger/block.json rename to includes/blocks/v3/formtrigger/block.json diff --git a/includes/blocks/product/block.json b/includes/blocks/v3/product/block.json similarity index 100% rename from includes/blocks/product/block.json rename to includes/blocks/v3/product/block.json diff --git a/includes/class-convertkit-gutenberg.php b/includes/class-convertkit-gutenberg.php index 4c8fc5d4b..3d7059af5 100644 --- a/includes/class-convertkit-gutenberg.php +++ b/includes/class-convertkit-gutenberg.php @@ -147,6 +147,21 @@ public function add_blocks() { return; } + // Determine the block API version to use for registering blocks. + // WordPress supports Version 3 from WordPress 6.3: + // https://developer.wordpress.org/block-editor/reference-guides/block-api/block-api-versions/. + $block_api_version = ( version_compare( get_bloginfo( 'version' ), '6.3', '>=' ) ? 3 : 2 ); + + /** + * Determine the block API version to use for registering blocks. + * + * @since 3.1.4 + * + * @param int $block_api_version Block API version. + * @return int Block API version. + */ + $block_api_version = apply_filters( 'convertkit_gutenberg_block_api_version', $block_api_version ); + // Get registered blocks. $registered_blocks = array_keys( WP_Block_Type_Registry::get_instance()->get_all_registered() ); @@ -160,7 +175,7 @@ public function add_blocks() { // Register block. register_block_type( - CONVERTKIT_PLUGIN_PATH . '/includes/blocks/' . $block, + CONVERTKIT_PLUGIN_PATH . '/includes/blocks/v' . (string) $block_api_version . '/' . $block, array( 'attributes' => $properties['attributes'], 'editor_script' => 'convertkit-gutenberg', From f93e142cfb7ee85f8f52770e7f9d5e9cce7e264d Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Mon, 5 Jan 2026 17:03:46 +0800 Subject: [PATCH 03/19] Fix tests --- .../forms/blocks-shortcodes/PageBlockFormCest.php | 2 -- tests/Support/Data/dump.sql | 2 +- tests/Support/Helper/WPMetabox.php | 8 +------- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormCest.php b/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormCest.php index 8066b839e..1940355cb 100644 --- a/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormCest.php +++ b/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormCest.php @@ -42,8 +42,6 @@ public function testFormBlockWithValidFormParameter(EndToEndTester $I) title: 'Kit: Page: Form: Block: Valid Form Param' ); - // @TODO. - // Configure metabox's Form setting = None, ensuring we only test the block in Gutenberg. $I->configureMetaboxSettings( $I, diff --git a/tests/Support/Data/dump.sql b/tests/Support/Data/dump.sql index e3ec007bf..f8c6cba2b 100644 --- a/tests/Support/Data/dump.sql +++ b/tests/Support/Data/dump.sql @@ -372,7 +372,7 @@ INSERT INTO `wp_usermeta` (`umeta_id`, `user_id`, `meta_key`, `meta_value`) VALU (19, 1, 'wp_dashboard_quick_press_last_post_id', '1'), (20, 1, 'edit_page_per_page', '100'), (21, 1, 'edit_post_per_page', '100'), -(22, 1, 'wp_persisted_preferences', 'a:4:{s:4:"core";a:1:{s:26:"isComplementaryAreaVisible";b:1;}s:14:"core/edit-post";a:1:{s:12:"welcomeGuide";b:0;}s:9:"_modified";s:24:"2024-07-18T02:45:41.491Z";s:17:"core/edit-widgets";a:2:{s:26:"isComplementaryAreaVisible";b:1;s:12:"welcomeGuide";b:0;}}'); +(22, 1, 'wp_persisted_preferences', 'a:4:{s:4:"core";a:2:{s:26:"isComplementaryAreaVisible";b:1;s:24:"enableChoosePatternModal";b:0;}s:14:"core/edit-post";a:4:{s:12:"welcomeGuide";b:0;s:23:"metaBoxesMainOpenHeight";i:540;s:20:"welcomeGuideTemplate";b:0;s:19:"metaBoxesMainIsOpen";b:1;}s:9:"_modified";s:24:"2024-07-18T02:45:41.491Z";s:17:"core/edit-widgets";a:2:{s:26:"isComplementaryAreaVisible";b:1;s:12:"welcomeGuide";b:0;}}'); DROP TABLE IF EXISTS `wp_users`; CREATE TABLE `wp_users` ( diff --git a/tests/Support/Helper/WPMetabox.php b/tests/Support/Helper/WPMetabox.php index 958b4d4f3..22269da2c 100644 --- a/tests/Support/Helper/WPMetabox.php +++ b/tests/Support/Helper/WPMetabox.php @@ -20,11 +20,8 @@ class WPMetabox extends \Codeception\Module */ public function configureMetaboxSettings($I, $metabox, $configuration) { - // Expand the Meta Boxes panel. - $I->click('Meta Boxes', '.edit-post-meta-boxes-main'); - // Check that the metabox exists. - $I->waitForElementVisible('#' . $metabox); + $I->seeElementInDOM('#' . $metabox); // Apply configuration. foreach ($configuration as $field => $attributes) { @@ -47,8 +44,5 @@ public function configureMetaboxSettings($I, $metabox, $configuration) break; } } - - // Collapse the Meta Boxes panel. - $I->click('Meta Boxes', '.edit-post-meta-boxes-main'); } } From 7c94c4a962b1db8daebdea01d73a15de06f5cd38 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Mon, 5 Jan 2026 17:18:24 +0800 Subject: [PATCH 04/19] Tests: Form Block IFrame: Switch to Gutenberg Editor --- tests/Support/Helper/KitPlugin.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/Support/Helper/KitPlugin.php b/tests/Support/Helper/KitPlugin.php index d3c00c168..794ebbe66 100644 --- a/tests/Support/Helper/KitPlugin.php +++ b/tests/Support/Helper/KitPlugin.php @@ -888,6 +888,8 @@ public function clickLinkInBlockAndAssertKitLoginScreen($I, $linkText) */ public function seeFormBlockIFrameHasMessage($I, $message) { + $I->switchToGutenbergEditor($I); // Required for apiVersion 3 blocks. + // Switch to iframe preview for the Form block. $I->switchToIFrame('iframe[class="components-sandbox"]'); From 082a01532633c67788cc729b68cdf4d2f5f339d2 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Mon, 5 Jan 2026 17:19:12 +0800 Subject: [PATCH 05/19] Tests: Restore headless mode --- tests/EndToEnd.suite.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/EndToEnd.suite.yml b/tests/EndToEnd.suite.yml index a485010f1..9bc855a5a 100644 --- a/tests/EndToEnd.suite.yml +++ b/tests/EndToEnd.suite.yml @@ -55,6 +55,7 @@ modules: capabilities: "goog:chromeOptions": args: + - "--headless" - "--disable-gpu" - "--disable-dev-shm-usage" - "--disable-software-rasterizer" From b9050b888aad0d5807f4cbf6eb9f751cc08897fd Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Mon, 5 Jan 2026 17:34:23 +0800 Subject: [PATCH 06/19] Tests: Switch to iframe editor in more helpers --- tests/Support/Helper/KitPlugin.php | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/tests/Support/Helper/KitPlugin.php b/tests/Support/Helper/KitPlugin.php index 794ebbe66..8e98daf20 100644 --- a/tests/Support/Helper/KitPlugin.php +++ b/tests/Support/Helper/KitPlugin.php @@ -780,6 +780,9 @@ public function testBlockNoCredentialsPopupWindow($I, $blockName, $expectedMessa // Confirm that the Form block displays instructions to the user on how to enter their API Key. $I->seeBlockHasNoContentMessage($I, 'Not connected to Kit.'); + // Switch to the Gutenberg IFrame. + $I->switchToGutenbergEditor($I); + // Click the link to confirm it loads the Plugin's setup wizard. $I->click( 'Click here to connect your Kit account.', @@ -807,6 +810,9 @@ public function testBlockNoCredentialsPopupWindow($I, $blockName, $expectedMessa // and that resources now exist. $I->waitForElementNotVisible('div.convertkit-no-content button.wp-convertkit-refresh-resources', 30); + // Switch back to main window. + $I->switchToIFrame(); + // Confirm that the block displays the expected message. if ($expectedMessage) { $I->seeBlockHasNoContentMessage($I, $expectedMessage); @@ -822,11 +828,17 @@ public function testBlockNoCredentialsPopupWindow($I, $blockName, $expectedMessa */ public function clickBlockRefreshButton($I) { + // Switch to the Gutenberg IFrame. + $I->switchToGutenbergEditor($I); + // Click the refresh button. $I->click('div.convertkit-no-content button.wp-convertkit-refresh-resources'); // Wait for the refresh button to disappear, confirming that credentials and resources now exist. $I->waitForElementNotVisible('div.convertkit-no-content button.wp-convertkit-refresh-resources'); + + // Switch back to main window. + $I->switchToIFrame(); } /** @@ -839,6 +851,9 @@ public function clickBlockRefreshButton($I) */ public function seeBlockHasNoContentMessage($I, $message) { + // Switch to the Gutenberg IFrame. + $I->switchToGutenbergEditor($I); + $I->see( $message, [ @@ -861,6 +876,9 @@ public function seeBlockHasNoContentMessage($I, $message) */ public function clickLinkInBlockAndAssertKitLoginScreen($I, $linkText) { + // Switch to the Gutenberg IFrame. + $I->switchToGutenbergEditor($I); + $I->click( $linkText, [ @@ -876,6 +894,9 @@ public function clickLinkInBlockAndAssertKitLoginScreen($I, $linkText) // Close tab. $I->closeTab(); + + // Switch back to main window. + $I->switchToIFrame(); } /** @@ -888,7 +909,8 @@ public function clickLinkInBlockAndAssertKitLoginScreen($I, $linkText) */ public function seeFormBlockIFrameHasMessage($I, $message) { - $I->switchToGutenbergEditor($I); // Required for apiVersion 3 blocks. + // Switch to the Gutenberg IFrame. + $I->switchToGutenbergEditor($I); // Switch to iframe preview for the Form block. $I->switchToIFrame('iframe[class="components-sandbox"]'); From d2f8a7560416d90cc79001d75468f84fd6e7a055 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Mon, 5 Jan 2026 17:34:37 +0800 Subject: [PATCH 07/19] =?UTF-8?q?Divi:=20Don=E2=80=99t=20attempt=20to=20sw?= =?UTF-8?q?itch=20to=20iframe=20editor,=20as=20it=20won=E2=80=99t=20exist?= =?UTF-8?q?=20when=20Divi=20enabled?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/Support/Helper/DiviBuilder.php | 8 +++++++- tests/Support/Helper/WPGutenberg.php | 17 +++++++++++------ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/tests/Support/Helper/DiviBuilder.php b/tests/Support/Helper/DiviBuilder.php index 87aa7372a..7568e6db4 100644 --- a/tests/Support/Helper/DiviBuilder.php +++ b/tests/Support/Helper/DiviBuilder.php @@ -83,7 +83,13 @@ public function createDiviPageInBackendEditor($I, $title) public function createDiviPageInFrontendEditor($I, $title, $configureMetaBox = true) { // Add a Page using the Gutenberg editor. - $I->addGutenbergPage($I, 'page', $title); + // Don't switch to the Gutenberg IFrame, as we're using the Divi Builder, which won't use the iframe. + $I->addGutenbergPage( + $I, + postType: 'page', + title: $title, + switchToGutenbergEditor: false + ); // Configure metabox's Form setting = None, ensuring we only test the block in Gutenberg. if ($configureMetaBox) { diff --git a/tests/Support/Helper/WPGutenberg.php b/tests/Support/Helper/WPGutenberg.php index 3c60987f3..a152396f3 100644 --- a/tests/Support/Helper/WPGutenberg.php +++ b/tests/Support/Helper/WPGutenberg.php @@ -28,24 +28,29 @@ public function switchToGutenbergEditor($I) * * @since 1.9.7.5 * - * @param EndToEndTester $I EndToEnd Tester. - * @param string $postType Post Type. - * @param string $title Post Title. + * @param EndToEndTester $I EndToEnd Tester. + * @param string $postType Post Type. + * @param string $title Post Title. + * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame (i.e if all blocks use apiVersion 3). */ - public function addGutenbergPage($I, $postType = 'page', $title = 'Gutenberg Title') + public function addGutenbergPage($I, $postType = 'page', $title = 'Gutenberg Title', $switchToGutenbergEditor = true) { // Navigate to Post Type (e.g. Pages / Posts) > Add New. $I->amOnAdminPage('post-new.php?post_type=' . $postType); $I->waitForElementVisible('body.post-new-php'); // Switch to the Gutenberg IFrame. - $I->switchToGutenbergEditor($I); + if ($switchToGutenbergEditor) { + $I->switchToGutenbergEditor($I); + } // Define the Title. $I->fillField('.editor-post-title__input', $title); // Switch back to main window. - $I->switchToIFrame(); + if ($switchToGutenbergEditor) { + $I->switchToIFrame(); + } } /** From 5d61c5f9a47d300a0a79d5a76a8e96fcdf818628 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Mon, 5 Jan 2026 17:45:29 +0800 Subject: [PATCH 08/19] Tests: testBlockNoCredentialsPopupWindow: Switch to editor after closing popup Need to call switchToGutenbergEditor, as closeTab() also reverts back to the main browser window, not the iframe we previously switched to --- tests/Support/Helper/KitPlugin.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/Support/Helper/KitPlugin.php b/tests/Support/Helper/KitPlugin.php index 8e98daf20..7f4409223 100644 --- a/tests/Support/Helper/KitPlugin.php +++ b/tests/Support/Helper/KitPlugin.php @@ -803,6 +803,9 @@ public function testBlockNoCredentialsPopupWindow($I, $blockName, $expectedMessa // Close the popup window. $I->closeTab(); + // Switch to the Gutenberg IFrame. + $I->switchToGutenbergEditor($I); + // Wait until the block changes to refreshing. $I->waitForElementVisible('.' . $blockName . ' div.convertkit-progress-bar', 30); From b9b1e35ee1370626dc1cfbe5894da9e06aeee198 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Mon, 5 Jan 2026 18:01:28 +0800 Subject: [PATCH 09/19] Tests: Default switchToGutenbergEditor = true --- .../PageBlockFormBuilderCest.php | 47 ++++++++-- tests/Support/Helper/KitPlugin.php | 87 +++++++++++++------ 2 files changed, 100 insertions(+), 34 deletions(-) diff --git a/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormBuilderCest.php b/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormBuilderCest.php index 38ee77d1a..b3c344478 100644 --- a/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormBuilderCest.php +++ b/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormBuilderCest.php @@ -1246,11 +1246,22 @@ public function _passed(EndToEndTester $I) * * @since 3.0.0 * - * @param EndToEndTester $I Tester. + * @param EndToEndTester $I Tester. + * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame. */ - private function seeFormBuilderBlock(EndToEndTester $I) + private function seeFormBuilderBlock(EndToEndTester $I, $switchToGutenbergEditor = true) { + // Switch to the Gutenberg IFrame. + if ($switchToGutenbergEditor) { + $I->switchToGutenbergEditor($I); + } + $I->seeElementInDOM('div[data-type="convertkit/form-builder"]'); + + // Switch back to main window. + if ($switchToGutenbergEditor) { + $I->switchToIFrame(); + } } /** @@ -1258,11 +1269,22 @@ private function seeFormBuilderBlock(EndToEndTester $I) * * @since 3.0.0 * - * @param EndToEndTester $I Tester. + * @param EndToEndTester $I Tester. + * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame. */ - private function seeFormBuilderButtonBlock(EndToEndTester $I) + private function seeFormBuilderButtonBlock(EndToEndTester $I, $switchToGutenbergEditor = true) { + // Switch to the Gutenberg IFrame. + if ($switchToGutenbergEditor) { + $I->switchToGutenbergEditor($I); + } + $I->seeElementInDOM('div[data-type="convertkit/form-builder"] div[data-type="core/button"]'); + + // Switch back to main window. + if ($switchToGutenbergEditor) { + $I->switchToIFrame(); + } } /** @@ -1277,9 +1299,15 @@ private function seeFormBuilderButtonBlock(EndToEndTester $I) * @param string $label Field label. * @param bool $required Whether the field should be marked `required`. * @param string $container The container the field should be in. + * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame. */ - private function seeFormBuilderField(EndToEndTester $I, $fieldType, $fieldName, $fieldID, $label, $required = true, $container = 'div') + private function seeFormBuilderField(EndToEndTester $I, $fieldType, $fieldName, $fieldID, $label, $required = true, $container = 'div', $switchToGutenbergEditor = true) { + // Switch to the Gutenberg IFrame. + if ($switchToGutenbergEditor) { + $I->switchToGutenbergEditor($I); + } + // Check field exists with correct attributes. switch ( $fieldType ) { case 'textarea': @@ -1297,6 +1325,11 @@ private function seeFormBuilderField(EndToEndTester $I, $fieldType, $fieldName, if ($required) { $I->seeElementInDOM($container . ' label[for="' . $fieldID . '"] span.convertkit-form-builder-field-required'); } + + // Switch back to main window. + if ($switchToGutenbergEditor) { + $I->switchToIFrame(); + } } /** @@ -1304,8 +1337,8 @@ private function seeFormBuilderField(EndToEndTester $I, $fieldType, $fieldName, * * @since 3.0.0 * - * @param EndToEndTester $I Tester. - * @param string $text The text to check for in the submit button. + * @param EndToEndTester $I Tester. + * @param string $text The text to check for in the submit button. */ private function seeFormBuilderSubmitButton(EndToEndTester $I, $text) { diff --git a/tests/Support/Helper/KitPlugin.php b/tests/Support/Helper/KitPlugin.php index 7f4409223..f02049f89 100644 --- a/tests/Support/Helper/KitPlugin.php +++ b/tests/Support/Helper/KitPlugin.php @@ -771,17 +771,24 @@ public function checkSelectOptionOrder($I, $selectElement, $values) * * @since 2.2.6 * - * @param EndToEndTester $I Tester. - * @param string $blockName Block Name. - * @param bool|string $expectedMessage Expected message displayed in block after valid OAuth tokens are specified. + * @param EndToEndTester $I Tester. + * @param string $blockName Block Name. + * @param bool|string $expectedMessage Expected message displayed in block after valid OAuth tokens are specified. + * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame. */ - public function testBlockNoCredentialsPopupWindow($I, $blockName, $expectedMessage = false) + public function testBlockNoCredentialsPopupWindow($I, $blockName, $expectedMessage = false, $switchToGutenbergEditor = true) { // Confirm that the Form block displays instructions to the user on how to enter their API Key. - $I->seeBlockHasNoContentMessage($I, 'Not connected to Kit.'); + $I->seeBlockHasNoContentMessage( + $I, + message: 'Not connected to Kit.', + switchToGutenbergEditor: $switchToGutenbergEditor + ); // Switch to the Gutenberg IFrame. - $I->switchToGutenbergEditor($I); + if ($switchToGutenbergEditor) { + $I->switchToGutenbergEditor($I); + } // Click the link to confirm it loads the Plugin's setup wizard. $I->click( @@ -804,7 +811,9 @@ public function testBlockNoCredentialsPopupWindow($I, $blockName, $expectedMessa $I->closeTab(); // Switch to the Gutenberg IFrame. - $I->switchToGutenbergEditor($I); + if ($switchToGutenbergEditor) { + $I->switchToGutenbergEditor($I); + } // Wait until the block changes to refreshing. $I->waitForElementVisible('.' . $blockName . ' div.convertkit-progress-bar', 30); @@ -814,11 +823,17 @@ public function testBlockNoCredentialsPopupWindow($I, $blockName, $expectedMessa $I->waitForElementNotVisible('div.convertkit-no-content button.wp-convertkit-refresh-resources', 30); // Switch back to main window. - $I->switchToIFrame(); + if ($switchToGutenbergEditor) { + $I->switchToIFrame(); + } // Confirm that the block displays the expected message. if ($expectedMessage) { - $I->seeBlockHasNoContentMessage($I, $expectedMessage); + $I->seeBlockHasNoContentMessage( + $I, + message: $expectedMessage, + switchToGutenbergEditor: $switchToGutenbergEditor + ); } } @@ -827,12 +842,15 @@ public function testBlockNoCredentialsPopupWindow($I, $blockName, $expectedMessa * * @since 2.7.7 * - * @param EndToEndTester $I EndToEndTester. + * @param EndToEndTester $I EndToEndTester. + * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame. */ - public function clickBlockRefreshButton($I) + public function clickBlockRefreshButton($I, $switchToGutenbergEditor = true) { // Switch to the Gutenberg IFrame. - $I->switchToGutenbergEditor($I); + if ($switchToGutenbergEditor) { + $I->switchToGutenbergEditor($I); + } // Click the refresh button. $I->click('div.convertkit-no-content button.wp-convertkit-refresh-resources'); @@ -841,7 +859,9 @@ public function clickBlockRefreshButton($I) $I->waitForElementNotVisible('div.convertkit-no-content button.wp-convertkit-refresh-resources'); // Switch back to main window. - $I->switchToIFrame(); + if ($switchToGutenbergEditor) { + $I->switchToIFrame(); + } } /** @@ -849,13 +869,16 @@ public function clickBlockRefreshButton($I) * * @since 2.7.7 * - * @param EndToEndTester $I EndToEndTester. - * @param string $message Message. + * @param EndToEndTester $I EndToEndTester. + * @param string $message Message. + * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame. */ - public function seeBlockHasNoContentMessage($I, $message) + public function seeBlockHasNoContentMessage($I, $message, $switchToGutenbergEditor = true) { // Switch to the Gutenberg IFrame. - $I->switchToGutenbergEditor($I); + if ($switchToGutenbergEditor) { + $I->switchToGutenbergEditor($I); + } $I->see( $message, @@ -865,7 +888,9 @@ public function seeBlockHasNoContentMessage($I, $message) ); // Switch back to main window. - $I->switchToIFrame(); + if ($switchToGutenbergEditor) { + $I->switchToIFrame(); + } } /** @@ -874,13 +899,16 @@ public function seeBlockHasNoContentMessage($I, $message) * * @since 2.7.7 * - * @param EndToEndTester $I EndToEndTester. - * @param string $linkText Link text. + * @param EndToEndTester $I EndToEndTester. + * @param string $linkText Link text. + * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame. */ - public function clickLinkInBlockAndAssertKitLoginScreen($I, $linkText) + public function clickLinkInBlockAndAssertKitLoginScreen($I, $linkText, $switchToGutenbergEditor = true) { // Switch to the Gutenberg IFrame. - $I->switchToGutenbergEditor($I); + if ($switchToGutenbergEditor) { + $I->switchToGutenbergEditor($I); + } $I->click( $linkText, @@ -899,7 +927,9 @@ public function clickLinkInBlockAndAssertKitLoginScreen($I, $linkText) $I->closeTab(); // Switch back to main window. - $I->switchToIFrame(); + if ($switchToGutenbergEditor) { + $I->switchToIFrame(); + } } /** @@ -907,13 +937,16 @@ public function clickLinkInBlockAndAssertKitLoginScreen($I, $linkText) * * @since 2.7.7 * - * @param EndToEndTester $I EndToEndTester. - * @param string $message Message. + * @param EndToEndTester $I EndToEndTester. + * @param string $message Message. + * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame. */ - public function seeFormBlockIFrameHasMessage($I, $message) + public function seeFormBlockIFrameHasMessage($I, $message, $switchToGutenbergEditor = true) { // Switch to the Gutenberg IFrame. - $I->switchToGutenbergEditor($I); + if ($switchToGutenbergEditor) { + $I->switchToGutenbergEditor($I); + } // Switch to iframe preview for the Form block. $I->switchToIFrame('iframe[class="components-sandbox"]'); From c6ced2e9a3a839f9834f0656691ff35e76aefd91 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Mon, 5 Jan 2026 18:13:06 +0800 Subject: [PATCH 10/19] =?UTF-8?q?Tests:=20Form=20Builder:=20Don=E2=80=99t?= =?UTF-8?q?=20switch=20to=20the=20Gutenberg=20Editor=20when=20testing=20fr?= =?UTF-8?q?ontend=20site?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PageBlockFormBuilderCest.php | 49 ++++++++++++------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormBuilderCest.php b/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormBuilderCest.php index b3c344478..08079af25 100644 --- a/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormBuilderCest.php +++ b/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormBuilderCest.php @@ -129,7 +129,8 @@ public function testFormBuilderBlockWithDefaultConfiguration(EndToEndTester $I) fieldName: 'first_name', fieldID: 'first_name', label: 'First name', - container: 'div.wp-block-convertkit-form-builder' + container: 'div.wp-block-convertkit-form-builder', + switchToGutenbergEditor: false ); $this->seeFormBuilderField( $I, @@ -137,7 +138,8 @@ public function testFormBuilderBlockWithDefaultConfiguration(EndToEndTester $I) fieldName: 'email', fieldID: 'email', label: 'Email address', - container: 'div.wp-block-convertkit-form-builder' + container: 'div.wp-block-convertkit-form-builder', + switchToGutenbergEditor: false ); // Generate email address for this test. @@ -247,7 +249,8 @@ public function testFormBuilderBlockWithTextCustomization(EndToEndTester $I) fieldName: 'first_name', fieldID: 'first_name', label: 'Nafnið þitt', - container: 'div.wp-block-convertkit-form-builder' + container: 'div.wp-block-convertkit-form-builder', + switchToGutenbergEditor: false ); $this->seeFormBuilderField( $I, @@ -255,7 +258,8 @@ public function testFormBuilderBlockWithTextCustomization(EndToEndTester $I) fieldName: 'email', fieldID: 'email', label: 'Netfangið þitt', - container: 'div.wp-block-convertkit-form-builder' + container: 'div.wp-block-convertkit-form-builder', + switchToGutenbergEditor: false ); // Generate email address for this test. @@ -348,7 +352,8 @@ public function testFormBuilderBlockWithFormEnabled(EndToEndTester $I) fieldName: 'first_name', fieldID: 'first_name', label: 'First name', - container: 'div.wp-block-convertkit-form-builder' + container: 'div.wp-block-convertkit-form-builder', + switchToGutenbergEditor: false ); $this->seeFormBuilderField( $I, @@ -356,7 +361,8 @@ public function testFormBuilderBlockWithFormEnabled(EndToEndTester $I) fieldName: 'email', fieldID: 'email', label: 'Email address', - container: 'div.wp-block-convertkit-form-builder' + container: 'div.wp-block-convertkit-form-builder', + switchToGutenbergEditor: false ); // Generate email address for this test. @@ -454,7 +460,8 @@ public function testFormBuilderBlockWithTaggingEnabled(EndToEndTester $I) fieldName: 'first_name', fieldID: 'first_name', label: 'First name', - container: 'div.wp-block-convertkit-form-builder' + container: 'div.wp-block-convertkit-form-builder', + switchToGutenbergEditor: false ); $this->seeFormBuilderField( $I, @@ -462,7 +469,8 @@ public function testFormBuilderBlockWithTaggingEnabled(EndToEndTester $I) fieldName: 'email', fieldID: 'email', label: 'Email address', - container: 'div.wp-block-convertkit-form-builder' + container: 'div.wp-block-convertkit-form-builder', + switchToGutenbergEditor: false ); // Generate email address for this test. @@ -559,7 +567,8 @@ public function testFormBuilderBlockWithSequenceEnabled(EndToEndTester $I) fieldName: 'first_name', fieldID: 'first_name', label: 'First name', - container: 'div.wp-block-convertkit-form-builder' + container: 'div.wp-block-convertkit-form-builder', + switchToGutenbergEditor: false ); $this->seeFormBuilderField( $I, @@ -567,7 +576,8 @@ public function testFormBuilderBlockWithSequenceEnabled(EndToEndTester $I) fieldName: 'email', fieldID: 'email', label: 'Email address', - container: 'div.wp-block-convertkit-form-builder' + container: 'div.wp-block-convertkit-form-builder', + switchToGutenbergEditor: false ); // Generate email address for this test. @@ -681,7 +691,8 @@ public function testFormBuilderBlockWithCustomField(EndToEndTester $I) fieldName: 'first_name', fieldID: 'first_name', label: 'First name', - container: 'div.wp-block-convertkit-form-builder' + container: 'div.wp-block-convertkit-form-builder', + switchToGutenbergEditor: false ); $this->seeFormBuilderField( $I, @@ -689,7 +700,8 @@ public function testFormBuilderBlockWithCustomField(EndToEndTester $I) fieldName: 'email', fieldID: 'email', label: 'Email address', - container: 'div.wp-block-convertkit-form-builder' + container: 'div.wp-block-convertkit-form-builder', + switchToGutenbergEditor: false ); foreach ( $customFields as $key => $field ) { $this->seeFormBuilderField( @@ -698,7 +710,8 @@ public function testFormBuilderBlockWithCustomField(EndToEndTester $I) fieldName: 'custom_fields][' . $key, fieldID: 'custom_fields_' . $key, label: $field['label'], - container: 'div.wp-block-convertkit-form-builder' + container: 'div.wp-block-convertkit-form-builder', + switchToGutenbergEditor: false ); } @@ -796,7 +809,8 @@ public function testFormBuilderBlockWithRedirectOption(EndToEndTester $I) fieldName: 'first_name', fieldID: 'first_name', label: 'First name', - container: 'div.wp-block-convertkit-form-builder' + container: 'div.wp-block-convertkit-form-builder', + switchToGutenbergEditor: false ); $this->seeFormBuilderField( $I, @@ -804,7 +818,8 @@ public function testFormBuilderBlockWithRedirectOption(EndToEndTester $I) fieldName: 'email', fieldID: 'email', label: 'Email address', - container: 'div.wp-block-convertkit-form-builder' + container: 'div.wp-block-convertkit-form-builder', + switchToGutenbergEditor: false ); // Generate email address for this test. @@ -1311,10 +1326,10 @@ private function seeFormBuilderField(EndToEndTester $I, $fieldType, $fieldName, // Check field exists with correct attributes. switch ( $fieldType ) { case 'textarea': - $I->seeElementInDOM($container . ' textarea[name="convertkit[' . $fieldName . ']"][id="' . $fieldID . '"]' . $required ? '[required]' : ''); + $I->seeElementInDOM($container . ' textarea[name="convertkit[' . $fieldName . ']"][id="' . $fieldID . '"]' . ( $required ? '[required]' : '' ) ); break; default: - $I->seeElementInDOM($container . ' input[name="convertkit[' . $fieldName . ']"][type="' . $fieldType . '"][id="' . $fieldID . '"]' . $required ? '[required]' : ''); + $I->seeElementInDOM($container . ' input[name="convertkit[' . $fieldName . ']"][type="' . $fieldType . '"][id="' . $fieldID . '"]' . ( $required ? '[required]' : '' ) ); } // Check label exists with correct text. From 4a9583f95ef02094bbe27da27ea3969bc1fc812e Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Mon, 5 Jan 2026 18:32:17 +0800 Subject: [PATCH 11/19] Coding Standards --- .../PageBlockFormBuilderCest.php | 8 ++++---- tests/Support/Helper/KitPlugin.php | 20 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormBuilderCest.php b/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormBuilderCest.php index 08079af25..27ffac09a 100644 --- a/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormBuilderCest.php +++ b/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormBuilderCest.php @@ -1261,7 +1261,7 @@ public function _passed(EndToEndTester $I) * * @since 3.0.0 * - * @param EndToEndTester $I Tester. + * @param EndToEndTester $I Tester. * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame. */ private function seeFormBuilderBlock(EndToEndTester $I, $switchToGutenbergEditor = true) @@ -1284,7 +1284,7 @@ private function seeFormBuilderBlock(EndToEndTester $I, $switchToGutenbergEditor * * @since 3.0.0 * - * @param EndToEndTester $I Tester. + * @param EndToEndTester $I Tester. * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame. */ private function seeFormBuilderButtonBlock(EndToEndTester $I, $switchToGutenbergEditor = true) @@ -1352,8 +1352,8 @@ private function seeFormBuilderField(EndToEndTester $I, $fieldType, $fieldName, * * @since 3.0.0 * - * @param EndToEndTester $I Tester. - * @param string $text The text to check for in the submit button. + * @param EndToEndTester $I Tester. + * @param string $text The text to check for in the submit button. */ private function seeFormBuilderSubmitButton(EndToEndTester $I, $text) { diff --git a/tests/Support/Helper/KitPlugin.php b/tests/Support/Helper/KitPlugin.php index f02049f89..10620b3d8 100644 --- a/tests/Support/Helper/KitPlugin.php +++ b/tests/Support/Helper/KitPlugin.php @@ -771,9 +771,9 @@ public function checkSelectOptionOrder($I, $selectElement, $values) * * @since 2.2.6 * - * @param EndToEndTester $I Tester. - * @param string $blockName Block Name. - * @param bool|string $expectedMessage Expected message displayed in block after valid OAuth tokens are specified. + * @param EndToEndTester $I Tester. + * @param string $blockName Block Name. + * @param bool|string $expectedMessage Expected message displayed in block after valid OAuth tokens are specified. * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame. */ public function testBlockNoCredentialsPopupWindow($I, $blockName, $expectedMessage = false, $switchToGutenbergEditor = true) @@ -842,7 +842,7 @@ public function testBlockNoCredentialsPopupWindow($I, $blockName, $expectedMessa * * @since 2.7.7 * - * @param EndToEndTester $I EndToEndTester. + * @param EndToEndTester $I EndToEndTester. * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame. */ public function clickBlockRefreshButton($I, $switchToGutenbergEditor = true) @@ -869,8 +869,8 @@ public function clickBlockRefreshButton($I, $switchToGutenbergEditor = true) * * @since 2.7.7 * - * @param EndToEndTester $I EndToEndTester. - * @param string $message Message. + * @param EndToEndTester $I EndToEndTester. + * @param string $message Message. * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame. */ public function seeBlockHasNoContentMessage($I, $message, $switchToGutenbergEditor = true) @@ -899,8 +899,8 @@ public function seeBlockHasNoContentMessage($I, $message, $switchToGutenbergEdit * * @since 2.7.7 * - * @param EndToEndTester $I EndToEndTester. - * @param string $linkText Link text. + * @param EndToEndTester $I EndToEndTester. + * @param string $linkText Link text. * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame. */ public function clickLinkInBlockAndAssertKitLoginScreen($I, $linkText, $switchToGutenbergEditor = true) @@ -937,8 +937,8 @@ public function clickLinkInBlockAndAssertKitLoginScreen($I, $linkText, $switchTo * * @since 2.7.7 * - * @param EndToEndTester $I EndToEndTester. - * @param string $message Message. + * @param EndToEndTester $I EndToEndTester. + * @param string $message Message. * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame. */ public function seeFormBlockIFrameHasMessage($I, $message, $switchToGutenbergEditor = true) From 92d071d5b9cab87489c27919c377af7280987200 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Tue, 6 Jan 2026 14:16:30 +0800 Subject: [PATCH 12/19] Fix tests --- .../PageBlockFormBuilderCest.php | 14 +++---- tests/Support/Helper/KitPlugin.php | 17 ++++++-- tests/Support/Helper/WPGutenberg.php | 41 +++++++++++++++++-- 3 files changed, 59 insertions(+), 13 deletions(-) diff --git a/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormBuilderCest.php b/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormBuilderCest.php index 27ffac09a..a217b829a 100644 --- a/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormBuilderCest.php +++ b/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormBuilderCest.php @@ -208,11 +208,11 @@ public function testFormBuilderBlockWithTextCustomization(EndToEndTester $I) ); // Change the labels of the form fields. These are added as inner blocks when the Form Builder block is added. - $I->click('div[data-type="convertkit/form-builder-field-name"]'); + $I->selectGutenbergBlockInEditor($I, 'convertkit/form-builder-field-name'); $I->waitForElementVisible('.interface-interface-skeleton__sidebar[aria-label="Editor settings"]'); $I->fillField('#convertkit_form_builder_field_name_label', 'Nafnið þitt'); - $I->click('div[data-type="convertkit/form-builder-field-email"]'); + $I->selectGutenbergBlockInEditor($I, 'convertkit/form-builder-field-email'); $I->waitForElementVisible('.interface-interface-skeleton__sidebar[aria-label="Editor settings"]'); $I->fillField('#convertkit_form_builder_field_email_label', 'Netfangið þitt'); @@ -271,9 +271,9 @@ public function testFormBuilderBlockWithTextCustomization(EndToEndTester $I) $I->click('div.wp-block-convertkit-form-builder button[type="submit"]'); // Check that the form no longer displays and the message displays. + $I->waitForText('Welcome to the newsletter!', 10, '.convertkit-form-builder.wp-block-convertkit-form-builder'); $I->dontSeeElementInDOM('input[name="convertkit[first_name]"]'); $I->dontSeeElementInDOM('input[name="convertkit[email]"]'); - $I->waitForText('Welcome to the newsletter!', 10, '.convertkit-form-builder.wp-block-convertkit-form-builder'); // Confirm that the email address was added to Kit. $I->apiCheckSubscriberExists( @@ -666,7 +666,7 @@ public function testFormBuilderBlockWithCustomField(EndToEndTester $I) foreach ( $customFields as $field ) { // Focus on an inner block, so the Form Builder field blocks are available in the inserter. - $I->click('div[data-type="convertkit/form-builder-field-name"]'); + $I->selectGutenbergBlockInEditor($I, 'convertkit/form-builder-field-name'); // Add custom field block, mapping its data to the Last Name field in Kit. $I->addGutenbergBlock( @@ -936,7 +936,7 @@ public function testFormBuilderFieldsCanOnlyBeInsertedToFormBuilderBlock(EndToEn ); // Click an inner block within the Form Builder block. - $I->click('div[data-type="convertkit/form-builder"]'); + $I->selectGutenbergBlockInEditor($I, 'convertkit/form-builder'); $I->waitForElementVisible('.interface-interface-skeleton__sidebar[aria-label="Editor settings"]'); // Confirm the Form Field blocks can be added to the Form Builder block. @@ -990,7 +990,7 @@ public function testFormBuilderSupportsCoreBlocks(EndToEndTester $I) ); // Click an inner block within the Form Builder block. - $I->click('div[data-type="convertkit/form-builder"]'); + $I->selectGutenbergBlockInEditor($I, 'convertkit/form-builder'); $I->waitForElementVisible('.interface-interface-skeleton__sidebar[aria-label="Editor settings"]'); // Confirm some core blocks can be added to the Form Builder block. @@ -1175,7 +1175,7 @@ public function testFormBuilderWithStoreEntriesEnabled(EndToEndTester $I) ); // Focus on an inner block, so the Form Builder field blocks are available in the inserter. - $I->click('div[data-type="convertkit/form-builder-field-name"]'); + $I->selectGutenbergBlockInEditor($I, 'convertkit/form-builder-field-name'); // Add custom field block, mapping its data to the Last Name field in Kit. $I->addGutenbergBlock( diff --git a/tests/Support/Helper/KitPlugin.php b/tests/Support/Helper/KitPlugin.php index 10620b3d8..ed836c367 100644 --- a/tests/Support/Helper/KitPlugin.php +++ b/tests/Support/Helper/KitPlugin.php @@ -1006,11 +1006,17 @@ public function dontSeeCreatorNetworkRecommendationsScript($I, $pageID) * * @since 2.2.0 * - * @param EndToEndTester $I EndToEnd Tester. - * @param string $selector CSS or ID selector for the input element. + * @param EndToEndTester $I EndToEnd Tester. + * @param string $selector CSS or ID selector for the input element. + * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame. */ - public function selectAllText($I, $selector) + public function selectAllText($I, $selector, $switchToGutenbergEditor = true) { + // Switch to the Gutenberg IFrame. + if ($switchToGutenbergEditor) { + $I->switchToGutenbergEditor($I); + } + // Determine whether to use the control or command key, depending on the OS. $key = \Facebook\WebDriver\WebDriverKeys::CONTROL; @@ -1021,6 +1027,11 @@ public function selectAllText($I, $selector) // Press Ctrl/Command + a on Keyboard. $I->pressKey($selector, array( $key, 'a' )); + + // Switch back to main window. + if ($switchToGutenbergEditor) { + $I->switchToIFrame(); + } } /** diff --git a/tests/Support/Helper/WPGutenberg.php b/tests/Support/Helper/WPGutenberg.php index a152396f3..2f826ddab 100644 --- a/tests/Support/Helper/WPGutenberg.php +++ b/tests/Support/Helper/WPGutenberg.php @@ -151,15 +151,28 @@ public function addGutenbergBlock($I, $blockName, $blockProgrammaticName, $block * * @since 2.0.0 * - * @param EndToEndTester $I EndToEnd Tester. - * @param string $text Paragraph Text. + * @param EndToEndTester $I EndToEnd Tester. + * @param string $text Paragraph Text. + * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame. */ - public function addGutenbergParagraphBlock($I, $text) + public function addGutenbergParagraphBlock($I, $text, $switchToGutenbergEditor = true) { + // Add paragraph block. $I->addGutenbergBlock($I, 'Paragraph', 'paragraph/paragraph'); + // Switch to the Gutenberg IFrame. + if ($switchToGutenbergEditor) { + $I->switchToGutenbergEditor($I); + } + + // Click the editor area and enter the text in the paragraph. $I->click('.wp-block-post-content'); $I->fillField('.wp-block-post-content p[data-empty="true"]', $text); + + // Switch back to main window. + if ($switchToGutenbergEditor) { + $I->switchToIFrame(); + } } /** @@ -261,6 +274,28 @@ private function insertGutenbergLink($I, $name) $I->click($name, '.block-editor-link-control__search-results'); } + /** + * Helper method to select an existing block previously added to the Gutenberg editor. + * + * @since 3.1.4 + * + * @param EndToEndTester $I EndToEnd Tester. + * @param string $blockProgrammaticName Programmatic Block Name (e.g. 'convertkit/form-builder-field-name'). + * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame. + */ + public function selectGutenbergBlockInEditor($I, $blockProgrammaticName, $switchToGutenbergEditor = true) + { + if ($switchToGutenbergEditor) { + $I->switchToGutenbergEditor($I); + } + + $I->click('div[data-type="' . $blockProgrammaticName . '"]'); + + if ($switchToGutenbergEditor) { + $I->switchToIFrame(); + } + } + /** * Asserts that the given block is not available in the Gutenberg block library. * From bdf0bb27a0c11b1e512f0e2d76ce0b01d6edddec Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Tue, 6 Jan 2026 15:52:01 +0800 Subject: [PATCH 13/19] Add apiVersion 2 block tests --- .github/workflows/tests-backward-compat.yml | 305 ++++++++++++++++++ .github/workflows/tests.yml | 2 + .../PageBlockFormBuilderCest.php | 58 ++-- tests/Support/Helper/DiviBuilder.php | 15 +- tests/Support/Helper/KitPlugin.php | 62 ++-- tests/Support/Helper/WPGutenberg.php | 42 ++- 6 files changed, 396 insertions(+), 88 deletions(-) create mode 100644 .github/workflows/tests-backward-compat.yml diff --git a/.github/workflows/tests-backward-compat.yml b/.github/workflows/tests-backward-compat.yml new file mode 100644 index 000000000..ced780c0e --- /dev/null +++ b/.github/workflows/tests-backward-compat.yml @@ -0,0 +1,305 @@ +name: Run Tests + +# When to run tests. +on: + pull_request: + types: + - opened + - synchronize + push: + branches: + - main + +jobs: + tests: + # Name. + name: ${{ matrix.test-groups }} / WordPress ${{ matrix.wp-versions }} / PHP ${{ matrix.php-versions }} + + # Virtual Environment to use. + # @see: https://github.com/actions/virtual-environments + runs-on: ubuntu-latest + + # Environment Variables. + # Accessible by using ${{ env.NAME }} + # Use ${{ secrets.NAME }} to include any GitHub Secrets in ${{ env.NAME }} + env: + ROOT_DIR: /var/www/html + PLUGIN_DIR: /var/www/html/wp-content/plugins/convertkit + DB_NAME: test + DB_USER: root + DB_PASS: root + DB_HOST: localhost + WORDPRESS_V3_BLOCK_EDITOR_ENABLED: false # Test apiVersion 2 blocks against WordPress 6.2.8 + CONVERTKIT_API_KEY: ${{ secrets.CONVERTKIT_API_KEY }} # ConvertKit API Key, stored in the repository's Settings > Secrets + CONVERTKIT_API_SECRET: ${{ secrets.CONVERTKIT_API_SECRET }} # ConvertKit API Secret, stored in the repository's Settings > Secrets + CONVERTKIT_API_KEY_NO_DATA: ${{ secrets.CONVERTKIT_API_KEY_NO_DATA }} # ConvertKit API Key for ConvertKit account with no data, stored in the repository's Settings > Secrets + CONVERTKIT_API_SECRET_NO_DATA: ${{ secrets.CONVERTKIT_API_SECRET_NO_DATA }} # ConvertKit API Secret for ConvertKit account with no data, stored in the repository's Settings > Secrets + CONVERTKIT_OAUTH_CLIENT_ID: ${{ secrets.CONVERTKIT_OAUTH_CLIENT_ID }} + CONVERTKIT_OAUTH_REDIRECT_URI: ${{ secrets.CONVERTKIT_OAUTH_REDIRECT_URI }} + KIT_OAUTH_REDIRECT_URI: ${{ secrets.KIT_OAUTH_REDIRECT_URI }} + CONVERTKIT_API_SIGNED_SUBSCRIBER_ID: ${{ secrets.CONVERTKIT_API_SIGNED_SUBSCRIBER_ID }} # ConvertKit API Signed Subscriber ID, stored in the repository's Settings > Secrets + CONVERTKIT_API_SIGNED_SUBSCRIBER_ID_NO_ACCESS: ${{ secrets.CONVERTKIT_API_SIGNED_SUBSCRIBER_ID_NO_ACCESS }} # ConvertKit API Signed Subscriber ID with no access to Products, stored in the repository's Settings > Secrets + CONVERTKIT_API_RECAPTCHA_SITE_KEY: ${{ secrets.CONVERTKIT_API_RECAPTCHA_SITE_KEY }} # Google reCAPTCHA v3 Site Key, stored in the repository's Settings > Secrets + CONVERTKIT_API_RECAPTCHA_SECRET_KEY: ${{ secrets.CONVERTKIT_API_RECAPTCHA_SECRET_KEY }} # Google reCAPTCHA v3 Secret Key, stored in the repository's Settings > Secrets + + # Defines the WordPress and PHP Versions matrix to run tests on + # WordPress 6.2.8 and specific block tests are run to test apiVersion 2 blocks + strategy: + fail-fast: false + matrix: + wp-versions: [ '6.2.8' ] #[ '6.1.1', 'latest' ] + php-versions: [ '8.1' ] #[ '7.4', '8.0', '8.1' ] + + # Folder names within the 'tests' folder to run tests in parallel. + test-groups: [ + 'EndToEnd/broadcasts/blocks-shortcodes/PageBlockBroadcastsCest', + 'EndToEnd/forms/blocks-shortcodes/PageBlockFormBuilderCest', + 'EndToEnd/forms/blocks-shortcodes/PageBlockFormCest', + 'EndToEnd/forms/blocks-shortcodes/PageBlockFormTriggerCest', + 'EndToEnd/products/PageBlockFormatterProductLinkCest', + 'EndToEnd/products/PageBlockProductCest' + ] + + # Steps to install, configure and run tests + steps: + - name: Define Test Group Name + id: test-group + uses: mad9000/actions-find-and-replace-string@5 + with: + source: ${{ matrix.test-groups }} + find: '/' + replace: '-' + replaceAll: true + + # Checkout Plugin to /home/runner/work/convertkit-wordpress/convertkit-wordpress/convertkit + # We cannot checkout to ${{ env.PLUGIN_DIR }} as GitHub Actions require it be first placed in /home/runner/work/repo/repo + - name: Checkout Plugin + uses: actions/checkout@v4 + with: + path: /home/runner/work/convertkit-wordpress/convertkit-wordpress/convertkit + + - name: Start MySQL + run: sudo systemctl start mysql.service + + - name: Create MySQL Database + run: | + mysql -e 'CREATE DATABASE test;' -u${{ env.DB_USER }} -p${{ env.DB_PASS }} + mysql -e 'SHOW DATABASES;' -u${{ env.DB_USER }} -p${{ env.DB_PASS }} + + # WordPress won't be able to connect to the DB if we don't perform this step. + - name: Permit MySQL Password Auth for MySQL 8.0 + run: mysql -e "ALTER USER '${{ env.DB_USER }}'@'${{ env.DB_HOST }}' IDENTIFIED WITH mysql_native_password BY '${{ env.DB_PASS }}';" -u${{ env.DB_USER }} -p${{ env.DB_PASS }} + + # Some workflows checkout WordPress from GitHub, but that seems to bring a bunch of uncompiled files with it. + # Instead download from wordpress.org stable. + - name: Download and Extract WordPress + run: | + sudo chown -R runner:docker /var/www/html + ls -la /var/www/html + cd /var/www/html + wget https://wordpress.org/wordpress-${{ matrix.wp-versions }}.tar.gz + tar xfz wordpress-${{ matrix.wp-versions }}.tar.gz + mv wordpress/* . + rm -rf wordpress wordpress-${{ matrix.wp-versions }}.tar.gz + + # We install WP-CLI, as it provides useful commands to setup and install WordPress through the command line. + - name: Install WP-CLI + run: | + curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar + chmod +x wp-cli.phar + sudo mv wp-cli.phar /usr/local/bin/wp-cli + + - name: Setup wp-config.php + working-directory: ${{ env.ROOT_DIR }} + run: wp-cli config create --dbname=${{ env.DB_NAME }} --dbuser=${{ env.DB_USER }} --dbpass=${{ env.DB_PASS }} --dbhost=${{ env.DB_HOST }} --locale=en_DB + + - name: Install WordPress + working-directory: ${{ env.ROOT_DIR }} + run: wp-cli core install --url=127.0.0.1 --title=ConvertKit --admin_user=admin --admin_password=password --admin_email=wordpress@convertkit.local + + # Move Plugin + - name: Move Plugin + run: mv /home/runner/work/convertkit-wordpress/convertkit-wordpress/convertkit ${{ env.PLUGIN_DIR }} + + # WP_DEBUG = true is required so all PHP errors are output and caught by tests (E_ALL). + - name: Enable WP_DEBUG + working-directory: ${{ env.ROOT_DIR }} + run: | + wp-cli config set WP_DEBUG true --raw + + # FS_METHOD = direct is required for WP_Filesystem to operate without suppressed PHP fopen() errors that trip up tests. + - name: Enable FS_METHOD + working-directory: ${{ env.ROOT_DIR }} + run: | + wp-cli config set FS_METHOD direct + + # DISALLOW_FILE_MODS = true is required to disable the block directory's "Available to Install" suggestions, which trips up + # tests that search and wait for block results. + - name: Enable DISALLOW_FILE_MODS + working-directory: ${{ env.ROOT_DIR }} + run: | + wp-cli config set DISALLOW_FILE_MODS true --raw + + # This step is deliberately after WordPress installation and configuration, as enabling PHP 8.x before using WP-CLI results + # in the workflow failing due to incompatibilities between WP-CLI and PHP 8.x. + # By installing PHP at this stage, we can still run our tests against e.g. PHP 8.x. + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + coverage: xdebug + + # Configure nginx to use the PHP version and WOrdPress installation at /var/www/html + - name: Configure nginx site + run: | + sudo rm -f /etc/nginx/sites-enabled/default + sudo tee /etc/nginx/sites-available/default > /dev/null << 'EOF' + + server { + listen 80 default_server; + listen [::]:80 default_server; + + root /var/www/html; + index index.php; + + server_name localhost; + + location / { + try_files $uri $uri/ /index.php?$args; + } + + location ~ \.php$ { + include snippets/fastcgi-php.conf; + fastcgi_pass unix:/run/php/php${{ matrix.php-versions }}-fpm.sock; + + # Prevent 502 Bad Gateway error "upstream sent too big header while reading response header from upstream" + fastcgi_buffers 16 16k; + fastcgi_buffer_size 32k; + fastcgi_busy_buffers_size 64k; + } + + location ~ /\.ht { + deny all; + } + } + EOF + + sudo ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default || true + + - name: Test nginx + run: sudo nginx -t + + - name: Start nginx + run: sudo systemctl start nginx.service + + # Start chromedriver + - name: Start chromedriver + run: | + export DISPLAY=:99 + chromedriver --port=9515 --url-base=/wd/hub & + sudo Xvfb -ac :99 -screen 0 1920x1080x24 > /dev/null 2>&1 & # optional + + # Exchange API Keys and Secrets for OAuth Tokens. + - name: Exchange API Key and Secret for OAuth Tokens + id: get-oauth-tokens + run: | + response=$(curl -s -X POST "${{ secrets.CONVERTKIT_EXCHANGE_API_KEYS_ENDPOINT }}?api_key=${{ env.CONVERTKIT_API_KEY }}&api_secret=${{ env.CONVERTKIT_API_SECRET }}&client_id=${{ env.CONVERTKIT_OAUTH_CLIENT_ID }}&redirect_uri=${{ env.CONVERTKIT_OAUTH_REDIRECT_URI }}&tenant_name=github-actions-${{ steps.test-group.outputs.value }}-${{ matrix.php-versions }}") + access_token=$(echo "$response" | jq -r '.oauth.access_token') + refresh_token=$(echo "$response" | jq -r '.oauth.refresh_token') + echo "CONVERTKIT_OAUTH_ACCESS_TOKEN=$access_token" >> $GITHUB_ENV + echo "CONVERTKIT_OAUTH_REFRESH_TOKEN=$refresh_token" >> $GITHUB_ENV + response=$(curl -s -X POST "${{ secrets.CONVERTKIT_EXCHANGE_API_KEYS_ENDPOINT }}?api_key=${{ env.CONVERTKIT_API_KEY_NO_DATA }}&api_secret=${{ env.CONVERTKIT_API_SECRET_NO_DATA }}&client_id=${{ env.CONVERTKIT_OAUTH_CLIENT_ID }}&redirect_uri=${{ env.CONVERTKIT_OAUTH_REDIRECT_URI }}&tenant_name=github-actions-${{ steps.test-group.outputs.value }}-${{ matrix.php-versions }}") + access_token=$(echo "$response" | jq -r '.oauth.access_token') + refresh_token=$(echo "$response" | jq -r '.oauth.refresh_token') + echo "CONVERTKIT_OAUTH_ACCESS_TOKEN_NO_DATA=$access_token" >> $GITHUB_ENV + echo "CONVERTKIT_OAUTH_REFRESH_TOKEN_NO_DATA=$refresh_token" >> $GITHUB_ENV + + # Write any secrets, such as API keys, to the .env.testing file now. + - name: Define GitHub Secrets in .env.dist.testing + uses: DamianReeves/write-file-action@v1.3 + with: + path: ${{ env.PLUGIN_DIR }}/.env.testing + contents: | + WORDPRESS_V3_BLOCK_EDITOR_ENABLED=${{ env.WORDPRESS_V3_BLOCK_EDITOR_ENABLED }} + CONVERTKIT_API_KEY=${{ env.CONVERTKIT_API_KEY }} + CONVERTKIT_API_SECRET=${{ env.CONVERTKIT_API_SECRET }} + CONVERTKIT_API_KEY_NO_DATA=${{ env.CONVERTKIT_API_KEY_NO_DATA }} + CONVERTKIT_API_SECRET_NO_DATA=${{ env.CONVERTKIT_API_SECRET_NO_DATA }} + CONVERTKIT_OAUTH_ACCESS_TOKEN=${{ env.CONVERTKIT_OAUTH_ACCESS_TOKEN }} + CONVERTKIT_OAUTH_REFRESH_TOKEN=${{ env.CONVERTKIT_OAUTH_REFRESH_TOKEN }} + CONVERTKIT_OAUTH_ACCESS_TOKEN_NO_DATA=${{ env.CONVERTKIT_OAUTH_ACCESS_TOKEN_NO_DATA }} + CONVERTKIT_OAUTH_REFRESH_TOKEN_NO_DATA=${{ env.CONVERTKIT_OAUTH_REFRESH_TOKEN_NO_DATA }} + CONVERTKIT_OAUTH_CLIENT_ID=${{ env.CONVERTKIT_OAUTH_CLIENT_ID }} + CONVERTKIT_OAUTH_REDIRECT_URI=${{ env.CONVERTKIT_OAUTH_REDIRECT_URI }} + KIT_OAUTH_REDIRECT_URI=${{ env.KIT_OAUTH_REDIRECT_URI }} + CONVERTKIT_API_SIGNED_SUBSCRIBER_ID=${{ env.CONVERTKIT_API_SIGNED_SUBSCRIBER_ID }} + CONVERTKIT_API_SIGNED_SUBSCRIBER_ID_NO_ACCESS=${{ env.CONVERTKIT_API_SIGNED_SUBSCRIBER_ID_NO_ACCESS }} + CONVERTKIT_API_RECAPTCHA_SITE_KEY=${{ env.CONVERTKIT_API_RECAPTCHA_SITE_KEY }} + CONVERTKIT_API_RECAPTCHA_SECRET_KEY=${{ env.CONVERTKIT_API_RECAPTCHA_SECRET_KEY }} + + write-mode: overwrite + + # Installs wp-browser, Codeception, PHP CodeSniffer and anything else needed to run tests. + - name: Run Composer + working-directory: ${{ env.PLUGIN_DIR }} + run: composer update + + - name: Build PHP Autoloader + working-directory: ${{ env.PLUGIN_DIR }} + run: composer dump-autoload + + # This ensures that applicable files and folders can be written to by WordPress and cache Plugins. + - name: Set File and Folder Permissions + run: | + sudo chmod 767 ${{ env.ROOT_DIR }} + sudo chown www-data:www-data ${{ env.ROOT_DIR }} + + sudo chmod 767 ${{ env.ROOT_DIR }}/wp-config.php + sudo chown www-data:www-data ${{ env.ROOT_DIR }}/wp-config.php + + sudo chmod 767 ${{ env.ROOT_DIR }}/wp-content + sudo chown www-data:www-data ${{ env.ROOT_DIR }}/wp-content + + sudo chmod -R 767 ${{ env.ROOT_DIR }}/wp-content/uploads + sudo chown www-data:www-data ${{ env.ROOT_DIR }}/wp-content/uploads + + # This ensures the Plugin's log file can be written to. + # We don't recursively do this, as it'll prevent Codeception from writing to the /tests/_output directory. + - name: Set Permissions for Plugin Directory + run: | + sudo chmod g+w ${{ env.PLUGIN_DIR }} + sudo chown www-data:www-data ${{ env.PLUGIN_DIR }} + + # Build Codeception Tests. + - name: Build Tests + working-directory: ${{ env.PLUGIN_DIR }} + run: php vendor/bin/codecept build + + # Run Codeception Tests. + - name: Run tests/${{ matrix.test-groups }} + working-directory: ${{ env.PLUGIN_DIR }} + run: php vendor/bin/codecept run tests/${{ matrix.test-groups }} --fail-fast + + # Artifacts are data generated by this workflow that we want to access, such as log files, screenshots, HTML output. + # The if: failure() directive means that this will run when the workflow fails e.g. if a test fails, which is needed + # because we want to see why a test failed. + - name: Upload nginx Error Log to Artifact + if: failure() + uses: actions/upload-artifact@v4 + with: + name: nginx-error-log-${{ steps.test-group.outputs.value }}-${{ matrix.php-versions }}.log + path: /var/log/nginx/error.log + + - name: Upload Test Results to Artifact + if: failure() + uses: actions/upload-artifact@v4 + with: + name: test-results-${{ steps.test-group.outputs.value }}-${{ matrix.php-versions }} + path: ${{ env.PLUGIN_DIR }}/tests/_output/ + + - name: Upload Plugin Log File to Artifact + if: failure() + uses: actions/upload-artifact@v4 + with: + name: log-${{ steps.test-group.outputs.value }}-${{ matrix.php-versions }}.txt + path: ${{ env.PLUGIN_DIR }}/log/log.txt \ No newline at end of file diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ec742687a..f9d8e6b80 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -30,6 +30,7 @@ jobs: DB_USER: root DB_PASS: root DB_HOST: localhost + WORDPRESS_V3_BLOCK_EDITOR_ENABLED: true INSTALL_PLUGINS: "admin-menu-editor autoptimize beaver-builder-lite-version block-visibility contact-form-7 classic-editor custom-post-type-ui debloat elementor forminator jetpack-boost mailchimp-for-wp rocket-lazy-load woocommerce wordpress-seo wpforms-lite litespeed-cache wp-crontrol wp-super-cache w3-total-cache wp-fastest-cache wp-optimize sg-cachepress" # Don't include this repository's Plugin here. INSTALL_PLUGINS_URLS: "https://downloads.wordpress.org/plugin/convertkit-for-woocommerce.1.6.4.zip http://cktestplugins.wpengine.com/wp-content/uploads/2024/01/convertkit-action-filter-tests.zip http://cktestplugins.wpengine.com/wp-content/uploads/2024/11/disable-doing-it-wrong-notices.zip http://cktestplugins.wpengine.com/wp-content/uploads/2025/03/uncode-js_composer.7.8.zip http://cktestplugins.wpengine.com/wp-content/uploads/2025/03/uncode-core.zip" # URLs to specific third party Plugins INSTALL_THEMES_URLS: "http://cktestplugins.wpengine.com/wp-content/uploads/2025/03/uncode.zip http://cktestplugins.wpengine.com/wp-content/uploads/2025/04/Divi.zip" @@ -265,6 +266,7 @@ jobs: with: path: ${{ env.PLUGIN_DIR }}/.env.testing contents: | + WORDPRESS_V3_BLOCK_EDITOR_ENABLED=${{ env.WORDPRESS_V3_BLOCK_EDITOR_ENABLED }} CONVERTKIT_API_KEY=${{ env.CONVERTKIT_API_KEY }} CONVERTKIT_API_SECRET=${{ env.CONVERTKIT_API_SECRET }} CONVERTKIT_API_KEY_NO_DATA=${{ env.CONVERTKIT_API_KEY_NO_DATA }} diff --git a/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormBuilderCest.php b/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormBuilderCest.php index a217b829a..0d546023e 100644 --- a/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormBuilderCest.php +++ b/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormBuilderCest.php @@ -130,7 +130,7 @@ public function testFormBuilderBlockWithDefaultConfiguration(EndToEndTester $I) fieldID: 'first_name', label: 'First name', container: 'div.wp-block-convertkit-form-builder', - switchToGutenbergEditor: false + isFrontend: true ); $this->seeFormBuilderField( $I, @@ -139,7 +139,7 @@ public function testFormBuilderBlockWithDefaultConfiguration(EndToEndTester $I) fieldID: 'email', label: 'Email address', container: 'div.wp-block-convertkit-form-builder', - switchToGutenbergEditor: false + isFrontend: true ); // Generate email address for this test. @@ -250,7 +250,7 @@ public function testFormBuilderBlockWithTextCustomization(EndToEndTester $I) fieldID: 'first_name', label: 'Nafnið þitt', container: 'div.wp-block-convertkit-form-builder', - switchToGutenbergEditor: false + isFrontend: true ); $this->seeFormBuilderField( $I, @@ -259,7 +259,7 @@ public function testFormBuilderBlockWithTextCustomization(EndToEndTester $I) fieldID: 'email', label: 'Netfangið þitt', container: 'div.wp-block-convertkit-form-builder', - switchToGutenbergEditor: false + isFrontend: true ); // Generate email address for this test. @@ -353,7 +353,7 @@ public function testFormBuilderBlockWithFormEnabled(EndToEndTester $I) fieldID: 'first_name', label: 'First name', container: 'div.wp-block-convertkit-form-builder', - switchToGutenbergEditor: false + isFrontend: true ); $this->seeFormBuilderField( $I, @@ -362,7 +362,7 @@ public function testFormBuilderBlockWithFormEnabled(EndToEndTester $I) fieldID: 'email', label: 'Email address', container: 'div.wp-block-convertkit-form-builder', - switchToGutenbergEditor: false + isFrontend: true ); // Generate email address for this test. @@ -461,7 +461,7 @@ public function testFormBuilderBlockWithTaggingEnabled(EndToEndTester $I) fieldID: 'first_name', label: 'First name', container: 'div.wp-block-convertkit-form-builder', - switchToGutenbergEditor: false + isFrontend: true ); $this->seeFormBuilderField( $I, @@ -470,7 +470,7 @@ public function testFormBuilderBlockWithTaggingEnabled(EndToEndTester $I) fieldID: 'email', label: 'Email address', container: 'div.wp-block-convertkit-form-builder', - switchToGutenbergEditor: false + isFrontend: true ); // Generate email address for this test. @@ -568,7 +568,7 @@ public function testFormBuilderBlockWithSequenceEnabled(EndToEndTester $I) fieldID: 'first_name', label: 'First name', container: 'div.wp-block-convertkit-form-builder', - switchToGutenbergEditor: false + isFrontend: true ); $this->seeFormBuilderField( $I, @@ -577,7 +577,7 @@ public function testFormBuilderBlockWithSequenceEnabled(EndToEndTester $I) fieldID: 'email', label: 'Email address', container: 'div.wp-block-convertkit-form-builder', - switchToGutenbergEditor: false + isFrontend: true ); // Generate email address for this test. @@ -692,7 +692,7 @@ public function testFormBuilderBlockWithCustomField(EndToEndTester $I) fieldID: 'first_name', label: 'First name', container: 'div.wp-block-convertkit-form-builder', - switchToGutenbergEditor: false + isFrontend: true ); $this->seeFormBuilderField( $I, @@ -701,7 +701,7 @@ public function testFormBuilderBlockWithCustomField(EndToEndTester $I) fieldID: 'email', label: 'Email address', container: 'div.wp-block-convertkit-form-builder', - switchToGutenbergEditor: false + isFrontend: true ); foreach ( $customFields as $key => $field ) { $this->seeFormBuilderField( @@ -711,7 +711,7 @@ public function testFormBuilderBlockWithCustomField(EndToEndTester $I) fieldID: 'custom_fields_' . $key, label: $field['label'], container: 'div.wp-block-convertkit-form-builder', - switchToGutenbergEditor: false + isFrontend: true ); } @@ -810,7 +810,7 @@ public function testFormBuilderBlockWithRedirectOption(EndToEndTester $I) fieldID: 'first_name', label: 'First name', container: 'div.wp-block-convertkit-form-builder', - switchToGutenbergEditor: false + isFrontend: true ); $this->seeFormBuilderField( $I, @@ -819,7 +819,7 @@ public function testFormBuilderBlockWithRedirectOption(EndToEndTester $I) fieldID: 'email', label: 'Email address', container: 'div.wp-block-convertkit-form-builder', - switchToGutenbergEditor: false + isFrontend: true ); // Generate email address for this test. @@ -1262,19 +1262,18 @@ public function _passed(EndToEndTester $I) * @since 3.0.0 * * @param EndToEndTester $I Tester. - * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame. */ - private function seeFormBuilderBlock(EndToEndTester $I, $switchToGutenbergEditor = true) + private function seeFormBuilderBlock(EndToEndTester $I) { // Switch to the Gutenberg IFrame. - if ($switchToGutenbergEditor) { - $I->switchToGutenbergEditor($I); + if ($I->isGutenbergIFrameEditorEnabled()) { + $I->switchToGutenbergIFrameEditor($I); } $I->seeElementInDOM('div[data-type="convertkit/form-builder"]'); // Switch back to main window. - if ($switchToGutenbergEditor) { + if ($I->isGutenbergIFrameEditorEnabled()) { $I->switchToIFrame(); } } @@ -1285,19 +1284,18 @@ private function seeFormBuilderBlock(EndToEndTester $I, $switchToGutenbergEditor * @since 3.0.0 * * @param EndToEndTester $I Tester. - * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame. */ - private function seeFormBuilderButtonBlock(EndToEndTester $I, $switchToGutenbergEditor = true) + private function seeFormBuilderButtonBlock(EndToEndTester $I) { // Switch to the Gutenberg IFrame. - if ($switchToGutenbergEditor) { - $I->switchToGutenbergEditor($I); + if ($I->isGutenbergIFrameEditorEnabled()) { + $I->switchToGutenbergIFrameEditor($I); } $I->seeElementInDOM('div[data-type="convertkit/form-builder"] div[data-type="core/button"]'); // Switch back to main window. - if ($switchToGutenbergEditor) { + if ($I->isGutenbergIFrameEditorEnabled()) { $I->switchToIFrame(); } } @@ -1314,13 +1312,13 @@ private function seeFormBuilderButtonBlock(EndToEndTester $I, $switchToGutenberg * @param string $label Field label. * @param bool $required Whether the field should be marked `required`. * @param string $container The container the field should be in. - * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame. + * @param bool $isFrontend Whether the field is being tested in the frontend. */ - private function seeFormBuilderField(EndToEndTester $I, $fieldType, $fieldName, $fieldID, $label, $required = true, $container = 'div', $switchToGutenbergEditor = true) + private function seeFormBuilderField(EndToEndTester $I, $fieldType, $fieldName, $fieldID, $label, $required = true, $container = 'div', $isFrontend = false) { // Switch to the Gutenberg IFrame. - if ($switchToGutenbergEditor) { - $I->switchToGutenbergEditor($I); + if ( ! $isFrontend && $I->isGutenbergIFrameEditorEnabled()) { + $I->switchToGutenbergIFrameEditor($I); } // Check field exists with correct attributes. @@ -1342,7 +1340,7 @@ private function seeFormBuilderField(EndToEndTester $I, $fieldType, $fieldName, } // Switch back to main window. - if ($switchToGutenbergEditor) { + if ( ! $isFrontend && $I->isGutenbergIFrameEditorEnabled()) { $I->switchToIFrame(); } } diff --git a/tests/Support/Helper/DiviBuilder.php b/tests/Support/Helper/DiviBuilder.php index 7568e6db4..5c7ff3402 100644 --- a/tests/Support/Helper/DiviBuilder.php +++ b/tests/Support/Helper/DiviBuilder.php @@ -83,13 +83,14 @@ public function createDiviPageInBackendEditor($I, $title) public function createDiviPageInFrontendEditor($I, $title, $configureMetaBox = true) { // Add a Page using the Gutenberg editor. - // Don't switch to the Gutenberg IFrame, as we're using the Divi Builder, which won't use the iframe. - $I->addGutenbergPage( - $I, - postType: 'page', - title: $title, - switchToGutenbergEditor: false - ); + // We don't use addGutenbergPage(), as when the Divi Builder is used, the iframed Gutenberg editor is not used, + // and addGutenbergPage() may switch to an iframe based on the value of the WORDPRESS_V3_BLOCK_EDITOR_ENABLED environment variable. + // Navigate to Post Type (e.g. Pages / Posts) > Add New. + $I->amOnAdminPage('post-new.php?post_type=page'); + $I->waitForElementVisible('body.post-new-php'); + + // Define the Title. + $I->fillField('.editor-post-title__input', $title); // Configure metabox's Form setting = None, ensuring we only test the block in Gutenberg. if ($configureMetaBox) { diff --git a/tests/Support/Helper/KitPlugin.php b/tests/Support/Helper/KitPlugin.php index ed836c367..7259c75c2 100644 --- a/tests/Support/Helper/KitPlugin.php +++ b/tests/Support/Helper/KitPlugin.php @@ -774,20 +774,18 @@ public function checkSelectOptionOrder($I, $selectElement, $values) * @param EndToEndTester $I Tester. * @param string $blockName Block Name. * @param bool|string $expectedMessage Expected message displayed in block after valid OAuth tokens are specified. - * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame. */ - public function testBlockNoCredentialsPopupWindow($I, $blockName, $expectedMessage = false, $switchToGutenbergEditor = true) + public function testBlockNoCredentialsPopupWindow($I, $blockName, $expectedMessage = false) { // Confirm that the Form block displays instructions to the user on how to enter their API Key. $I->seeBlockHasNoContentMessage( $I, - message: 'Not connected to Kit.', - switchToGutenbergEditor: $switchToGutenbergEditor + message: 'Not connected to Kit.' ); // Switch to the Gutenberg IFrame. - if ($switchToGutenbergEditor) { - $I->switchToGutenbergEditor($I); + if ($I->isGutenbergIFrameEditorEnabled()) { + $I->switchToGutenbergIFrameEditor($I); } // Click the link to confirm it loads the Plugin's setup wizard. @@ -811,8 +809,8 @@ public function testBlockNoCredentialsPopupWindow($I, $blockName, $expectedMessa $I->closeTab(); // Switch to the Gutenberg IFrame. - if ($switchToGutenbergEditor) { - $I->switchToGutenbergEditor($I); + if ($I->isGutenbergIFrameEditorEnabled()) { + $I->switchToGutenbergIFrameEditor($I); } // Wait until the block changes to refreshing. @@ -823,7 +821,7 @@ public function testBlockNoCredentialsPopupWindow($I, $blockName, $expectedMessa $I->waitForElementNotVisible('div.convertkit-no-content button.wp-convertkit-refresh-resources', 30); // Switch back to main window. - if ($switchToGutenbergEditor) { + if ($I->isGutenbergIFrameEditorEnabled()) { $I->switchToIFrame(); } @@ -831,8 +829,7 @@ public function testBlockNoCredentialsPopupWindow($I, $blockName, $expectedMessa if ($expectedMessage) { $I->seeBlockHasNoContentMessage( $I, - message: $expectedMessage, - switchToGutenbergEditor: $switchToGutenbergEditor + message: $expectedMessage ); } } @@ -843,13 +840,12 @@ public function testBlockNoCredentialsPopupWindow($I, $blockName, $expectedMessa * @since 2.7.7 * * @param EndToEndTester $I EndToEndTester. - * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame. */ - public function clickBlockRefreshButton($I, $switchToGutenbergEditor = true) + public function clickBlockRefreshButton($I) { // Switch to the Gutenberg IFrame. - if ($switchToGutenbergEditor) { - $I->switchToGutenbergEditor($I); + if ($I->isGutenbergIFrameEditorEnabled()) { + $I->switchToGutenbergIFrameEditor($I); } // Click the refresh button. @@ -859,7 +855,7 @@ public function clickBlockRefreshButton($I, $switchToGutenbergEditor = true) $I->waitForElementNotVisible('div.convertkit-no-content button.wp-convertkit-refresh-resources'); // Switch back to main window. - if ($switchToGutenbergEditor) { + if ($I->isGutenbergIFrameEditorEnabled()) { $I->switchToIFrame(); } } @@ -871,13 +867,12 @@ public function clickBlockRefreshButton($I, $switchToGutenbergEditor = true) * * @param EndToEndTester $I EndToEndTester. * @param string $message Message. - * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame. */ - public function seeBlockHasNoContentMessage($I, $message, $switchToGutenbergEditor = true) + public function seeBlockHasNoContentMessage($I, $message) { // Switch to the Gutenberg IFrame. - if ($switchToGutenbergEditor) { - $I->switchToGutenbergEditor($I); + if ($I->isGutenbergIFrameEditorEnabled()) { + $I->switchToGutenbergIFrameEditor($I); } $I->see( @@ -888,7 +883,7 @@ public function seeBlockHasNoContentMessage($I, $message, $switchToGutenbergEdit ); // Switch back to main window. - if ($switchToGutenbergEditor) { + if ($I->isGutenbergIFrameEditorEnabled()) { $I->switchToIFrame(); } } @@ -901,13 +896,12 @@ public function seeBlockHasNoContentMessage($I, $message, $switchToGutenbergEdit * * @param EndToEndTester $I EndToEndTester. * @param string $linkText Link text. - * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame. */ - public function clickLinkInBlockAndAssertKitLoginScreen($I, $linkText, $switchToGutenbergEditor = true) + public function clickLinkInBlockAndAssertKitLoginScreen($I, $linkText) { // Switch to the Gutenberg IFrame. - if ($switchToGutenbergEditor) { - $I->switchToGutenbergEditor($I); + if ($I->isGutenbergIFrameEditorEnabled()) { + $I->switchToGutenbergIFrameEditor($I); } $I->click( @@ -927,7 +921,7 @@ public function clickLinkInBlockAndAssertKitLoginScreen($I, $linkText, $switchTo $I->closeTab(); // Switch back to main window. - if ($switchToGutenbergEditor) { + if ($I->isGutenbergIFrameEditorEnabled()) { $I->switchToIFrame(); } } @@ -939,13 +933,12 @@ public function clickLinkInBlockAndAssertKitLoginScreen($I, $linkText, $switchTo * * @param EndToEndTester $I EndToEndTester. * @param string $message Message. - * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame. */ - public function seeFormBlockIFrameHasMessage($I, $message, $switchToGutenbergEditor = true) + public function seeFormBlockIFrameHasMessage($I, $message) { // Switch to the Gutenberg IFrame. - if ($switchToGutenbergEditor) { - $I->switchToGutenbergEditor($I); + if ($I->isGutenbergIFrameEditorEnabled()) { + $I->switchToGutenbergIFrameEditor($I); } // Switch to iframe preview for the Form block. @@ -1008,13 +1001,12 @@ public function dontSeeCreatorNetworkRecommendationsScript($I, $pageID) * * @param EndToEndTester $I EndToEnd Tester. * @param string $selector CSS or ID selector for the input element. - * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame. */ - public function selectAllText($I, $selector, $switchToGutenbergEditor = true) + public function selectAllText($I, $selector) { // Switch to the Gutenberg IFrame. - if ($switchToGutenbergEditor) { - $I->switchToGutenbergEditor($I); + if ($I->isGutenbergIFrameEditorEnabled()) { + $I->switchToGutenbergIFrameEditor($I); } // Determine whether to use the control or command key, depending on the OS. @@ -1029,7 +1021,7 @@ public function selectAllText($I, $selector, $switchToGutenbergEditor = true) $I->pressKey($selector, array( $key, 'a' )); // Switch back to main window. - if ($switchToGutenbergEditor) { + if ($I->isGutenbergIFrameEditorEnabled()) { $I->switchToIFrame(); } } diff --git a/tests/Support/Helper/WPGutenberg.php b/tests/Support/Helper/WPGutenberg.php index 2f826ddab..8831acc56 100644 --- a/tests/Support/Helper/WPGutenberg.php +++ b/tests/Support/Helper/WPGutenberg.php @@ -9,6 +9,19 @@ */ class WPGutenberg extends \Codeception\Module { + /** + * Helper method to determine if the Gutenberg IFrame editor is enabled + * in tests by inspecting the WORDPRESS_V3_BLOCK_EDITOR_ENABLED environment variable. + * + * @since 3.1.4 + * + * @return bool + */ + public function isGutenbergIFrameEditorEnabled() + { + return filter_var($_ENV['WORDPRESS_V3_BLOCK_EDITOR_ENABLED'], FILTER_VALIDATE_BOOLEAN); + } + /** * Helper method to switch to the Gutenberg editor Iframe * when all blocks use the Block API v3: @@ -18,7 +31,7 @@ class WPGutenberg extends \Codeception\Module * * @param EndToEndTester $I EndToEnd Tester. */ - public function switchToGutenbergEditor($I) + public function switchToGutenbergIFrameEditor($I) { $I->switchToIFrame('iframe[name="editor-canvas"]'); } @@ -31,24 +44,23 @@ public function switchToGutenbergEditor($I) * @param EndToEndTester $I EndToEnd Tester. * @param string $postType Post Type. * @param string $title Post Title. - * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame (i.e if all blocks use apiVersion 3). */ - public function addGutenbergPage($I, $postType = 'page', $title = 'Gutenberg Title', $switchToGutenbergEditor = true) + public function addGutenbergPage($I, $postType = 'page', $title = 'Gutenberg Title') { // Navigate to Post Type (e.g. Pages / Posts) > Add New. $I->amOnAdminPage('post-new.php?post_type=' . $postType); $I->waitForElementVisible('body.post-new-php'); // Switch to the Gutenberg IFrame. - if ($switchToGutenbergEditor) { - $I->switchToGutenbergEditor($I); + if ($this->isGutenbergIFrameEditorEnabled()) { + $I->switchToGutenbergIFrameEditor($I); } // Define the Title. $I->fillField('.editor-post-title__input', $title); // Switch back to main window. - if ($switchToGutenbergEditor) { + if ($this->isGutenbergIFrameEditorEnabled()) { $I->switchToIFrame(); } } @@ -153,16 +165,15 @@ public function addGutenbergBlock($I, $blockName, $blockProgrammaticName, $block * * @param EndToEndTester $I EndToEnd Tester. * @param string $text Paragraph Text. - * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame. */ - public function addGutenbergParagraphBlock($I, $text, $switchToGutenbergEditor = true) + public function addGutenbergParagraphBlock($I, $text) { // Add paragraph block. $I->addGutenbergBlock($I, 'Paragraph', 'paragraph/paragraph'); // Switch to the Gutenberg IFrame. - if ($switchToGutenbergEditor) { - $I->switchToGutenbergEditor($I); + if ($this->isGutenbergIFrameEditorEnabled()) { + $I->switchToGutenbergIFrameEditor($I); } // Click the editor area and enter the text in the paragraph. @@ -170,7 +181,7 @@ public function addGutenbergParagraphBlock($I, $text, $switchToGutenbergEditor = $I->fillField('.wp-block-post-content p[data-empty="true"]', $text); // Switch back to main window. - if ($switchToGutenbergEditor) { + if ($this->isGutenbergIFrameEditorEnabled()) { $I->switchToIFrame(); } } @@ -281,17 +292,16 @@ private function insertGutenbergLink($I, $name) * * @param EndToEndTester $I EndToEnd Tester. * @param string $blockProgrammaticName Programmatic Block Name (e.g. 'convertkit/form-builder-field-name'). - * @param bool $switchToGutenbergEditor Switch to the Gutenberg IFrame. */ - public function selectGutenbergBlockInEditor($I, $blockProgrammaticName, $switchToGutenbergEditor = true) + public function selectGutenbergBlockInEditor($I, $blockProgrammaticName) { - if ($switchToGutenbergEditor) { - $I->switchToGutenbergEditor($I); + if ($this->isGutenbergIFrameEditorEnabled()) { + $I->switchToGutenbergIFrameEditor($I); } $I->click('div[data-type="' . $blockProgrammaticName . '"]'); - if ($switchToGutenbergEditor) { + if ($this->isGutenbergIFrameEditorEnabled()) { $I->switchToIFrame(); } } From 76246d47d9aaab1c62324d0dfda0197eb6d3cd97 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Tue, 6 Jan 2026 16:11:52 +0800 Subject: [PATCH 14/19] Tests: Revert spacing on docblocks --- .../PageBlockFormBuilderCest.php | 8 ++--- tests/Support/Helper/KitPlugin.php | 34 ++++++++----------- tests/Support/Helper/WPGutenberg.php | 10 +++--- 3 files changed, 23 insertions(+), 29 deletions(-) diff --git a/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormBuilderCest.php b/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormBuilderCest.php index 0d546023e..3ba66bd14 100644 --- a/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormBuilderCest.php +++ b/tests/EndToEnd/forms/blocks-shortcodes/PageBlockFormBuilderCest.php @@ -1261,7 +1261,7 @@ public function _passed(EndToEndTester $I) * * @since 3.0.0 * - * @param EndToEndTester $I Tester. + * @param EndToEndTester $I Tester. */ private function seeFormBuilderBlock(EndToEndTester $I) { @@ -1283,7 +1283,7 @@ private function seeFormBuilderBlock(EndToEndTester $I) * * @since 3.0.0 * - * @param EndToEndTester $I Tester. + * @param EndToEndTester $I Tester. */ private function seeFormBuilderButtonBlock(EndToEndTester $I) { @@ -1350,8 +1350,8 @@ private function seeFormBuilderField(EndToEndTester $I, $fieldType, $fieldName, * * @since 3.0.0 * - * @param EndToEndTester $I Tester. - * @param string $text The text to check for in the submit button. + * @param EndToEndTester $I Tester. + * @param string $text The text to check for in the submit button. */ private function seeFormBuilderSubmitButton(EndToEndTester $I, $text) { diff --git a/tests/Support/Helper/KitPlugin.php b/tests/Support/Helper/KitPlugin.php index 7259c75c2..ad03bec12 100644 --- a/tests/Support/Helper/KitPlugin.php +++ b/tests/Support/Helper/KitPlugin.php @@ -771,17 +771,14 @@ public function checkSelectOptionOrder($I, $selectElement, $values) * * @since 2.2.6 * - * @param EndToEndTester $I Tester. - * @param string $blockName Block Name. - * @param bool|string $expectedMessage Expected message displayed in block after valid OAuth tokens are specified. + * @param EndToEndTester $I Tester. + * @param string $blockName Block Name. + * @param bool|string $expectedMessage Expected message displayed in block after valid OAuth tokens are specified. */ public function testBlockNoCredentialsPopupWindow($I, $blockName, $expectedMessage = false) { // Confirm that the Form block displays instructions to the user on how to enter their API Key. - $I->seeBlockHasNoContentMessage( - $I, - message: 'Not connected to Kit.' - ); + $I->seeBlockHasNoContentMessage($I, 'Not connected to Kit.'); // Switch to the Gutenberg IFrame. if ($I->isGutenbergIFrameEditorEnabled()) { @@ -827,10 +824,7 @@ public function testBlockNoCredentialsPopupWindow($I, $blockName, $expectedMessa // Confirm that the block displays the expected message. if ($expectedMessage) { - $I->seeBlockHasNoContentMessage( - $I, - message: $expectedMessage - ); + $I->seeBlockHasNoContentMessage($I, $expectedMessage); } } @@ -839,7 +833,7 @@ public function testBlockNoCredentialsPopupWindow($I, $blockName, $expectedMessa * * @since 2.7.7 * - * @param EndToEndTester $I EndToEndTester. + * @param EndToEndTester $I EndToEndTester. */ public function clickBlockRefreshButton($I) { @@ -865,8 +859,8 @@ public function clickBlockRefreshButton($I) * * @since 2.7.7 * - * @param EndToEndTester $I EndToEndTester. - * @param string $message Message. + * @param EndToEndTester $I EndToEndTester. + * @param string $message Message. */ public function seeBlockHasNoContentMessage($I, $message) { @@ -894,8 +888,8 @@ public function seeBlockHasNoContentMessage($I, $message) * * @since 2.7.7 * - * @param EndToEndTester $I EndToEndTester. - * @param string $linkText Link text. + * @param EndToEndTester $I EndToEndTester. + * @param string $linkText Link text. */ public function clickLinkInBlockAndAssertKitLoginScreen($I, $linkText) { @@ -931,8 +925,8 @@ public function clickLinkInBlockAndAssertKitLoginScreen($I, $linkText) * * @since 2.7.7 * - * @param EndToEndTester $I EndToEndTester. - * @param string $message Message. + * @param EndToEndTester $I EndToEndTester. + * @param string $message Message. */ public function seeFormBlockIFrameHasMessage($I, $message) { @@ -999,8 +993,8 @@ public function dontSeeCreatorNetworkRecommendationsScript($I, $pageID) * * @since 2.2.0 * - * @param EndToEndTester $I EndToEnd Tester. - * @param string $selector CSS or ID selector for the input element. + * @param EndToEndTester $I EndToEnd Tester. + * @param string $selector CSS or ID selector for the input element. */ public function selectAllText($I, $selector) { diff --git a/tests/Support/Helper/WPGutenberg.php b/tests/Support/Helper/WPGutenberg.php index 8831acc56..e1b73dcc9 100644 --- a/tests/Support/Helper/WPGutenberg.php +++ b/tests/Support/Helper/WPGutenberg.php @@ -41,9 +41,9 @@ public function switchToGutenbergIFrameEditor($I) * * @since 1.9.7.5 * - * @param EndToEndTester $I EndToEnd Tester. - * @param string $postType Post Type. - * @param string $title Post Title. + * @param EndToEndTester $I EndToEnd Tester. + * @param string $postType Post Type. + * @param string $title Post Title. */ public function addGutenbergPage($I, $postType = 'page', $title = 'Gutenberg Title') { @@ -163,8 +163,8 @@ public function addGutenbergBlock($I, $blockName, $blockProgrammaticName, $block * * @since 2.0.0 * - * @param EndToEndTester $I EndToEnd Tester. - * @param string $text Paragraph Text. + * @param EndToEndTester $I EndToEnd Tester. + * @param string $text Paragraph Text. */ public function addGutenbergParagraphBlock($I, $text) { From c1184f7e380b5e74972f0bc4ad456b21bbbf2ae6 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Tue, 6 Jan 2026 16:24:23 +0800 Subject: [PATCH 15/19] GitHub Actions: Use specific dump.sql depending on test suite --- .env.example | 8 + .github/workflows/tests-backward-compat.yml | 4 +- .github/workflows/tests.yml | 2 + TESTING.md | 23 ++ tests/EndToEnd.suite.yml | 2 +- tests/Support/Data/dump-6.2.8.sql | 355 ++++++++++++++++++++ 6 files changed, 392 insertions(+), 2 deletions(-) create mode 100644 tests/Support/Data/dump-6.2.8.sql diff --git a/.env.example b/.env.example index e63441941..7b919f2e8 100644 --- a/.env.example +++ b/.env.example @@ -4,6 +4,14 @@ WORDPRESS_ROOT_DIR="/Users/tim/Local Sites/convertkit-github/app/public" # Local site URL WORDPRESS_URL=http://kit.local +# Local site DB SQL dump file +# Set to `tests/Support/Data/dump-6.2.8.sql` when testing in WordPress 6.2.8 or older i.e. to test apiVersion 2 blocks +WORDPRESS_DB_SQL_DUMP_FILE="tests/Support/Data/dump.sql" + +# Use apiVersion 3 of the block editor +# Set to `false` when testing in WordPress 6.2.8 or older i.e. to test apiVersion 2 blocks +WORDPRESS_V3_BLOCK_EDITOR_ENABLED=true + # Kit credentials CONVERTKIT_OAUTH_ACCESS_TOKEN= CONVERTKIT_OAUTH_REFRESH_TOKEN= diff --git a/.github/workflows/tests-backward-compat.yml b/.github/workflows/tests-backward-compat.yml index ced780c0e..eaf55f6eb 100644 --- a/.github/workflows/tests-backward-compat.yml +++ b/.github/workflows/tests-backward-compat.yml @@ -1,4 +1,4 @@ -name: Run Tests +name: Run Backward Compat. Tests # When to run tests. on: @@ -30,6 +30,7 @@ jobs: DB_PASS: root DB_HOST: localhost WORDPRESS_V3_BLOCK_EDITOR_ENABLED: false # Test apiVersion 2 blocks against WordPress 6.2.8 + WORDPRESS_DB_SQL_DUMP_FILE: tests/Support/Data/dump-6.2.8.sql # Used to populate the test site database for WordPress 6.2.8 CONVERTKIT_API_KEY: ${{ secrets.CONVERTKIT_API_KEY }} # ConvertKit API Key, stored in the repository's Settings > Secrets CONVERTKIT_API_SECRET: ${{ secrets.CONVERTKIT_API_SECRET }} # ConvertKit API Secret, stored in the repository's Settings > Secrets CONVERTKIT_API_KEY_NO_DATA: ${{ secrets.CONVERTKIT_API_KEY_NO_DATA }} # ConvertKit API Key for ConvertKit account with no data, stored in the repository's Settings > Secrets @@ -221,6 +222,7 @@ jobs: path: ${{ env.PLUGIN_DIR }}/.env.testing contents: | WORDPRESS_V3_BLOCK_EDITOR_ENABLED=${{ env.WORDPRESS_V3_BLOCK_EDITOR_ENABLED }} + WORDPRESS_DB_SQL_DUMP_FILE=${{ env.WORDPRESS_DB_SQL_DUMP_FILE }} CONVERTKIT_API_KEY=${{ env.CONVERTKIT_API_KEY }} CONVERTKIT_API_SECRET=${{ env.CONVERTKIT_API_SECRET }} CONVERTKIT_API_KEY_NO_DATA=${{ env.CONVERTKIT_API_KEY_NO_DATA }} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f9d8e6b80..704de67b6 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -31,6 +31,7 @@ jobs: DB_PASS: root DB_HOST: localhost WORDPRESS_V3_BLOCK_EDITOR_ENABLED: true + WORDPRESS_DB_SQL_DUMP_FILE: tests/Support/Data/dump.sql INSTALL_PLUGINS: "admin-menu-editor autoptimize beaver-builder-lite-version block-visibility contact-form-7 classic-editor custom-post-type-ui debloat elementor forminator jetpack-boost mailchimp-for-wp rocket-lazy-load woocommerce wordpress-seo wpforms-lite litespeed-cache wp-crontrol wp-super-cache w3-total-cache wp-fastest-cache wp-optimize sg-cachepress" # Don't include this repository's Plugin here. INSTALL_PLUGINS_URLS: "https://downloads.wordpress.org/plugin/convertkit-for-woocommerce.1.6.4.zip http://cktestplugins.wpengine.com/wp-content/uploads/2024/01/convertkit-action-filter-tests.zip http://cktestplugins.wpengine.com/wp-content/uploads/2024/11/disable-doing-it-wrong-notices.zip http://cktestplugins.wpengine.com/wp-content/uploads/2025/03/uncode-js_composer.7.8.zip http://cktestplugins.wpengine.com/wp-content/uploads/2025/03/uncode-core.zip" # URLs to specific third party Plugins INSTALL_THEMES_URLS: "http://cktestplugins.wpengine.com/wp-content/uploads/2025/03/uncode.zip http://cktestplugins.wpengine.com/wp-content/uploads/2025/04/Divi.zip" @@ -267,6 +268,7 @@ jobs: path: ${{ env.PLUGIN_DIR }}/.env.testing contents: | WORDPRESS_V3_BLOCK_EDITOR_ENABLED=${{ env.WORDPRESS_V3_BLOCK_EDITOR_ENABLED }} + WORDPRESS_DB_SQL_DUMP_FILE=${{ env.WORDPRESS_DB_SQL_DUMP_FILE }} CONVERTKIT_API_KEY=${{ env.CONVERTKIT_API_KEY }} CONVERTKIT_API_SECRET=${{ env.CONVERTKIT_API_SECRET }} CONVERTKIT_API_KEY_NO_DATA=${{ env.CONVERTKIT_API_KEY_NO_DATA }} diff --git a/TESTING.md b/TESTING.md index 14d732985..2577f28f0 100644 --- a/TESTING.md +++ b/TESTING.md @@ -339,6 +339,29 @@ the Helper's namespace and class under the `enabled` section. Need to change how Codeception runs? Edit the [codeception.dist.xml](codeception.dist.xml) file. +## Block Testing + +To locally test that Kit Blocks are compatible with apiVersion 2, use the following configuration in `.env.testing`: + +| Environment Variable | Value | +|----------------------|-------| +| `WORDPRESS_DB_SQL_DUMP_FILE` | `tests/Support/Data/dump-6.2.8.sql` | +| `WORDPRESS_V3_BLOCK_EDITOR_ENABLED` | `false` | + +To locally test that Kit Blocks are compatible with apiVersion 3, use the following configuration in `.env.testing`: + +| Environment Variable | Value | +|----------------------|-------| +| `WORDPRESS_DB_SQL_DUMP_FILE` | `tests/Support/Data/dump.sql` | +| `WORDPRESS_V3_BLOCK_EDITOR_ENABLED` | `true` | + +GitHub Actions are configured to automatically configure the hosted runner with the applicable SQL dump file and block editor version: + +| Workflow File | Description | +|---------------|-------------| +| `tests-backward-compat.yml` | Runs tests against WordPress 6.2.8, with apiVersion `2` for blocks | +| `tests.yml` | Runs tests against the latest WordPress version, with apiVersion `3` for blocks | + ## Writing a WordPress Unit Test WordPress Unit tests provide testing of Plugin specific functions and/or classes, typically to assert that they perform as expected diff --git a/tests/EndToEnd.suite.yml b/tests/EndToEnd.suite.yml index 9bc855a5a..7cf15b9ed 100644 --- a/tests/EndToEnd.suite.yml +++ b/tests/EndToEnd.suite.yml @@ -67,7 +67,7 @@ modules: download.default_directory: '%WORDPRESS_ROOT_DIR%' lucatume\WPBrowser\Module\WPDb: dbUrl: '%WORDPRESS_DB_URL%' - dump: 'tests/Support/Data/dump.sql' + dump: '%WORDPRESS_DB_SQL_DUMP_FILE%' #import the dump before the tests; this means the test site database will be repopulated before the tests. populate: true # re-import the dump between tests; this means the test site database will be repopulated between the tests. diff --git a/tests/Support/Data/dump-6.2.8.sql b/tests/Support/Data/dump-6.2.8.sql new file mode 100644 index 000000000..c2c1e3c91 --- /dev/null +++ b/tests/Support/Data/dump-6.2.8.sql @@ -0,0 +1,355 @@ +-- Adminer 4.8.1 MySQL 8.0.16 dump + +SET NAMES utf8; +SET time_zone = '+00:00'; +SET foreign_key_checks = 0; +SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO'; + +SET NAMES utf8mb4; + +DROP TABLE IF EXISTS `wp_commentmeta`; +CREATE TABLE `wp_commentmeta` ( + `meta_id` bigint unsigned NOT NULL AUTO_INCREMENT, + `comment_id` bigint unsigned NOT NULL DEFAULT '0', + `meta_key` varchar(255) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL, + `meta_value` longtext COLLATE utf8mb4_unicode_520_ci, + PRIMARY KEY (`meta_id`), + KEY `comment_id` (`comment_id`), + KEY `meta_key` (`meta_key`(191)) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; + + +DROP TABLE IF EXISTS `wp_comments`; +CREATE TABLE `wp_comments` ( + `comment_ID` bigint unsigned NOT NULL AUTO_INCREMENT, + `comment_post_ID` bigint unsigned NOT NULL DEFAULT '0', + `comment_author` tinytext COLLATE utf8mb4_unicode_520_ci NOT NULL, + `comment_author_email` varchar(100) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `comment_author_url` varchar(200) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `comment_author_IP` varchar(100) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `comment_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `comment_date_gmt` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `comment_content` text COLLATE utf8mb4_unicode_520_ci NOT NULL, + `comment_karma` int NOT NULL DEFAULT '0', + `comment_approved` varchar(20) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '1', + `comment_agent` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `comment_type` varchar(20) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT 'comment', + `comment_parent` bigint unsigned NOT NULL DEFAULT '0', + `user_id` bigint unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`comment_ID`), + KEY `comment_post_ID` (`comment_post_ID`), + KEY `comment_approved_date_gmt` (`comment_approved`,`comment_date_gmt`), + KEY `comment_date_gmt` (`comment_date_gmt`), + KEY `comment_parent` (`comment_parent`), + KEY `comment_author_email` (`comment_author_email`(10)) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; + +INSERT INTO `wp_comments` (`comment_ID`, `comment_post_ID`, `comment_author`, `comment_author_email`, `comment_author_url`, `comment_author_IP`, `comment_date`, `comment_date_gmt`, `comment_content`, `comment_karma`, `comment_approved`, `comment_agent`, `comment_type`, `comment_parent`, `user_id`) VALUES +(1, 1, 'A WordPress Commenter', 'wapuu@wordpress.example', 'https://wordpress.org/', '', '2026-01-06 08:19:29', '2026-01-06 08:19:29', 'Hi, this is a comment.\nTo get started with moderating, editing, and deleting comments, please visit the Comments screen in the dashboard.\nCommenter avatars come from Gravatar.', 0, '1', '', 'comment', 0, 0); + +DROP TABLE IF EXISTS `wp_links`; +CREATE TABLE `wp_links` ( + `link_id` bigint unsigned NOT NULL AUTO_INCREMENT, + `link_url` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `link_name` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `link_image` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `link_target` varchar(25) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `link_description` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `link_visible` varchar(20) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT 'Y', + `link_owner` bigint unsigned NOT NULL DEFAULT '1', + `link_rating` int NOT NULL DEFAULT '0', + `link_updated` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `link_rel` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `link_notes` mediumtext COLLATE utf8mb4_unicode_520_ci NOT NULL, + `link_rss` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + PRIMARY KEY (`link_id`), + KEY `link_visible` (`link_visible`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; + + +DROP TABLE IF EXISTS `wp_options`; +CREATE TABLE `wp_options` ( + `option_id` bigint unsigned NOT NULL AUTO_INCREMENT, + `option_name` varchar(191) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `option_value` longtext COLLATE utf8mb4_unicode_520_ci NOT NULL, + `autoload` varchar(20) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT 'yes', + PRIMARY KEY (`option_id`), + UNIQUE KEY `option_name` (`option_name`), + KEY `autoload` (`autoload`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; + +INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES +(1, 'siteurl', 'http://kit.local', 'yes'), +(2, 'home', 'http://kit.local', 'yes'), +(3, 'blogname', 'kit', 'yes'), +(4, 'blogdescription', '', 'yes'), +(5, 'users_can_register', '0', 'yes'), +(6, 'admin_email', 'dev-email@flywheel.local', 'yes'), +(7, 'start_of_week', '1', 'yes'), +(8, 'use_balanceTags', '0', 'yes'), +(9, 'use_smilies', '1', 'yes'), +(10, 'require_name_email', '1', 'yes'), +(11, 'comments_notify', '1', 'yes'), +(12, 'posts_per_rss', '10', 'yes'), +(13, 'rss_use_excerpt', '0', 'yes'), +(14, 'mailserver_url', 'mail.example.com', 'yes'), +(15, 'mailserver_login', 'login@example.com', 'yes'), +(16, 'mailserver_pass', 'password', 'yes'), +(17, 'mailserver_port', '110', 'yes'), +(18, 'default_category', '1', 'yes'), +(19, 'default_comment_status', 'open', 'yes'), +(20, 'default_ping_status', 'open', 'yes'), +(21, 'default_pingback_flag', '0', 'yes'), +(22, 'posts_per_page', '10', 'yes'), +(23, 'date_format', 'F j, Y', 'yes'), +(24, 'time_format', 'g:i a', 'yes'), +(25, 'links_updated_date_format', 'F j, Y g:i a', 'yes'), +(26, 'comment_moderation', '0', 'yes'), +(27, 'moderation_notify', '1', 'yes'), +(28, 'permalink_structure', '/%year%/%monthnum%/%day%/%postname%/', 'yes'), +(29, 'rewrite_rules', 'a:81:{s:11:\"^wp-json/?$\";s:22:\"index.php?rest_route=/\";s:14:\"^wp-json/(.*)?\";s:33:\"index.php?rest_route=/$matches[1]\";s:21:\"^index.php/wp-json/?$\";s:22:\"index.php?rest_route=/\";s:24:\"^index.php/wp-json/(.*)?\";s:33:\"index.php?rest_route=/$matches[1]\";s:17:\"^wp-sitemap\\.xml$\";s:23:\"index.php?sitemap=index\";s:17:\"^wp-sitemap\\.xsl$\";s:36:\"index.php?sitemap-stylesheet=sitemap\";s:23:\"^wp-sitemap-index\\.xsl$\";s:34:\"index.php?sitemap-stylesheet=index\";s:48:\"^wp-sitemap-([a-z]+?)-([a-z\\d_-]+?)-(\\d+?)\\.xml$\";s:75:\"index.php?sitemap=$matches[1]&sitemap-subtype=$matches[2]&paged=$matches[3]\";s:34:\"^wp-sitemap-([a-z]+?)-(\\d+?)\\.xml$\";s:47:\"index.php?sitemap=$matches[1]&paged=$matches[2]\";s:12:\"robots\\.txt$\";s:18:\"index.php?robots=1\";s:13:\"favicon\\.ico$\";s:19:\"index.php?favicon=1\";s:48:\".*wp-(atom|rdf|rss|rss2|feed|commentsrss2)\\.php$\";s:18:\"index.php?feed=old\";s:20:\".*wp-app\\.php(/.*)?$\";s:19:\"index.php?error=403\";s:18:\".*wp-register.php$\";s:23:\"index.php?register=true\";s:32:\"feed/(feed|rdf|rss|rss2|atom)/?$\";s:27:\"index.php?&feed=$matches[1]\";s:27:\"(feed|rdf|rss|rss2|atom)/?$\";s:27:\"index.php?&feed=$matches[1]\";s:8:\"embed/?$\";s:21:\"index.php?&embed=true\";s:20:\"page/?([0-9]{1,})/?$\";s:28:\"index.php?&paged=$matches[1]\";s:41:\"comments/feed/(feed|rdf|rss|rss2|atom)/?$\";s:42:\"index.php?&feed=$matches[1]&withcomments=1\";s:36:\"comments/(feed|rdf|rss|rss2|atom)/?$\";s:42:\"index.php?&feed=$matches[1]&withcomments=1\";s:17:\"comments/embed/?$\";s:21:\"index.php?&embed=true\";s:44:\"search/(.+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:40:\"index.php?s=$matches[1]&feed=$matches[2]\";s:39:\"search/(.+)/(feed|rdf|rss|rss2|atom)/?$\";s:40:\"index.php?s=$matches[1]&feed=$matches[2]\";s:20:\"search/(.+)/embed/?$\";s:34:\"index.php?s=$matches[1]&embed=true\";s:32:\"search/(.+)/page/?([0-9]{1,})/?$\";s:41:\"index.php?s=$matches[1]&paged=$matches[2]\";s:14:\"search/(.+)/?$\";s:23:\"index.php?s=$matches[1]\";s:47:\"author/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:50:\"index.php?author_name=$matches[1]&feed=$matches[2]\";s:42:\"author/([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:50:\"index.php?author_name=$matches[1]&feed=$matches[2]\";s:23:\"author/([^/]+)/embed/?$\";s:44:\"index.php?author_name=$matches[1]&embed=true\";s:35:\"author/([^/]+)/page/?([0-9]{1,})/?$\";s:51:\"index.php?author_name=$matches[1]&paged=$matches[2]\";s:17:\"author/([^/]+)/?$\";s:33:\"index.php?author_name=$matches[1]\";s:69:\"([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/feed/(feed|rdf|rss|rss2|atom)/?$\";s:80:\"index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&feed=$matches[4]\";s:64:\"([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/(feed|rdf|rss|rss2|atom)/?$\";s:80:\"index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&feed=$matches[4]\";s:45:\"([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/embed/?$\";s:74:\"index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&embed=true\";s:57:\"([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/page/?([0-9]{1,})/?$\";s:81:\"index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&paged=$matches[4]\";s:39:\"([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/?$\";s:63:\"index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]\";s:56:\"([0-9]{4})/([0-9]{1,2})/feed/(feed|rdf|rss|rss2|atom)/?$\";s:64:\"index.php?year=$matches[1]&monthnum=$matches[2]&feed=$matches[3]\";s:51:\"([0-9]{4})/([0-9]{1,2})/(feed|rdf|rss|rss2|atom)/?$\";s:64:\"index.php?year=$matches[1]&monthnum=$matches[2]&feed=$matches[3]\";s:32:\"([0-9]{4})/([0-9]{1,2})/embed/?$\";s:58:\"index.php?year=$matches[1]&monthnum=$matches[2]&embed=true\";s:44:\"([0-9]{4})/([0-9]{1,2})/page/?([0-9]{1,})/?$\";s:65:\"index.php?year=$matches[1]&monthnum=$matches[2]&paged=$matches[3]\";s:26:\"([0-9]{4})/([0-9]{1,2})/?$\";s:47:\"index.php?year=$matches[1]&monthnum=$matches[2]\";s:43:\"([0-9]{4})/feed/(feed|rdf|rss|rss2|atom)/?$\";s:43:\"index.php?year=$matches[1]&feed=$matches[2]\";s:38:\"([0-9]{4})/(feed|rdf|rss|rss2|atom)/?$\";s:43:\"index.php?year=$matches[1]&feed=$matches[2]\";s:19:\"([0-9]{4})/embed/?$\";s:37:\"index.php?year=$matches[1]&embed=true\";s:31:\"([0-9]{4})/page/?([0-9]{1,})/?$\";s:44:\"index.php?year=$matches[1]&paged=$matches[2]\";s:13:\"([0-9]{4})/?$\";s:26:\"index.php?year=$matches[1]\";s:58:\"[0-9]{4}/[0-9]{1,2}/[0-9]{1,2}/[^/]+/attachment/([^/]+)/?$\";s:32:\"index.php?attachment=$matches[1]\";s:68:\"[0-9]{4}/[0-9]{1,2}/[0-9]{1,2}/[^/]+/attachment/([^/]+)/trackback/?$\";s:37:\"index.php?attachment=$matches[1]&tb=1\";s:88:\"[0-9]{4}/[0-9]{1,2}/[0-9]{1,2}/[^/]+/attachment/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:49:\"index.php?attachment=$matches[1]&feed=$matches[2]\";s:83:\"[0-9]{4}/[0-9]{1,2}/[0-9]{1,2}/[^/]+/attachment/([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:49:\"index.php?attachment=$matches[1]&feed=$matches[2]\";s:83:\"[0-9]{4}/[0-9]{1,2}/[0-9]{1,2}/[^/]+/attachment/([^/]+)/comment-page-([0-9]{1,})/?$\";s:50:\"index.php?attachment=$matches[1]&cpage=$matches[2]\";s:64:\"[0-9]{4}/[0-9]{1,2}/[0-9]{1,2}/[^/]+/attachment/([^/]+)/embed/?$\";s:43:\"index.php?attachment=$matches[1]&embed=true\";s:53:\"([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/([^/]+)/embed/?$\";s:91:\"index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&name=$matches[4]&embed=true\";s:57:\"([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/([^/]+)/trackback/?$\";s:85:\"index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&name=$matches[4]&tb=1\";s:77:\"([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:97:\"index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&name=$matches[4]&feed=$matches[5]\";s:72:\"([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:97:\"index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&name=$matches[4]&feed=$matches[5]\";s:65:\"([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/([^/]+)/page/?([0-9]{1,})/?$\";s:98:\"index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&name=$matches[4]&paged=$matches[5]\";s:72:\"([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/([^/]+)/comment-page-([0-9]{1,})/?$\";s:98:\"index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&name=$matches[4]&cpage=$matches[5]\";s:61:\"([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/([^/]+)(?:/([0-9]+))?/?$\";s:97:\"index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&name=$matches[4]&page=$matches[5]\";s:47:\"[0-9]{4}/[0-9]{1,2}/[0-9]{1,2}/[^/]+/([^/]+)/?$\";s:32:\"index.php?attachment=$matches[1]\";s:57:\"[0-9]{4}/[0-9]{1,2}/[0-9]{1,2}/[^/]+/([^/]+)/trackback/?$\";s:37:\"index.php?attachment=$matches[1]&tb=1\";s:77:\"[0-9]{4}/[0-9]{1,2}/[0-9]{1,2}/[^/]+/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:49:\"index.php?attachment=$matches[1]&feed=$matches[2]\";s:72:\"[0-9]{4}/[0-9]{1,2}/[0-9]{1,2}/[^/]+/([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:49:\"index.php?attachment=$matches[1]&feed=$matches[2]\";s:72:\"[0-9]{4}/[0-9]{1,2}/[0-9]{1,2}/[^/]+/([^/]+)/comment-page-([0-9]{1,})/?$\";s:50:\"index.php?attachment=$matches[1]&cpage=$matches[2]\";s:53:\"[0-9]{4}/[0-9]{1,2}/[0-9]{1,2}/[^/]+/([^/]+)/embed/?$\";s:43:\"index.php?attachment=$matches[1]&embed=true\";s:64:\"([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/comment-page-([0-9]{1,})/?$\";s:81:\"index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&cpage=$matches[4]\";s:51:\"([0-9]{4})/([0-9]{1,2})/comment-page-([0-9]{1,})/?$\";s:65:\"index.php?year=$matches[1]&monthnum=$matches[2]&cpage=$matches[3]\";s:38:\"([0-9]{4})/comment-page-([0-9]{1,})/?$\";s:44:\"index.php?year=$matches[1]&cpage=$matches[2]\";s:27:\".?.+?/attachment/([^/]+)/?$\";s:32:\"index.php?attachment=$matches[1]\";s:37:\".?.+?/attachment/([^/]+)/trackback/?$\";s:37:\"index.php?attachment=$matches[1]&tb=1\";s:57:\".?.+?/attachment/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:49:\"index.php?attachment=$matches[1]&feed=$matches[2]\";s:52:\".?.+?/attachment/([^/]+)/(feed|rdf|rss|rss2|atom)/?$\";s:49:\"index.php?attachment=$matches[1]&feed=$matches[2]\";s:52:\".?.+?/attachment/([^/]+)/comment-page-([0-9]{1,})/?$\";s:50:\"index.php?attachment=$matches[1]&cpage=$matches[2]\";s:33:\".?.+?/attachment/([^/]+)/embed/?$\";s:43:\"index.php?attachment=$matches[1]&embed=true\";s:16:\"(.?.+?)/embed/?$\";s:41:\"index.php?pagename=$matches[1]&embed=true\";s:20:\"(.?.+?)/trackback/?$\";s:35:\"index.php?pagename=$matches[1]&tb=1\";s:40:\"(.?.+?)/feed/(feed|rdf|rss|rss2|atom)/?$\";s:47:\"index.php?pagename=$matches[1]&feed=$matches[2]\";s:35:\"(.?.+?)/(feed|rdf|rss|rss2|atom)/?$\";s:47:\"index.php?pagename=$matches[1]&feed=$matches[2]\";s:28:\"(.?.+?)/page/?([0-9]{1,})/?$\";s:48:\"index.php?pagename=$matches[1]&paged=$matches[2]\";s:35:\"(.?.+?)/comment-page-([0-9]{1,})/?$\";s:48:\"index.php?pagename=$matches[1]&cpage=$matches[2]\";s:24:\"(.?.+?)(?:/([0-9]+))?/?$\";s:47:\"index.php?pagename=$matches[1]&page=$matches[2]\";}', 'yes'), +(30, 'hack_file', '0', 'yes'), +(31, 'blog_charset', 'UTF-8', 'yes'), +(32, 'moderation_keys', '', 'no'), +(33, 'active_plugins', 'a:0:{}', 'yes'), +(34, 'category_base', '', 'yes'), +(35, 'ping_sites', 'http://rpc.pingomatic.com/', 'yes'), +(36, 'comment_max_links', '2', 'yes'), +(37, 'gmt_offset', '0', 'yes'), +(38, 'default_email_category', '1', 'yes'), +(39, 'recently_edited', '', 'no'), +(40, 'template', 'twentytwentythree', 'yes'), +(41, 'stylesheet', 'twentytwentythree', 'yes'), +(42, 'comment_registration', '0', 'yes'), +(43, 'html_type', 'text/html', 'yes'), +(44, 'use_trackback', '0', 'yes'), +(45, 'default_role', 'subscriber', 'yes'), +(46, 'db_version', '53496', 'yes'), +(47, 'uploads_use_yearmonth_folders', '1', 'yes'), +(48, 'upload_path', '', 'yes'), +(49, 'blog_public', '0', 'yes'), +(50, 'default_link_category', '2', 'yes'), +(51, 'show_on_front', 'posts', 'yes'), +(52, 'tag_base', '', 'yes'), +(53, 'show_avatars', '1', 'yes'), +(54, 'avatar_rating', 'G', 'yes'), +(55, 'upload_url_path', '', 'yes'), +(56, 'thumbnail_size_w', '150', 'yes'), +(57, 'thumbnail_size_h', '150', 'yes'), +(58, 'thumbnail_crop', '1', 'yes'), +(59, 'medium_size_w', '300', 'yes'), +(60, 'medium_size_h', '300', 'yes'), +(61, 'avatar_default', 'mystery', 'yes'), +(62, 'large_size_w', '1024', 'yes'), +(63, 'large_size_h', '1024', 'yes'), +(64, 'image_default_link_type', 'none', 'yes'), +(65, 'image_default_size', '', 'yes'), +(66, 'image_default_align', '', 'yes'), +(67, 'close_comments_for_old_posts', '0', 'yes'), +(68, 'close_comments_days_old', '14', 'yes'), +(69, 'thread_comments', '1', 'yes'), +(70, 'thread_comments_depth', '5', 'yes'), +(71, 'page_comments', '0', 'yes'), +(72, 'comments_per_page', '50', 'yes'), +(73, 'default_comments_page', 'newest', 'yes'), +(74, 'comment_order', 'asc', 'yes'), +(75, 'sticky_posts', 'a:0:{}', 'yes'), +(76, 'widget_categories', 'a:0:{}', 'yes'), +(77, 'widget_text', 'a:0:{}', 'yes'), +(78, 'widget_rss', 'a:0:{}', 'yes'), +(79, 'uninstall_plugins', 'a:0:{}', 'no'), +(80, 'timezone_string', '', 'yes'), +(81, 'page_for_posts', '0', 'yes'), +(82, 'page_on_front', '0', 'yes'), +(83, 'default_post_format', '0', 'yes'), +(84, 'link_manager_enabled', '0', 'yes'), +(85, 'finished_splitting_shared_terms', '1', 'yes'), +(86, 'site_icon', '0', 'yes'), +(87, 'medium_large_size_w', '768', 'yes'), +(88, 'medium_large_size_h', '0', 'yes'), +(89, 'wp_page_for_privacy_policy', '3', 'yes'), +(90, 'show_comments_cookies_opt_in', '1', 'yes'), +(91, 'admin_email_lifespan', '1783239569', 'yes'), +(92, 'disallowed_keys', '', 'no'), +(93, 'comment_previously_approved', '1', 'yes'), +(94, 'auto_plugin_theme_update_emails', 'a:0:{}', 'no'), +(95, 'auto_update_core_dev', 'enabled', 'yes'), +(96, 'auto_update_core_minor', 'enabled', 'yes'), +(97, 'auto_update_core_major', 'enabled', 'yes'), +(98, 'wp_force_deactivated_plugins', 'a:0:{}', 'yes'), +(99, 'initial_db_version', '53496', 'yes'), +(100, 'wp_user_roles', 'a:5:{s:13:\"administrator\";a:2:{s:4:\"name\";s:13:\"Administrator\";s:12:\"capabilities\";a:61:{s:13:\"switch_themes\";b:1;s:11:\"edit_themes\";b:1;s:16:\"activate_plugins\";b:1;s:12:\"edit_plugins\";b:1;s:10:\"edit_users\";b:1;s:10:\"edit_files\";b:1;s:14:\"manage_options\";b:1;s:17:\"moderate_comments\";b:1;s:17:\"manage_categories\";b:1;s:12:\"manage_links\";b:1;s:12:\"upload_files\";b:1;s:6:\"import\";b:1;s:15:\"unfiltered_html\";b:1;s:10:\"edit_posts\";b:1;s:17:\"edit_others_posts\";b:1;s:20:\"edit_published_posts\";b:1;s:13:\"publish_posts\";b:1;s:10:\"edit_pages\";b:1;s:4:\"read\";b:1;s:8:\"level_10\";b:1;s:7:\"level_9\";b:1;s:7:\"level_8\";b:1;s:7:\"level_7\";b:1;s:7:\"level_6\";b:1;s:7:\"level_5\";b:1;s:7:\"level_4\";b:1;s:7:\"level_3\";b:1;s:7:\"level_2\";b:1;s:7:\"level_1\";b:1;s:7:\"level_0\";b:1;s:17:\"edit_others_pages\";b:1;s:20:\"edit_published_pages\";b:1;s:13:\"publish_pages\";b:1;s:12:\"delete_pages\";b:1;s:19:\"delete_others_pages\";b:1;s:22:\"delete_published_pages\";b:1;s:12:\"delete_posts\";b:1;s:19:\"delete_others_posts\";b:1;s:22:\"delete_published_posts\";b:1;s:20:\"delete_private_posts\";b:1;s:18:\"edit_private_posts\";b:1;s:18:\"read_private_posts\";b:1;s:20:\"delete_private_pages\";b:1;s:18:\"edit_private_pages\";b:1;s:18:\"read_private_pages\";b:1;s:12:\"delete_users\";b:1;s:12:\"create_users\";b:1;s:17:\"unfiltered_upload\";b:1;s:14:\"edit_dashboard\";b:1;s:14:\"update_plugins\";b:1;s:14:\"delete_plugins\";b:1;s:15:\"install_plugins\";b:1;s:13:\"update_themes\";b:1;s:14:\"install_themes\";b:1;s:11:\"update_core\";b:1;s:10:\"list_users\";b:1;s:12:\"remove_users\";b:1;s:13:\"promote_users\";b:1;s:18:\"edit_theme_options\";b:1;s:13:\"delete_themes\";b:1;s:6:\"export\";b:1;}}s:6:\"editor\";a:2:{s:4:\"name\";s:6:\"Editor\";s:12:\"capabilities\";a:34:{s:17:\"moderate_comments\";b:1;s:17:\"manage_categories\";b:1;s:12:\"manage_links\";b:1;s:12:\"upload_files\";b:1;s:15:\"unfiltered_html\";b:1;s:10:\"edit_posts\";b:1;s:17:\"edit_others_posts\";b:1;s:20:\"edit_published_posts\";b:1;s:13:\"publish_posts\";b:1;s:10:\"edit_pages\";b:1;s:4:\"read\";b:1;s:7:\"level_7\";b:1;s:7:\"level_6\";b:1;s:7:\"level_5\";b:1;s:7:\"level_4\";b:1;s:7:\"level_3\";b:1;s:7:\"level_2\";b:1;s:7:\"level_1\";b:1;s:7:\"level_0\";b:1;s:17:\"edit_others_pages\";b:1;s:20:\"edit_published_pages\";b:1;s:13:\"publish_pages\";b:1;s:12:\"delete_pages\";b:1;s:19:\"delete_others_pages\";b:1;s:22:\"delete_published_pages\";b:1;s:12:\"delete_posts\";b:1;s:19:\"delete_others_posts\";b:1;s:22:\"delete_published_posts\";b:1;s:20:\"delete_private_posts\";b:1;s:18:\"edit_private_posts\";b:1;s:18:\"read_private_posts\";b:1;s:20:\"delete_private_pages\";b:1;s:18:\"edit_private_pages\";b:1;s:18:\"read_private_pages\";b:1;}}s:6:\"author\";a:2:{s:4:\"name\";s:6:\"Author\";s:12:\"capabilities\";a:10:{s:12:\"upload_files\";b:1;s:10:\"edit_posts\";b:1;s:20:\"edit_published_posts\";b:1;s:13:\"publish_posts\";b:1;s:4:\"read\";b:1;s:7:\"level_2\";b:1;s:7:\"level_1\";b:1;s:7:\"level_0\";b:1;s:12:\"delete_posts\";b:1;s:22:\"delete_published_posts\";b:1;}}s:11:\"contributor\";a:2:{s:4:\"name\";s:11:\"Contributor\";s:12:\"capabilities\";a:5:{s:10:\"edit_posts\";b:1;s:4:\"read\";b:1;s:7:\"level_1\";b:1;s:7:\"level_0\";b:1;s:12:\"delete_posts\";b:1;}}s:10:\"subscriber\";a:2:{s:4:\"name\";s:10:\"Subscriber\";s:12:\"capabilities\";a:2:{s:4:\"read\";b:1;s:7:\"level_0\";b:1;}}}', 'yes'), +(101, 'fresh_site', '1', 'yes'), +(102, 'user_count', '1', 'no'), +(103, 'widget_block', 'a:6:{i:2;a:1:{s:7:\"content\";s:19:\"\";}i:3;a:1:{s:7:\"content\";s:154:\"

Recent Posts

\";}i:4;a:1:{s:7:\"content\";s:227:\"

Recent Comments

\";}i:5;a:1:{s:7:\"content\";s:146:\"

Archives

\";}i:6;a:1:{s:7:\"content\";s:150:\"

Categories

\";}s:12:\"_multiwidget\";i:1;}', 'yes'), +(104, 'sidebars_widgets', 'a:4:{s:19:\"wp_inactive_widgets\";a:0:{}s:9:\"sidebar-1\";a:3:{i:0;s:7:\"block-2\";i:1;s:7:\"block-3\";i:2;s:7:\"block-4\";}s:9:\"sidebar-2\";a:2:{i:0;s:7:\"block-5\";i:1;s:7:\"block-6\";}s:13:\"array_version\";i:3;}', 'yes'), +(105, 'cron', 'a:8:{i:1767687569;a:2:{s:17:\"wp_update_plugins\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:10:\"twicedaily\";s:4:\"args\";a:0:{}s:8:\"interval\";i:43200;}}s:16:\"wp_update_themes\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:10:\"twicedaily\";s:4:\"args\";a:0:{}s:8:\"interval\";i:43200;}}}i:1767687580;a:3:{s:19:\"wp_scheduled_delete\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:5:\"daily\";s:4:\"args\";a:0:{}s:8:\"interval\";i:86400;}}s:25:\"delete_expired_transients\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:5:\"daily\";s:4:\"args\";a:0:{}s:8:\"interval\";i:86400;}}s:21:\"wp_update_user_counts\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:10:\"twicedaily\";s:4:\"args\";a:0:{}s:8:\"interval\";i:43200;}}}i:1767687585;a:1:{s:30:\"wp_scheduled_auto_draft_delete\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:5:\"daily\";s:4:\"args\";a:0:{}s:8:\"interval\";i:86400;}}}i:1767687640;a:1:{s:28:\"wp_update_comment_type_batch\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:2:{s:8:\"schedule\";b:0;s:4:\"args\";a:0:{}}}}i:1767691169;a:1:{s:34:\"wp_privacy_delete_old_export_files\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:6:\"hourly\";s:4:\"args\";a:0:{}s:8:\"interval\";i:3600;}}}i:1767730769;a:2:{s:18:\"wp_https_detection\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:10:\"twicedaily\";s:4:\"args\";a:0:{}s:8:\"interval\";i:43200;}}s:16:\"wp_version_check\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:10:\"twicedaily\";s:4:\"args\";a:0:{}s:8:\"interval\";i:43200;}}}i:1767773969;a:2:{s:30:\"wp_site_health_scheduled_check\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:6:\"weekly\";s:4:\"args\";a:0:{}s:8:\"interval\";i:604800;}}s:32:\"recovery_mode_clean_expired_keys\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:5:\"daily\";s:4:\"args\";a:0:{}s:8:\"interval\";i:86400;}}}s:7:\"version\";i:2;}', 'yes'), +(106, 'widget_pages', 'a:1:{s:12:\"_multiwidget\";i:1;}', 'yes'), +(107, 'widget_calendar', 'a:1:{s:12:\"_multiwidget\";i:1;}', 'yes'), +(108, 'widget_archives', 'a:1:{s:12:\"_multiwidget\";i:1;}', 'yes'), +(109, 'widget_media_audio', 'a:1:{s:12:\"_multiwidget\";i:1;}', 'yes'), +(110, 'widget_media_image', 'a:1:{s:12:\"_multiwidget\";i:1;}', 'yes'), +(111, 'widget_media_gallery', 'a:1:{s:12:\"_multiwidget\";i:1;}', 'yes'), +(112, 'widget_media_video', 'a:1:{s:12:\"_multiwidget\";i:1;}', 'yes'), +(113, 'widget_meta', 'a:1:{s:12:\"_multiwidget\";i:1;}', 'yes'), +(114, 'widget_search', 'a:1:{s:12:\"_multiwidget\";i:1;}', 'yes'), +(115, 'widget_recent-posts', 'a:1:{s:12:\"_multiwidget\";i:1;}', 'yes'), +(116, 'widget_recent-comments', 'a:1:{s:12:\"_multiwidget\";i:1;}', 'yes'), +(117, 'widget_tag_cloud', 'a:1:{s:12:\"_multiwidget\";i:1;}', 'yes'), +(118, 'widget_nav_menu', 'a:1:{s:12:\"_multiwidget\";i:1;}', 'yes'), +(119, 'widget_custom_html', 'a:1:{s:12:\"_multiwidget\";i:1;}', 'yes'), +(120, '_transient_doing_cron', '1767687569.2989718914031982421875', 'yes'), +(121, 'theme_mods_twentytwentythree', 'a:1:{s:18:\"custom_css_post_id\";i:-1;}', 'yes'), +(122, 'recovery_keys', 'a:0:{}', 'yes'), +(123, 'https_detection_errors', 'a:1:{s:23:\"ssl_verification_failed\";a:1:{i:0;s:24:\"SSL verification failed.\";}}', 'yes'), +(124, 'can_compress_scripts', '0', 'no'); + +DROP TABLE IF EXISTS `wp_postmeta`; +CREATE TABLE `wp_postmeta` ( + `meta_id` bigint unsigned NOT NULL AUTO_INCREMENT, + `post_id` bigint unsigned NOT NULL DEFAULT '0', + `meta_key` varchar(255) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL, + `meta_value` longtext COLLATE utf8mb4_unicode_520_ci, + PRIMARY KEY (`meta_id`), + KEY `post_id` (`post_id`), + KEY `meta_key` (`meta_key`(191)) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; + +DROP TABLE IF EXISTS `wp_posts`; +CREATE TABLE `wp_posts` ( + `ID` bigint unsigned NOT NULL AUTO_INCREMENT, + `post_author` bigint unsigned NOT NULL DEFAULT '0', + `post_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `post_date_gmt` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `post_content` longtext COLLATE utf8mb4_unicode_520_ci NOT NULL, + `post_title` text COLLATE utf8mb4_unicode_520_ci NOT NULL, + `post_excerpt` text COLLATE utf8mb4_unicode_520_ci NOT NULL, + `post_status` varchar(20) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT 'publish', + `comment_status` varchar(20) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT 'open', + `ping_status` varchar(20) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT 'open', + `post_password` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `post_name` varchar(200) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `to_ping` text COLLATE utf8mb4_unicode_520_ci NOT NULL, + `pinged` text COLLATE utf8mb4_unicode_520_ci NOT NULL, + `post_modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `post_modified_gmt` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `post_content_filtered` longtext COLLATE utf8mb4_unicode_520_ci NOT NULL, + `post_parent` bigint unsigned NOT NULL DEFAULT '0', + `guid` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `menu_order` int NOT NULL DEFAULT '0', + `post_type` varchar(20) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT 'post', + `post_mime_type` varchar(100) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `comment_count` bigint NOT NULL DEFAULT '0', + PRIMARY KEY (`ID`), + KEY `post_name` (`post_name`(191)), + KEY `type_status_date` (`post_type`,`post_status`,`post_date`,`ID`), + KEY `post_parent` (`post_parent`), + KEY `post_author` (`post_author`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; + +DROP TABLE IF EXISTS `wp_term_relationships`; +CREATE TABLE `wp_term_relationships` ( + `object_id` bigint unsigned NOT NULL DEFAULT '0', + `term_taxonomy_id` bigint unsigned NOT NULL DEFAULT '0', + `term_order` int NOT NULL DEFAULT '0', + PRIMARY KEY (`object_id`,`term_taxonomy_id`), + KEY `term_taxonomy_id` (`term_taxonomy_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; + +INSERT INTO `wp_term_relationships` (`object_id`, `term_taxonomy_id`, `term_order`) VALUES +(1, 1, 0); + +DROP TABLE IF EXISTS `wp_term_taxonomy`; +CREATE TABLE `wp_term_taxonomy` ( + `term_taxonomy_id` bigint unsigned NOT NULL AUTO_INCREMENT, + `term_id` bigint unsigned NOT NULL DEFAULT '0', + `taxonomy` varchar(32) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `description` longtext COLLATE utf8mb4_unicode_520_ci NOT NULL, + `parent` bigint unsigned NOT NULL DEFAULT '0', + `count` bigint NOT NULL DEFAULT '0', + PRIMARY KEY (`term_taxonomy_id`), + UNIQUE KEY `term_id_taxonomy` (`term_id`,`taxonomy`), + KEY `taxonomy` (`taxonomy`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; + +INSERT INTO `wp_term_taxonomy` (`term_taxonomy_id`, `term_id`, `taxonomy`, `description`, `parent`, `count`) VALUES +(1, 1, 'category', '', 0, 1); + +DROP TABLE IF EXISTS `wp_termmeta`; +CREATE TABLE `wp_termmeta` ( + `meta_id` bigint unsigned NOT NULL AUTO_INCREMENT, + `term_id` bigint unsigned NOT NULL DEFAULT '0', + `meta_key` varchar(255) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL, + `meta_value` longtext COLLATE utf8mb4_unicode_520_ci, + PRIMARY KEY (`meta_id`), + KEY `term_id` (`term_id`), + KEY `meta_key` (`meta_key`(191)) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; + + +DROP TABLE IF EXISTS `wp_terms`; +CREATE TABLE `wp_terms` ( + `term_id` bigint unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(200) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `slug` varchar(200) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `term_group` bigint NOT NULL DEFAULT '0', + PRIMARY KEY (`term_id`), + KEY `slug` (`slug`(191)), + KEY `name` (`name`(191)) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; + +INSERT INTO `wp_terms` (`term_id`, `name`, `slug`, `term_group`) VALUES +(1, 'Uncategorized', 'uncategorized', 0); + +DROP TABLE IF EXISTS `wp_usermeta`; +CREATE TABLE `wp_usermeta` ( + `umeta_id` bigint unsigned NOT NULL AUTO_INCREMENT, + `user_id` bigint unsigned NOT NULL DEFAULT '0', + `meta_key` varchar(255) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL, + `meta_value` longtext COLLATE utf8mb4_unicode_520_ci, + PRIMARY KEY (`umeta_id`), + KEY `user_id` (`user_id`), + KEY `meta_key` (`meta_key`(191)) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; + +INSERT INTO `wp_usermeta` (`umeta_id`, `user_id`, `meta_key`, `meta_value`) VALUES +(1, 1, 'nickname', 'admin'), +(2, 1, 'first_name', ''), +(3, 1, 'last_name', ''), +(4, 1, 'description', ''), +(5, 1, 'rich_editing', 'true'), +(6, 1, 'syntax_highlighting', 'true'), +(7, 1, 'comment_shortcuts', 'false'), +(8, 1, 'admin_color', 'fresh'), +(9, 1, 'use_ssl', '0'), +(10, 1, 'show_admin_bar_front', 'true'), +(11, 1, 'locale', ''), +(12, 1, 'wp_capabilities', 'a:1:{s:13:\"administrator\";b:1;}'), +(13, 1, 'wp_user_level', '10'), +(14, 1, 'dismissed_wp_pointers', ''), +(15, 1, 'show_welcome_panel', '1'), +(16, 1, 'session_tokens', 'a:1:{s:64:\"2e6c5be50a5dc4b7bf08d68c6db2092ed367421699b2f886930017c93ce1a4ea\";a:4:{s:10:\"expiration\";i:1767860380;s:2:\"ip\";s:9:\"127.0.0.1\";s:2:\"ua\";s:117:\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36\";s:5:\"login\";i:1767687580;}}'), +(17, 1, 'wp_dashboard_quick_press_last_post_id', '4'); + +DROP TABLE IF EXISTS `wp_users`; +CREATE TABLE `wp_users` ( + `ID` bigint unsigned NOT NULL AUTO_INCREMENT, + `user_login` varchar(60) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `user_pass` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `user_nicename` varchar(50) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `user_email` varchar(100) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `user_url` varchar(100) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `user_registered` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `user_activation_key` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `user_status` int NOT NULL DEFAULT '0', + `display_name` varchar(250) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + PRIMARY KEY (`ID`), + KEY `user_login_key` (`user_login`), + KEY `user_nicename` (`user_nicename`), + KEY `user_email` (`user_email`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; + +INSERT INTO `wp_users` (`ID`, `user_login`, `user_pass`, `user_nicename`, `user_email`, `user_url`, `user_registered`, `user_activation_key`, `user_status`, `display_name`) VALUES +(1, 'admin', '$P$BL6V8Lk8jOD6WFowZzH9DLpv9EWFP3.', 'admin', 'dev@flywheel.local', 'http://wordpress-628.local', '2026-01-06 08:19:29', '', 0, 'admin'); + +-- 2026-01-06 08:20:04 UTC From 50d4d7afff563211b664c76bbdfe16c689af6ae0 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Tue, 6 Jan 2026 16:24:55 +0800 Subject: [PATCH 16/19] Run tests against 8.1 for testing GitHub actions --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 704de67b6..8532cf1ee 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -54,7 +54,7 @@ jobs: fail-fast: false matrix: wp-versions: [ 'latest' ] #[ '6.1.1', 'latest' ] - php-versions: [ '8.1', '8.2', '8.3', '8.4' ] #[ '7.4', '8.0', '8.1' ] + php-versions: [ '8.1' ] #[ '7.4', '8.0', '8.1' ] # Folder names within the 'tests' folder to run tests in parallel. test-groups: [ From 3b9e1542dbec0a6200b7ee4abcd3ecd65574a278 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Tue, 6 Jan 2026 16:42:36 +0800 Subject: [PATCH 17/19] Reinstate all PHP versions for GitHub action --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8532cf1ee..704de67b6 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -54,7 +54,7 @@ jobs: fail-fast: false matrix: wp-versions: [ 'latest' ] #[ '6.1.1', 'latest' ] - php-versions: [ '8.1' ] #[ '7.4', '8.0', '8.1' ] + php-versions: [ '8.1', '8.2', '8.3', '8.4' ] #[ '7.4', '8.0', '8.1' ] # Folder names within the 'tests' folder to run tests in parallel. test-groups: [ From 72cd57c082ff8ff7c604d7f809adcaa922beac74 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Tue, 6 Jan 2026 16:53:31 +0800 Subject: [PATCH 18/19] =?UTF-8?q?GitHub=20Action:=20Backward=20Compat=20Te?= =?UTF-8?q?sts:=20Don=E2=80=99t=20auto=20update=20core=20during=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/tests-backward-compat.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/tests-backward-compat.yml b/.github/workflows/tests-backward-compat.yml index eaf55f6eb..c6877a502 100644 --- a/.github/workflows/tests-backward-compat.yml +++ b/.github/workflows/tests-backward-compat.yml @@ -141,6 +141,12 @@ jobs: run: | wp-cli config set DISALLOW_FILE_MODS true --raw + # Prevent WordPress auto updating to the latest version, as we specifically want to use a specific version of WordPress. + - name: Disable WP_AUTO_UPDATE_CORE + working-directory: ${{ env.ROOT_DIR }} + run: | + wp-cli config set WP_AUTO_UPDATE_CORE false --raw + # This step is deliberately after WordPress installation and configuration, as enabling PHP 8.x before using WP-CLI results # in the workflow failing due to incompatibilities between WP-CLI and PHP 8.x. # By installing PHP at this stage, we can still run our tests against e.g. PHP 8.x. From 636737348c70079716dc108e307c0102b5479324 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Tue, 6 Jan 2026 16:53:43 +0800 Subject: [PATCH 19/19] =?UTF-8?q?Tests:=20Backward=20compat:=20Don?= =?UTF-8?q?=E2=80=99t=20show=20welcome=20to=20block=20editor=20screen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/Support/Data/dump-6.2.8.sql | 39 +++++++++++++++++-------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/tests/Support/Data/dump-6.2.8.sql b/tests/Support/Data/dump-6.2.8.sql index c2c1e3c91..c7162a88b 100644 --- a/tests/Support/Data/dump-6.2.8.sql +++ b/tests/Support/Data/dump-6.2.8.sql @@ -313,23 +313,28 @@ CREATE TABLE `wp_usermeta` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; INSERT INTO `wp_usermeta` (`umeta_id`, `user_id`, `meta_key`, `meta_value`) VALUES -(1, 1, 'nickname', 'admin'), -(2, 1, 'first_name', ''), -(3, 1, 'last_name', ''), -(4, 1, 'description', ''), -(5, 1, 'rich_editing', 'true'), -(6, 1, 'syntax_highlighting', 'true'), -(7, 1, 'comment_shortcuts', 'false'), -(8, 1, 'admin_color', 'fresh'), -(9, 1, 'use_ssl', '0'), -(10, 1, 'show_admin_bar_front', 'true'), -(11, 1, 'locale', ''), -(12, 1, 'wp_capabilities', 'a:1:{s:13:\"administrator\";b:1;}'), -(13, 1, 'wp_user_level', '10'), -(14, 1, 'dismissed_wp_pointers', ''), -(15, 1, 'show_welcome_panel', '1'), -(16, 1, 'session_tokens', 'a:1:{s:64:\"2e6c5be50a5dc4b7bf08d68c6db2092ed367421699b2f886930017c93ce1a4ea\";a:4:{s:10:\"expiration\";i:1767860380;s:2:\"ip\";s:9:\"127.0.0.1\";s:2:\"ua\";s:117:\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36\";s:5:\"login\";i:1767687580;}}'), -(17, 1, 'wp_dashboard_quick_press_last_post_id', '4'); +(1, 1, 'nickname', 'admin'), +(2, 1, 'first_name', ''), +(3, 1, 'last_name', ''), +(4, 1, 'description', ''), +(5, 1, 'rich_editing', 'true'), +(6, 1, 'syntax_highlighting', 'true'), +(7, 1, 'comment_shortcuts', 'false'), +(8, 1, 'admin_color', 'fresh'), +(9, 1, 'use_ssl', '0'), +(10, 1, 'show_admin_bar_front', 'true'), +(11, 1, 'locale', ''), +(12, 1, 'wp_capabilities', 'a:1:{s:13:\"administrator\";b:1;}'), +(13, 1, 'wp_user_level', '10'), +(14, 1, 'dismissed_wp_pointers', ''), +(15, 1, 'show_welcome_panel', '1'), +(16, 1, 'session_tokens', 'a:1:{s:64:\"d1edb8c7d17dc41fa6de9833631a6381dca0306f20dfd4b64947e6b8818dd16e\";a:4:{s:10:\"expiration\";i:1676810217;s:2:\"ip\";s:9:\"127.0.0.1\";s:2:\"ua\";s:117:\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36\";s:5:\"login\";i:1676637417;}}'), +(17, 1, 'wp_user-settings', 'unfold=1&ampmfold=o&ampeditor=html&amplibraryContent=browse&ampsiteorigin_panels_setting_tab=widgets&libraryContent=browse&editor=tinymce&libraryContent=browse&editor=tinymce&siteorigin_panels_setting_tab=welcome'), +(18, 1, 'wp_user-settings-time', '1676637417'), +(19, 1, 'wp_dashboard_quick_press_last_post_id', '1'), +(20, 1, 'edit_page_per_page', '100'), +(21, 1, 'edit_post_per_page', '100'), +(22, 1, 'wp_persisted_preferences', 'a:4:{s:4:"core";a:2:{s:26:"isComplementaryAreaVisible";b:1;s:24:"enableChoosePatternModal";b:0;}s:14:"core/edit-post";a:4:{s:12:"welcomeGuide";b:0;s:23:"metaBoxesMainOpenHeight";i:540;s:20:"welcomeGuideTemplate";b:0;s:19:"metaBoxesMainIsOpen";b:1;}s:9:"_modified";s:24:"2024-07-18T02:45:41.491Z";s:17:"core/edit-widgets";a:2:{s:26:"isComplementaryAreaVisible";b:1;s:12:"welcomeGuide";b:0;}}'); DROP TABLE IF EXISTS `wp_users`; CREATE TABLE `wp_users` (