Skip to content

Demo Full Provider (QA / Testing Bypass)

Overview

Demo Full (demo-full) is one of three QA-only "demo POS" channels — alongside demo-minimal and demo-standard — used to bypass onboarding so that QA and Playwright tests can exercise post-POS features (online ordering, menus, kiosk, etc.) without performing a real POS setup.

It is not a real onboarding flow and it does not require a prerequisite chain. When active, the back office simply simulates a connected POS and a completed onboarding so the rest of the app behaves as if setup is done.

Important: Demo Full only works in non-production environments. It is gated by isTestEnv (true when VITE_ENV is not production or staging) and is activated only through a localStorage flag. It is never offered in production and never appears in the customer-facing guided-setup POS grid.

Source of truth: src/store/modules/app.ts (DEMO_POS_CHANNELS, fetchOnboardingState, getAvailableInHouseChannelKeys, POS_CHANNELS) and src/components/emily/EmilyWidget.vue (isQADemoMode).


How It Works

  • Activation: Set the browser localStorage key qa_demo_provider to demo-full (or demo-minimal / demo-standard). There is no URL parameter and no UI control for this — it is a manual/test-harness flag.

  • Channel injection (app.ts, getAvailableInHouseChannelKeys): in test env, if qa_demo_provider holds a demo channel, that key is injected into the available in-house channel keys so the app treats the POS as connected. POS_CHANNELS also includes the demo channels in test env so hasPOSConnected checks pass.

  • Simulated onboarding state (app.ts, fetchOnboardingState): in test env with a demo provider set, the store short-circuits and commits a demo onboarding state instead of calling the real Emily onboarding API:

    js
    {
      pos_provider: 'demo-full',
      phase: 'completed',   // onboarding done — post-POS features accessible
      setup_steps: [],       // no steps
      completed_steps: [],
      answers: {}
    }
  • Emily widget (EmilyWidget.vue, isQADemoMode): when qa_demo_provider is a demo channel and the env is a test env, QA demo mode is active and the widget lets the (simulated) store state drive the onboarding phase. Outside test environments isQADemoMode always returns false.

The net effect: pre-POS steps are skipped and the merchant is treated as fully onboarded with a connected POS.


Integration Type

  • Scope: QA bypass (no real integration; simulates a connected POS for the selected merchant/location)
  • Environment: Test/non-production only (isTestEnv); never production or staging
  • Prerequisites: None enforced. The demo state reports phase: 'completed' with empty setup_steps, so branding, billing, payment, and location steps are not required to proceed
  • Payment Processing: None (no payment configuration is created)
  • Menu Sync: None (no demo menu is auto-created)

The three demo channels differ only by name (demo-minimal, demo-standard, demo-full); the code path is identical for all three. There is no demo-specific discovery flow, no per-channel step list, and no auto-provisioning of data.


Relation to the Real Guided-Setup Flow

Demo Full does not appear in the guided-setup POS selection grid. That grid is driven by POS_PROVIDERS in src/components/dialogs/guided-setup/types.ts, which lists:

  • Production: Upvendo POS, Hendrickx, Vanhoutte
  • Development/testing: those plus Square, Shopcaisse, MplusKassa, Lightspeed K-Series

POS_PROVIDERS / PRODUCTION_POS_PROVIDERS now begin with the first-party upvendo entry, but neither is a live provider list: they are read only by POSSelectionGrid.vue, which renders inside EmilyGuidedSetupDialog — a component imported and registered in App.vue but absent from its template and referenced nowhere else as a tag, so it never renders (Emily's modal registry maps guided-setup to a different component, emilyModalRegistry.ts:139). The list a merchant actually sees comes from GET /back-office/merchant/reseller-providers. The first-party provider is server-gated regardless: staged test_only (config/pos-providers.php:51-52), so in production only merchants flagged is_test are offered it.

The real onboarding wizard, its per-POS step lists, automatic completion detection, and the GET /api/back-office/setup-status endpoint are described in the Guided Setup feature doc. Demo Full intentionally sidesteps all of that for testing; it is not a step in that flow.


Backend

There is no backend support for the demo providers. demo-minimal / demo-standard / demo-full exist only in the back-office frontend (app.ts and EmilyWidget.vue) and have no controller, config entry, or persisted record on the backend. The simulated onboarding state lives in the front-end store only.


Playwright / Test Usage

Activate the bypass before loading the back office so the app treats the POS as connected and onboarding as complete:

typescript
// Enable the QA demo bypass (test environments only)
await page.evaluate(() => {
  localStorage.setItem('qa_demo_provider', 'demo-full')
})

// Reload so the store reads the flag and simulates a connected POS
await page.reload()

// Post-POS features are now reachable without real setup, e.g.:
await page.goto('/online/online-ordering')
await page.goto('/menus/menu-builder')
await page.goto('/device-management/devices')

// Clear the flag to return to normal behavior
await page.evaluate(() => localStorage.removeItem('qa_demo_provider'))

Notes:

  • This only has effect when VITE_ENV is not production or staging.
  • There is no ?demo=full URL parameter; the localStorage key is the only mechanism.
  • demo-minimal and demo-standard behave the same way; the value is stored on the simulated state's pos_provider but does not change the flow.

Not Verified Here

The following are outside the back-office/backend code and are not verified by this audit: any sales, signup, or demo-environment provisioning process; how a "demo merchant" account is seeded; and any narrative about Hendrickx/Vanhoutte-style "real" onboarding being mirrored by this provider. In code, Demo Full is strictly a front-end test bypass and mirrors none of the real prerequisite chain.