v1.5.0 — BackOffice validated, checkout & order lifecycle, visual regression, HTTP presets
Second minor release after 1.3.0. Turns the framework from nav-validated into a proven end-to-end driver against a live PrestaShop 9: real product create/edit, guest and logged-in checkout, and full order lifecycle in the BackOffice — every increment validated live. Ships visual regression testing, HTTP presets (cookies, Basic Auth, User-Agent), a new RGPD FrontOffice page, cold-start resilience, and fixes several long-standing bugs in the core primitives.
✨ Added — reusable scenarios
CheckoutOrder— logged-in customer places an order end-to-end (login → cart → checkout tunnel → confirmation → order found in BackOffice). Live 5/5.GuestCheckout— pure guest checkout with new address (personal info + address + shipping + payment + confirmation). Live 4/4.ManageOrder— opens an order in the BackOffice, changes its status, adds an internal note, sets a tracking number, each verified.OrderLifecyclesuite — composesCheckoutOrder→ManageOrder: create then manage. Live 9/9.EditProduct— self-cleaning: create a product, open it from the list, change its price, verify, delete. Live 4/4.CreateProductAndVerify— BackOffice product creation + FrontOffice visibility check (cross-page BO → FO).
✨ Added — page objects & helpers
- FrontOffice:
Cart(goToCart,proceedToCheckout),Checkout(multi-step tunnel + guest stepscheckoutAsGuest/fillNewAddress),OrderConfirmation(isConfirmed,getOrderReference),Rgpd(cookie-consent banner handling for the FrontOffice). - BackOffice:
OrderView(updateStatus/hasStatusInHistory,setInternalNote/getInternalNote,addTracking/getTracking),Ordersextended withopenOrder,filterByReference,getOrderReferenceInList. - Products: real PS 9 create flow (
goToNewProductbypasses the JS type-choice modal),createProduct(name + price + quantity + activate + save),deleteProduct,openProduct,updatePrice,getFormPrice,getCreatedProductId,getCreatedProductUrl(reads the canonical FO URL from the BO Preview link). FrontOfficePage::goToUrl($url)— navigate to an absolute FO URL with a clean session;Product::goToProductPath($path)— reach a product by canonical path.UrlsFrench catalog (src/Urls/fr.json):login=connexion,cart=panier?action=show,order=commande.
✨ Added — visual regression testing
CommonPage::visualCheckpoint($label, $fullPage = true)— take a screenshot, compare against a stored baseline, record pass/fail into the run.Visual\VisualComparator— the underlying image diff engine.Reports\VisualReport— renders an HTML report (reports/visual/index.html) plus avisual-results.jsonside-file, wired tobin/prestaflow run --visual-report[=path].- VIEWPORT capture mode via
$fullPage = false(in addition to full-page). - Baselines stored in a persistent folder (outside the ephemeral
screens/).
✨ Added — HTTP presets (env-driven)
PRESTAFLOW_USER_AGENT— sets the browser's User-Agent for the whole run.PRESTAFLOW_COOKIES— preload cookies before the first navigation (awaited to be deterministic).- HTTP Basic Auth via env — installed at the connection level so it survives every
createPage()(persistent headers are automatically re-applied bygoToPage).
🔧 Changed — CommonPage primitives (behavioural supersets)
getInputValuenow reads the live.valueproperty via JS. Fixes<textarea>reads and any field whose current value differs from the initialvalueattribute.selectOption/selectValuenow usequerySelector+ dispatchchange. Handle compound CSS selectors and drive select2 (previously only worked with a bare#id/.class).- New
setValueByJs($selector, $value)— reliable JS value-set (firesinput+change) for fields on inactive tabs or otherwise not focusable. setValue(real click+type) intentionally unchanged.
🐛 Fixed
- BackOffice login/menu against a live PS 9: correct selectors, French/English tolerance, sidebar sub-links resolve their real
<a>href instead of clicking a wrapping<li>. - Flaky BO login:
waitForPageReload()rewritten toPage::waitForReload(Page::LOAD, 10000)in a bounded try/catch (was evaluating a bogus JS string and hanging on chrome-php's 30s default). - Browser lifecycle across suites: keep the keep-alive browser open between suites; close it once per run in
ExecuteSuiteand clean the socket — series runs are now stable. - Session isolation per suite:
before()clears cookies via CDPNetwork.clearBrowserCookies. click()gets a JS-click fallback when a coordinate click can't reach the element (collapsed menu, etc.).- Self-signed HTTPS: Chrome launched with
ignoreCertificateErrors— no more "connection not private" screen against local Valet TLS. selectOptionno longer writes a straytemp.logdebug file at every call.- Product create field leak: price and quantity live on inactive Pricing/Stocks tabs; the old click+type couldn't focus them and leaked the text into the name field (products came out named
PF Edit Test9.9910with price 0). Now driven viasetValueByJs. - BackOffice orders row link properly scoped to
a[href*="/orders/"][href*="/view"](the customer link also ends in/view). - Tracking read/write: the shipping-edit modal must be opened to populate its form (carrier + CSRF token); the read re-opens the modal (its field pre-fills). The Carriers-tab display cell is lazy and unreliable to read headlessly.
- Locale propagation: scenarios now push their
localeto the suite ($testSuite->params['locale']) before importing pages, soimportPageresolves French friendly URLs on the FR demo shop (otherwise/login,/cart,/orderfell back to English and 404'd).
🐛 Fixed — cold-start & network resilience
- Retry the browser launch at cold start — avoids false-green runs when the initial CDP handshake fails ("Message could not be sent. Reason: the connection is closed").
- Retry
close+createPage+navigateingoToPage— swallows the sporadic cold-startgetTargetInfo() on nullfrom target enumeration. - Retry
getPage()on the same flake. - Basic Auth: enable
Networkdomain beforesetBasicAuthHeader(otherwise the header was silently dropped); install it at the connection level so it survivesgoToPage'screatePage. - Re-apply persistent HTTP headers after every
createPage()(Basic Auth / User-Agent leak-through fix). await setCookies()in cookie presets — deterministic before navigation.- Autoload from
bin/prestaflow: prefergetcwd()(project autoload) before the library's own vendor — fixes running the library installed as a Composer dep. - Composer symlink installs: project path resolution now handles repo symlinks correctly.
PRESTAFLOW_USER_AGENTis now honored ingetBrowser().
🧰 CI / DX
- CI-ready runs: non-zero exit on failure,
--junitreport. - New
--visual-report[=path]option — HTML + JSON visual-regression report. - Vendored
nunzion/php-expect(upstream became unreliable). - Screenshots on failure (helper + JUnit
<system-out>attachment).
🧪 Tests
- 78 browser-free structural tests / 377 assertions covering the page objects, scenarios, CommonPage primitives, VisualComparator, VisualReport.
- New suites additionally validated live against a local PrestaShop 9.0.0-rc.1 (French demo shop):
ProductsCrud4/4 ·CreateProductAndVerify4/4 ·CheckoutOrder5/5 ·OrderLifecycle9/9 ·GuestCheckout4/4 ·EditProduct4/4. All three critical suites re-run green after themainmerge — zero regression.
Full changelog: v1.3.0…v1.5.0
Test-shop notes for reviewers: uses the PrestaShop demo customer John DOE (pub@prestashop.com) with an address on file; offline payment modules must be enabled AND allowed for the destination country. For visual-regression baselines, use --visual-report and commit the persistent baseline folder alongside the suites.