Architecture & Mechanics

Test Garden operates on a decoupled, secure parent-child communication model. The parent dashboard manages test suites, Supabase database storage, and execution states, while the child iframe renders your website and runs the injected tracker script.


Secure Communication Protocol

Because the child iframe runs on your website's domain and the dashboard runs on testgarden.dev, browsers block direct script access across the frames due to the Same-Origin Policy.

To bypass this securely, Test Garden utilizes the HTML5 window.postMessage API with strict origin and token validation.

Protocol Interaction Steps
1
parent ➔ db

1. Generate short-lived Temp Token

2
parent ➔ child

2. Load URL with ?tg_token=TEMP_TOKEN

3
Internal Action

Injected script initializes

4
child ➔ child

3. Save Temp Token in sessionStorage

5
child ➔ parent

4. Post Message "TG_READY" + Current URL

6
Internal Action

Validate origin and token

7
parent ➔ child

5. Post Message "START_RECORDING"

8
Internal Action

Capture clicks/inputs

9
child ➔ parent

6. Post Message "TG_EVENT" (click/type details)

10
parent ➔ db

7. Save step in public.test_steps


1. Dashboard Initialization & Handshake

When you click Record or Run in the dashboard:

  1. Token Generation: The backend generates a temporary cryptographically secure recording token (temp_token) in Supabase.
  2. Iframe Boot: The dashboard loads your website inside the workspace iframe, appending the token to the query string: https://myclientapp.com/?tg_token=TEMP_RECORDING_TOKEN
  3. Session Cache: The injected script testgarden-recorder.js running inside the client website reads tg_token from the URL parameters and immediately caches it in sessionStorage. This ensures the token persists even if the user clicks links or navigates to other pages within the iframe.
  4. Handshake Confirmation: The script posts a TG_READY message back to the parent window (testgarden.dev), confirming the page has loaded. The parent verifies the domain and token before unlocking the recording controls.

2. Real-Time Interaction Recording

When recording is active:

  • Event Listeners: The tracker registers event listeners on click, input, change, scroll, and hover events.
  • Selector Generation: When an interaction occurs, the script computes a robust, clean CSS selector. It filters out dynamic Tailwind utility classes, keeping only ID or structural semantic classes, and automatically escapes special characters using CSS.escape().
  • Payload Stream: The event details (action type, CSS selector, coordinates, text value, and the temporary token) are posted back to the dashboard via postMessage.
  • Supabase Storage: The dashboard validates the message payload and saves it to the test_steps table.

3. Playback Simulation

To replay a test:

  1. The dashboard resets the iframe to the initial starting URL.
  2. Once the script fires TG_READY on load, the dashboard reads the saved steps from Supabase.
  3. For each step, the dashboard posts a PLAY_STEP payload to the iframe.
  4. The tracker queries the element in the DOM using the saved selector and dispatches a programmatically generated trusted event (e.g., new MouseEvent('click') or updates values dynamically).
  5. If an assertion step is received, the script fetches computed styles or element text and sends the validation results back to the dashboard.

Was this page helpful?