Now opens a blank article editor modal with the category pre-selected (stored in localStorage). You can fill in the article details and create a new article directly from the folder view without navigating away.
alps

Automation End-to-End Testing Guide

9 min readInvalid Date35 views

Automation End-to-End Testing Guide

Prerequisites

Info

Fresh authentication token (expires in ~1 hour). Try hardcoding variable value in message - If that works, interpolation is broken - If that doesn't work, step execution is broken

Warning

Fresh authentication token (expires in ~1 hour). Try hardcoding variable value in message - If that works, interpolation is broken - If that doesn't work, step execution is broken

Success

Fresh authentication token (expires in ~1 hour). Try hardcoding variable value in message - If that works, interpolation is broken - If that doesn't work, step execution is broken

Error

Fresh authentication token (expires in ~1 hour). Try hardcoding variable value in message - If that works, interpolation is broken - If that doesn't work, step execution is broken

<strong>Required:</strong>

  • Fresh authentication token (expires in ~1 hour)
  • Workspace ID: <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">UIDRinD8Ef8UK1pxvdlv</code>
  • Automation ID: <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">xjDJ2Haamnapqf9V7Y4h</code>
  • Test widget key (inbox/channel ID the automation is attached to)
  • Localhost backend running on port 3030
  • Browser dev console open to monitor real-time messages

Phase 1: Pre-Test Verification

1.1 Verify Automation Structure

bash
curl -X GET http://localhost:3030/api/v1/automations/xjDJ2Haamnapqf9V7Y4h \
  -H "Authorization: Bearer <FRESH_TOKEN>" | jq '.data'

<strong>Verify these fields are present:</strong>

  • ✅ <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">trigger</code> — the entry point (e.g., conversation<em>created, message</em>received, etc.)
  • ✅ <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">triggerNextStepId</code> — points to first step after trigger
  • ✅ <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">steps</code> — array of all step objects
  • ✅ <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">channels</code> — array of channels trigger applies to
  • ✅ <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">frequency</code> — every<em>time / once</em>per<em>contact / once</em>per_conversation
  • ✅ <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">schedule</code> — { type: 'any<em>time' | 'office</em>hours' | 'custom', ... }
  • ✅ <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">audienceFilters</code> — filtering rules { logic: 'AND'|'OR', groups: [...] }
  • ✅ <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">goal</code> — success metric { enabled: bool, type, window }
  • ✅ <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">status</code> — must be 'live' to trigger

Phase 2: Trigger Testing

Scenario 2.1: Initial Trigger Activation

<strong>Setup:</strong>

  1. Open test page with widget (or create test contact widget at <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">localhost:3000</code>)
  2. Widget loads with test key
  3. Watch browser console for Pusher messages

<strong>Action:</strong>

  • Send first message from widget as <strong>anonymous visitor</strong>
  • Message: "Hello" (simple starter)

<strong>Expected Flow:</strong>

  1. ✅ Backend creates new conversation
  2. ✅ Automation <strong>trigger matches</strong> (conversation_created fires)
  3. ✅ Backend creates enrollment record
  4. ✅ First step after trigger begins executing
  5. ✅ Pusher event fires: <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">workflowQuestion</code> or <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">workflowChoices</code> or <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">message:new</code>
  6. ✅ Widget receives event and updates UI

<strong>What to Watch:</strong>

  • Browser console: <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">Pusher <private-conversation-ID> message:new</code>
  • Browser console: <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">Pusher <private-conversation-ID> workflowQuestion</code> (if ask_question)
  • Browser console: <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">Pusher <private-conversation-ID> workflowChoices</code> (if choices)
  • Backend logs: no errors during step execution

<strong>Common Bugs:</strong>

  • ❌ No Pusher event fired → step executor failed
  • ❌ Event fired but widget doesn't update → subscription issue
  • ❌ Trigger doesn't fire at all → status not 'live' or frequency/schedule blocked

Scenario 2.2: Frequency Control

<strong>Test:</strong> Ensure frequency setting prevents duplicate automations

<strong>Setup:</strong>

  • Automation frequency = "once<em>per</em>contact"

<strong>Action:</strong>

  1. Send message #1: "Hi"

- ✅ Automation should trigger

  1. Send message #2: "Hi again"

- ❌ Automation should NOT trigger again (frequency blocks it)

<strong>Expected:</strong>

  • First message: automation runs
  • Subsequent messages from same contact: automation skipped

<strong>Verify in Firestore:</strong>

  • Check <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">enrollments</code> collection
  • Contact should have only 1 enrollment for this automation
  • Status: 'completed' or 'in_progress'

Scenario 2.3: Schedule Control

<strong>Setup:</strong>

  • Automation schedule = "office_hours" (9am-5pm)
  • Test outside office hours

<strong>Action:</strong>

  • Send message at 6:00 PM
  • ❌ Automation should NOT trigger (schedule blocks it)

<strong>Verify:</strong>

  • Check backend logs for schedule evaluation
  • Message arrives but automation enrollment not created

Phase 3: Step Execution Testing

Scenario 3.1: ask_question Step

<strong>Setup:</strong>

  • First step after trigger = <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">ask_question</code>
  • Question text: "What is your name?"
  • Variable name: <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">user_name</code>

<strong>Action:</strong>

  1. Send message: "Hello"
  2. Automation triggers
  3. Bot asks: "What is your name?"
  4. <strong>WAIT</strong> — automation pauses

<strong>Expected:</strong>

  1. ✅ Message appears in widget conversation
  2. ✅ Conversation conversation has <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">workflow.awaitingQuestion = true</code>
  3. ✅ Conversation has <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">workflow.questionVariableName = 'user_name'</code>
  4. ✅ Widget shows <strong>input mode</strong> or question UI

<strong>What Breaks:</strong>

  • ❌ Question doesn't appear → step didn't execute
  • ❌ Question appears but widget crashes → UI doesn't handle event
  • ❌ Response gets lost → resumeQuestion handler failed

Scenario 3.2: Resuming From ask_question

<strong>Setup:</strong> (continuing from 3.1)

<strong>Action:</strong>

  1. User types response: "John"
  2. Submit via widget

<strong>Expected Flow:</strong>

  1. ✅ Widget sends POST to <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">/api/v1/automations/question/answer</code>

<code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em"></code>`json<br> {<br> "conversationId": "...",<br> "answer": "John",<br> "variableName": "user_name",<br> "enrollmentId": "..."<br> }<br> <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em"></code>`

  1. ✅ Backend resumes automation from pause point
  2. ✅ Variable <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">user_name</code> = "John" available to next steps
  3. ✅ "John" response is saved to conversation messages
  4. ✅ Next step executes

<strong>What to Monitor:</strong>

  • ✅ User's response appears in conversation as message
  • ✅ Check Firestore <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">conversations.workflow.variables.user_name</code> = "John"
  • ✅ Check <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">enrollments.variables.user_name</code> = "John"

<strong>Common Issues:</strong>

  • ❌ Response doesn't appear in conversation → message creation failed
  • ❌ Variable not stored → resumeQuestion didn't save it properly
  • ❌ Automation doesn't continue → nextStepId not set

Scenario 3.3: choices Step

<strong>Setup:</strong>

  • After ask_question, choices step appears
  • Prompt: "Which service do you need?"
  • Choices: ["Billing", "Technical Support", "Sales"]
  • Branches: 3 branches (one per choice)

<strong>Action:</strong>

  1. Bot sends: "Which service do you need?"
  2. Widget shows <strong>choice buttons</strong>
  3. User clicks "Billing"

<strong>Expected:</strong>

  1. ✅ Prompt appears as bot message
  2. ✅ Conversation has <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">workflow.awaitingChoice = true</code>
  3. ✅ Conversation has <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">workflow.currentChoices = ["Billing", "Technical Support", "Sales"]</code>
  4. ✅ Conversation has <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">workflow.choiceConnections</code> = [nextStepId1, nextStepId2, nextStepId3]

<strong>What to Monitor:</strong>

  • Browser console: <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">Pusher workflowChoices</code> event
  • Widget displays choice buttons
  • Each button is clickable

Scenario 3.4: Resuming From choices

<strong>Action:</strong>

  1. User clicks "Billing"

<strong>Expected Flow:</strong>

  1. ✅ Widget POST to <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">/api/v1/automations/choice/select</code>
javascript
   `json   {     "conversationId": "...",     "selectedChoiceIndex": 0,     "variableName": "last_choice",     "enrollmentId": "..."   }   `
  1. ✅ Automation branches to choice[0].nextStepId
  2. ✅ "Billing" selection appears in conversation
  3. ✅ Next step in Billing branch executes

<strong>Verify in Firestore:</strong>

  • Choice selection saved to messages (either as user message or bot message)
  • Variable <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">last_choice</code> = "Billing"
  • Enrollment continues on correct branch

Phase 4: Action Steps Testing

Scenario 4.1: send_message Action

<strong>Setup:</strong>

  • Step after choices: <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">send_message</code>
  • Content: "You selected {{last_choice}}. We'll connect you soon!"

<strong>Action:</strong>

  1. Trigger automation through full flow
  2. Select a choice
  3. Wait for message

<strong>Expected:</strong>

  1. ✅ Message appears in conversation
  2. ✅ Content interpolates variable: "You selected Billing. We'll connect you soon!"
  3. ✅ Message has <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">senderType = 'bot'</code>

<strong>Common Issues:</strong>

  • ❌ Variable not interpolated → context.variables not passed
  • ❌ Message doesn't appear → step executor failed

Scenario 4.2: assign Step

<strong>Setup:</strong>

  • After choices: <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">assign</code> step
  • Assign to: "Billing" inbox (from choices)
  • Message: "Routing to {{last_choice}} team..."

<strong>Action:</strong>

  1. Trigger automation to assignment step
  2. Select "Billing"

<strong>Expected:</strong>

  1. ✅ Conversation routed to Billing inbox
  2. ✅ <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">conversation.inboxId</code> = billingInboxId
  3. ✅ Notification message appears: "Routing to Billing team..."
  4. ✅ Agent sees conversation in Billing inbox

<strong>Verify:</strong>

  • Check Firestore conversation.inboxId
  • Check agent inbox (might need to refresh)

Scenario 4.3: route<em>to</em>inbox Step

<strong>Setup:</strong>

  • Step: <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">route<em>to</em>inbox</code>
  • Config: map choices to specific inboxes

- "Billing" → Billing Inbox<br> - "Technical Support" → Support Inbox<br> - "Sales" → Sales Inbox

<strong>Action:</strong>

  1. Full automation flow, select choice
  2. Step routes to mapped inbox

<strong>Expected:</strong>

  1. ✅ Conversation moves to selected inbox
  2. ✅ Assignment message appears
  3. ✅ Agent can see conversation

Scenario 4.4: Condition Branching

<strong>Setup:</strong>

  • After choices, condition step
  • Condition: "If last_choice == 'Technical Support', then..."
  • True branch: technical support flow
  • False branch: sales flow

<strong>Action:</strong>

  1. Choose "Technical Support"
  2. Follow automation

<strong>Expected:</strong>

  1. ✅ Condition evaluates to true
  2. ✅ Automation follows <strong>true branch</strong>
  3. ✅ Technical support actions execute

<strong>Test All Branches:</strong>

  • ✅ last_choice = "Billing" → false branch
  • ✅ last_choice = "Sales" → false branch
  • ✅ last_choice = "Technical Support" → true branch

Phase 5: End-to-End Scenario Testing

Scenario 5.1: Complete "Route to Support" Flow

<strong>Full Path:</strong>

plaintext
Trigger (conversation_created)
  ↓
ask_question: "What is your name?"  [PAUSE]
  ↓ [User: "John"]
send_message: "Thanks, John!"
  ↓
choices: "Which service?"  [PAUSE]
  ↓ [User: "Technical Support"]
condition: if last_choice == "Technical Support"
  ↓ [TRUE]
assign: route to Support inbox
  ↓
send_message: "Connecting to support team..."
  ↓
[COMPLETED]

<strong>Manual Test Steps:</strong>

  1. [ ] Load widget
  2. [ ] Send: "Hi"

- Verify: Bot asks "What is your name?"

  1. [ ] Send: "John"

- Verify: "Thanks, John!" appears<br> - Verify: Choice buttons appear

  1. [ ] Click: "Technical Support"

- Verify: "Connecting to support team..." appears<br> - Verify: Conversation moves to Support inbox

  1. [ ] Check inbox: Conversation should appear in Support

<strong>Monitor for Bugs:</strong>

  • [ ] Variables not available in interpolation
  • [ ] Messages in wrong order
  • [ ] Condition branching wrong
  • [ ] Inbox assignment fails
  • [ ] Pusher events delayed

Phase 6: Error Scenarios

Scenario 6.1: Missing Required Data

<strong>Setup:</strong>

  • Automation with variables in actions

<strong>Action:</strong>

  1. Skip ask<em>question step (jump to send</em>message using variable)
  2. Variable not defined

<strong>Expected:</strong>

  • ❌ Message appears with empty variable: "You selected ." (graceful degradation)
  • OR ✅ Error logged, message not sent

<strong>What to Monitor:</strong>

  • Check <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">enrollments.variables</code> object
  • Verify interpolation handles missing variables

Scenario 6.2: Inbox Not Found

<strong>Setup:</strong>

  • assign step references non-existent inbox ID

<strong>Action:</strong>

  1. Trigger automation to assignment

<strong>Expected:</strong>

  • ❌ Error logged in backend
  • ❌ Conversation NOT assigned
  • ❌ Automation should not crash

<strong>Verify:</strong>

  • Check backend logs for error
  • Check conversation status (should remain open, not assigned)

Scenario 6.3: Agent Offline / Unavailable

<strong>Setup:</strong>

  • assign step to specific agent
  • Agent is offline

<strong>Action:</strong>

  1. Trigger automation to assignment

<strong>Expected:</strong>

  • ✅ Conversation assigned anyway (no availability check)
  • OR ⚠️ Queue conversation for next available agent (if implemented)

Phase 7: Variable & Context Testing

Scenario 7.1: Contact Attributes in Messages

<strong>Setup:</strong>

  • Contact created with phone, company, language
  • Automation message: "Hello {{contact.firstName}}, from {{contact.company}}"

<strong>Action:</strong>

  1. Send message as logged-in contact

<strong>Expected:</strong>

  • ✅ Message: "Hello John, from Acme Inc"

Scenario 7.2: Conversation Attributes in Conditions

<strong>Setup:</strong>

  • Condition: if conversation.language == "fr"
  • Contact set language to French

<strong>Action:</strong>

  1. Trigger automation

<strong>Expected:</strong>

  • ✅ Condition evaluates correctly based on contact.language

Phase 8: Performance & Real-Time

Scenario 8.1: Message Latency

<strong>Setup:</strong>

  • Automation with multiple steps
  • Browser dev tools Performance tab open

<strong>Action:</strong>

  1. Send message to trigger
  2. Measure time for response to appear

<strong>Expected:</strong>

  • Bot response appears within 2-3 seconds
  • No janky rendering or lag

Scenario 8.2: Concurrent Conversations

<strong>Setup:</strong>

  • Multiple browser tabs / incognito windows
  • Each with different visitor identities

<strong>Action:</strong>

  1. Send message in each tab
  2. Different automations should run independently

<strong>Expected:</strong>

  • ✅ Each conversation enrolls in automation separately
  • ✅ Variables don't leak between conversations
  • ✅ All receive responses correctly

Debugging Checklist

If automation doesn't trigger:

bash
# 1. Check automation status
curl http://localhost:3030/api/v1/automations/xjDJ2Haamnapqf9V7Y4h \
  -H "Authorization: Bearer <TOKEN>" | jq '.data.status'
# Should be: "live"

# 2. Check trigger matches
curl http://localhost:3030/api/v1/automations/xjDJ2Haamnapqf9V7Y4h \
  -H "Authorization: Bearer <TOKEN>" | jq '.data.trigger'
# Should have: type, config

# 3. Check enrollment created
# Look in Firestore → enrollments
# Filter by: conversationId & automationId
# Should have status "in_progress" or "paused"

If step doesn't execute:

  1. Check Firestore <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">enrollments.{enrollmentId}</code>

- Look at <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">currentStepId</code> — is it correct?<br> - Look at <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">variables</code> — did previous steps run?

  1. Check backend logs

- Search for <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">[AutomationEngine]</code><br> - Look for step executor errors

  1. Check Pusher events

- Browser console: <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">Pusher <channel> <event></code><br> - Should see <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">message:new</code>, <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">workflowQuestion</code>, etc.

If variable not available:

  1. Check enrollment.variables object

- Should contain variableName = value

  1. Check context passed to step

- Backend logs should show context.variables

  1. Test interpolation

- Try hardcoding variable value in message<br> - If that works, interpolation is broken<br> - If that doesn't work, step execution is broken

Success Criteria

✅ <strong>Automation is working when:</strong>

  • [ ] Trigger fires correctly
  • [ ] First step executes (question/choice/action)
  • [ ] ask_question pauses and resumes correctly
  • [ ] Choices branch correctly
  • [ ] Variables are saved and available
  • [ ] Assignments route to correct inboxes
  • [ ] Messages appear in conversation
  • [ ] Multiple conversations don't interfere
  • [ ] No console errors
  • [ ] Pusher events arrive in real-time

❌ <strong>Bugs to report:</strong>

  • Variables not interpolating
  • Steps not executing in order
  • Branching takes wrong path
  • Assignments go to wrong inbox
  • Messages appear out of order
  • Automation stops mid-flow
  • Variables disappear
  • Slow responses (>5s)

Next Steps

  1. <strong>Get fresh token</strong> — current one expired
  2. <strong>Run Phase 2</strong> — verify automation structure is correct
  3. <strong>Run Phase 3</strong> — test basic steps (ask_question, choices)
  4. <strong>Run Phase 5</strong> — full end-to-end scenario
  5. <strong>Document bugs</strong> found and their exact steps to reproduce
  6. <strong>Create Firestore queries</strong> to verify enrollment state

Did this answer your question?