| 1 |
<?php |
| 2 |
require '/wordpress/wp-load.php'; |
| 3 |
|
| 4 |
// Ref-based navigation: the items live in a wp_navigation CPT post. |
| 5 |
// PHPUnit tests already pin WPNavigationController end to end. |
| 6 |
// The matching E2E flow needs the navigation block inside a *template-part* |
| 7 |
// (not page content) so resolveTarget routes through PART_ATTR → |
| 8 |
// wp-navigation source: a nav block embedded in post_content takes the |
| 9 |
// POST_ATTR branch and hits SaveController, which 409s on the outer |
| 10 |
// navigation block (parsed core/navigation has empty innerBlocks for |
| 11 |
// ref-based navs, since items live in a separate wp_navigation post). |
| 12 |
// Three items so item-index counts past zero and reorder/delete cases |
| 13 |
// have something to walk. |
| 14 |
$navContent = '<!-- wp:navigation-link {"label":"Original Home","url":"/"} /-->' |
| 15 |
. "\n" |
| 16 |
. '<!-- wp:navigation-link {"label":"Original About","url":"/about"} /-->' |
| 17 |
. "\n" |
| 18 |
. '<!-- wp:navigation-link {"label":"Original Contact","url":"/contact"} /-->'; |
| 19 |
|
| 20 |
$navPostId = wp_insert_post([ |
| 21 |
'post_type' => 'wp_navigation', |
| 22 |
'post_status' => 'publish', |
| 23 |
'post_title' => 'QE Test Nav', |
| 24 |
'post_content' => $navContent, |
| 25 |
]); |
| 26 |
|
| 27 |
$content = "<!-- wp:heading -->\n" |
| 28 |
. '<h2 class="wp-block-heading">QE reload-flows home.</h2>' |
| 29 |
. "\n<!-- /wp:heading -->"; |
| 30 |
|
| 31 |
$pageId = wp_insert_post([ |
| 32 |
'post_type' => 'page', |
| 33 |
'post_status' => 'publish', |
| 34 |
'post_title' => 'QE Reload Flows Home', |
| 35 |
'post_content' => $content, |
| 36 |
]); |
| 37 |
|
| 38 |
update_option('show_on_front', 'page'); |
| 39 |
update_option('page_on_front', $pageId); |
| 40 |
|
| 41 |
// Seed a 1x1 PNG attachment + point site_logo at it so the front-page |
| 42 |
// site-logo block has something to render — extendable hides |
| 43 |
// `.wp-block-site-logo:empty` via CSS, and an unset `site_logo` option |
| 44 |
// renders nothing, so without this the block isn't hoverable. The |
| 45 |
// attachment also gives SiteIdentityModal's `logo` kind a populated |
| 46 |
// `logo_url` + the Change-logo / Remove button pair the site-logo flow acts on. |
| 47 |
$uploadDir = wp_upload_dir(); |
| 48 |
if (!empty($uploadDir['path']) && !file_exists($uploadDir['path'])) { |
| 49 |
wp_mkdir_p($uploadDir['path']); |
| 50 |
} |
| 51 |
$logoPath = trailingslashit($uploadDir['path']) . 'qe-reload-flows-logo.png'; |
| 52 |
file_put_contents( |
| 53 |
$logoPath, |
| 54 |
base64_decode( |
| 55 |
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkAAIAAAoAAv/lxKUAAAAASUVORK5CYII=' |
| 56 |
) |
| 57 |
); |
| 58 |
$logoId = wp_insert_attachment( |
| 59 |
[ |
| 60 |
'post_mime_type' => 'image/png', |
| 61 |
'post_title' => 'QE Reload Flows Logo', |
| 62 |
'post_status' => 'inherit', |
| 63 |
], |
| 64 |
$logoPath |
| 65 |
); |
| 66 |
require_once ABSPATH . 'wp-admin/includes/image.php'; |
| 67 |
wp_update_attachment_metadata( |
| 68 |
$logoId, |
| 69 |
wp_generate_attachment_metadata($logoId, $logoPath) |
| 70 |
); |
| 71 |
update_option('site_logo', (int) $logoId); |
| 72 |
|
| 73 |
// Override extendable's `header` template-part so all three site-identity |
| 74 |
// blocks render side by side on the front page. Block themes prefer a |
| 75 |
// DB-resolved wp_template_part over the theme's filesystem part when both |
| 76 |
// exist for the same slug + wp_theme term. The base template still invokes |
| 77 |
// the part with tagName="header", so the <header> wrapper — and thus |
| 78 |
// role="banner" — is preserved for the locators in the spec. |
| 79 |
// The {"width":120} attribute renders the logo at 120px regardless of |
| 80 |
// the source PNG's intrinsic size — without it the 1x1 seed renders |
| 81 |
// 1px tall, the hover bar's transparent ::before bridge above the bar |
| 82 |
// overlaps the cursor's resting position, and Playwright's hover gives |
| 83 |
// up because the bar "intercepts pointer events". |
| 84 |
// The wp:navigation block here is what makes the ref-based save |
| 85 |
// path reachable from the front end: TagTemplateParts puts PART_ATTR on |
| 86 |
// every block inside the part scope (each <li> nav item included), so |
| 87 |
// resolveTarget's PART_ATTR branch fires and routes to findNavContext |
| 88 |
// instead of falling through to SaveController. `overlayMenu:"never"` |
| 89 |
// keeps the items inline at every viewport so Playwright can hover them |
| 90 |
// directly without driving the responsive overlay open first. |
| 91 |
$headerContent = "<!-- wp:site-logo {\"width\":120} /-->\n" |
| 92 |
. "<!-- wp:site-title /-->\n" |
| 93 |
. "<!-- wp:site-tagline /-->\n" |
| 94 |
. '<!-- wp:navigation {"ref":' . (int) $navPostId |
| 95 |
. ',"overlayMenu":"never"} /-->'; |
| 96 |
|
| 97 |
$headerPartId = wp_insert_post([ |
| 98 |
'post_type' => 'wp_template_part', |
| 99 |
'post_status' => 'publish', |
| 100 |
'post_name' => 'header', |
| 101 |
'post_title' => 'Header', |
| 102 |
'post_content' => $headerContent, |
| 103 |
]); |
| 104 |
wp_set_object_terms($headerPartId, 'extendable', 'wp_theme'); |
| 105 |
|