Skip to content

Demo Minimal Mode (QA / Testing Bypass)

Overview

Demo Minimal (demo-minimal) is one of three QA demo-mode bypass values, alongside demo-standard and demo-full. It is not a real POS provider and has no backend implementation. It is a front-office-only test harness that lets QA engineers and Playwright skip the POS-connection requirement so they can reach and test post-onboarding features (orders, menus, online ordering, etc.) without setting up a real POS integration.

It works by setting a localStorage flag (qa_demo_provider) that the app reads to simulate a "POS connected" state. demo-minimal simulates a Square-style connection (the QA-mode reference describes it as the "no prerequisites, fastest setup" option).

Important: This bypass is active only in non-production environments (VITE_ENV of local or testing). It is completely inert in staging and production — the isTestEnv guard ensures the code never runs there. It is not selectable from the onboarding UI and never appears as a provider option to real merchants.


Integration Type

  • Scope: Front-office QA bypass only (no backend integration, no real POS)
  • Simulates: A connected POS so hasPOSConnected returns true
  • Payment Processing: None (no real or simulated payments)
  • Auto-created data: None — the flag does not create a location, menu, payment profile, or any merchant data. It only simulates the "POS connected" / onboarding-complete state in the front-office store.
  • Environments: local, testing only (disabled in staging, production)

How It Works (code-backed)

When isTestEnv is true and localStorage['qa_demo_provider'] is one of the demo channels (demo-minimal, demo-standard, demo-full):

  1. Onboarding state is simulated as completed. The fetchOnboardingState action returns a demo state of { pos_provider: <demo value>, phase: 'completed', setup_steps: [], completed_steps: [], answers: {} } instead of calling the Emily onboarding API. This unlocks post-POS features.
  2. The demo provider is treated as a connected in-house channel. The getAvailableInHouseChannelKeys getter injects the demo provider key into the channel list, so hasPOSConnected-style checks pass.
  3. POS_CHANNELS includes the demo channels in test env. In test environments POS_CHANNELS is ['hendrickx', 'vanhoutte', 'square', 'shopcaisse', 'mpluskassa', 'lightspeed', 'demo-minimal', 'demo-standard', 'demo-full']; in production it is only ['hendrickx', 'vanhoutte', 'mpluskassa', 'lightspeed'].
  4. Emily widget detects QA mode. EmilyWidget.vue checks the same flag and lets the (simulated) completed state drive its phase rather than running discovery.

There is no discovery conversation, no per-mode setup-step list, and no auto-population of demo data tied to this flag. It is purely a state simulation.


Prerequisites

None — that is the point of the bypass. It deliberately skips the real onboarding prerequisites (which, for real providers, include a branding profile and a location; payment and billing profiles are optional). See the Guided Setup and Locations features for the real onboarding requirements.


Demo Mode Values

ValueSimulatesQA reference note
demo-minimalSquareNo prerequisites, fastest setup
demo-standardMplusKassa / ShopcaisseBranding required
demo-fullHendrickx / VanhoutteBrand + Billing + Location required

These mappings come from the QA Demo Mode reference in the back-office repo (docs/QA_DEMO_MODE.md). All three values resolve to the same code path — they only differ in which real provider's setup they are meant to stand in for during testing.


What Gets Unlocked

When the bypass is active:

  • hasPOSConnected returns true
  • The onboarding state reports phase: 'completed'
  • Post-POS UI becomes accessible (orders, menus, online ordering, etc.)

No merchant records are created; the bypass only changes how the front office evaluates connection/onboarding state.


Enabling / Disabling (Playwright & manual)

Set or clear the qa_demo_provider localStorage flag, then reload:

javascript
// Enable QA demo mode
localStorage.setItem('qa_demo_provider', 'demo-minimal')
location.reload()

// Disable QA demo mode
localStorage.removeItem('qa_demo_provider')
location.reload()

In Playwright tests the flag is set via page.evaluate. For example, an existing e2e page object enables a demo provider with:

typescript
await page.evaluate(() => localStorage.setItem('qa_demo_provider', 'demo-standard'))

There is no ?demo=minimal URL parameter and no /dashboard?demo=minimal entry point. The flag is read from localStorage only.


Source of Truth (code references)

  • Demo channel list & POS_CHANNELS gating: upvendo-backoffice/src/store/modules/app.ts (DEMO_POS_CHANNELS, POS_CHANNELS)
  • Onboarding-state simulation: app.tsfetchOnboardingState action (returns the completed demo state when the flag is set in test env)
  • Channel-key injection: app.tsgetAvailableInHouseChannelKeys getter
  • isTestEnv definition: upvendo-backoffice/src/config/helpers.ts (!['production', 'staging'].includes(import.meta.env.VITE_ENV))
  • Emily QA-mode detection: upvendo-backoffice/src/components/emily/EmilyWidget.vue
  • QA-mode reference doc: upvendo-backoffice/docs/QA_DEMO_MODE.md
  • Tests: upvendo-backoffice/test/store/modules/app.test.ts, upvendo-backoffice/e2e/pages/devices.page.ts

Notes / Not Verified Here

  • Account signup, sales, and demo-environment provisioning narratives are not part of this code path and are not verified here. This flag does not create a demo merchant, seed data, or stand up an environment.
  • For seeding real test merchants (a separate mechanism, not this flag), see the backend E2E account seeder; that is outside the scope of this QA bypass.
  • For the real onboarding flow (POS selection, discovery, the per-provider setup checklist, and automatic completion detection), see the Guided Setup feature. The genuine "minimal" real-provider path is Square's (branding → connect Square → review imported locations).