This repository has been archived on 2026-04-03. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
core/ci/e2e-workflow-nochat.sh
Jeffrey Smith 446edb8333 Feat v0.9.6 deprecate stage_type, collapse stage_mode
stage_type no longer validated — starlark_hook presence determines
automation. stage_mode collapsed from 4→3 values (form/delegated/
automated); "review" mapped to "form" on input for backward compat.
Migration 018 converts existing rows. Review surface removed (~110
lines). 4 package manifests updated.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 17:41:55 +00:00

178 lines
7.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# ═══════════════════════════════════════════════
# E2E Workflow Test — Without Chat
# ═══════════════════════════════════════════════
#
# Verifies the complete workflow lifecycle works without chat or
# chat-core packages installed. Uses only admin API + PAT auth.
#
# Proves: workflow independence from optional packages.
#
# Prerequisites:
# - Server running at $SERVER_URL (default: http://localhost:3000)
# - ADMIN_USER / ADMIN_PASS env vars (default: admin/admin)
#
# Exit codes: 0 = all assertions passed, 1 = failures detected
set -euo pipefail
SERVER_URL="${SERVER_URL:-http://localhost:3000}"
ADMIN_USER="${ADMIN_USER:-admin}"
ADMIN_PASS="${ADMIN_PASS:-admin}"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
PASS=0
FAIL=0
assert() {
local desc="$1" ok="$2"
if [ "$ok" = "true" ]; then
echo -e " ${GREEN}${NC} $desc"
PASS=$((PASS + 1))
else
echo -e " ${RED}${NC} $desc"
FAIL=$((FAIL + 1))
fi
}
echo -e "${YELLOW}═══ E2E Workflow Independence Test ═══${NC}"
echo " Server: ${SERVER_URL}"
# ── Authenticate ─────────────────────────────
TOKEN=""
PAT_FILE="/tmp/armature-admin-pat.txt"
if [ -f "$PAT_FILE" ]; then
TOKEN=$(cat "$PAT_FILE")
fi
if [ -z "$TOKEN" ]; then
TOKEN=$(curl -sf -X POST "${SERVER_URL}/api/v1/auth/login" \
-H "Content-Type: application/json" \
-d "{\"login\":\"${ADMIN_USER}\",\"password\":\"${ADMIN_PASS}\"}" \
| node -e "process.stdin.resume(); let d=''; process.stdin.on('data',c=>d+=c); process.stdin.on('end',()=>{try{console.log(JSON.parse(d).token)}catch(e){process.exit(1)}})" 2>/dev/null || true)
fi
if [ -z "$TOKEN" ]; then
echo -e "${RED}Failed to authenticate${NC}"
exit 1
fi
echo -e "${GREEN}Authenticated${NC}"
AUTH="Authorization: Bearer ${TOKEN}"
# ── Verify chat is NOT installed ─────────────
echo -e "\n${YELLOW}Phase 1: Verify chat packages not required${NC}"
CHAT_PKG=$(curl -sf -H "$AUTH" "${SERVER_URL}/api/v1/admin/packages" \
| node -e "process.stdin.resume(); let d=''; process.stdin.on('data',c=>d+=c); process.stdin.on('end',()=>{
const pkgs = JSON.parse(d).data || JSON.parse(d);
const chat = (Array.isArray(pkgs) ? pkgs : []).filter(p => p.id === 'chat' || p.id === 'chat-core');
console.log(JSON.stringify(chat));
})" 2>/dev/null || echo "[]")
echo " Chat packages found: ${CHAT_PKG}"
# ── Create a test workflow ───────────────────
echo -e "\n${YELLOW}Phase 2: Create workflow via admin API${NC}"
WF_RESP=$(curl -sf -X POST "${SERVER_URL}/api/v1/workflows" \
-H "$AUTH" -H "Content-Type: application/json" \
-d '{
"name": "E2E No-Chat Test",
"slug": "e2e-nochat-test",
"description": "Workflow independence E2E test",
"entry_mode": "public_link",
"is_active": true
}' 2>/dev/null || echo '{"error":"failed"}')
WF_ID=$(echo "$WF_RESP" | node -e "process.stdin.resume(); let d=''; process.stdin.on('data',c=>d+=c); process.stdin.on('end',()=>{try{console.log(JSON.parse(d).id||'')}catch(e){console.log('')}})" 2>/dev/null)
assert "Workflow created" "$([ -n "$WF_ID" ] && echo true || echo false)"
if [ -z "$WF_ID" ]; then
echo -e "${RED}Cannot continue without workflow ID${NC}"
echo "Response: ${WF_RESP}"
exit 1
fi
# ── Add a form stage ─────────────────────────
echo -e "\n${YELLOW}Phase 3: Add form stage${NC}"
STAGE_RESP=$(curl -sf -X POST "${SERVER_URL}/api/v1/workflows/${WF_ID}/stages" \
-H "$AUTH" -H "Content-Type: application/json" \
-d '{
"name": "Intake Form",
"stage_mode": "form",
"ordinal": 0,
"form_template": {
"fields": [
{"key": "title", "type": "text", "label": "Issue Title", "required": true},
{"key": "description", "type": "textarea", "label": "Description"}
]
}
}' 2>/dev/null || echo '{"error":"failed"}')
STAGE_ID=$(echo "$STAGE_RESP" | node -e "process.stdin.resume(); let d=''; process.stdin.on('data',c=>d+=c); process.stdin.on('end',()=>{try{console.log(JSON.parse(d).id||'')}catch(e){console.log('')}})" 2>/dev/null)
assert "Form stage created" "$([ -n "$STAGE_ID" ] && echo true || echo false)"
# ── Add a review stage ───────────────────────
REVIEW_RESP=$(curl -sf -X POST "${SERVER_URL}/api/v1/workflows/${WF_ID}/stages" \
-H "$AUTH" -H "Content-Type: application/json" \
-d '{
"name": "Manager Review",
"stage_mode": "form",
"ordinal": 1
}' 2>/dev/null || echo '{"error":"failed"}')
REVIEW_ID=$(echo "$REVIEW_RESP" | node -e "process.stdin.resume(); let d=''; process.stdin.on('data',c=>d+=c); process.stdin.on('end',()=>{try{console.log(JSON.parse(d).id||'')}catch(e){console.log('')}})" 2>/dev/null)
assert "Review stage created" "$([ -n "$REVIEW_ID" ] && echo true || echo false)"
# ── Landing page responds ────────────────────
echo -e "\n${YELLOW}Phase 4: Landing page accessible${NC}"
LANDING_STATUS=$(curl -so /dev/null -w "%{http_code}" "${SERVER_URL}/w/global/e2e-nochat-test" 2>/dev/null || echo "000")
assert "Landing page returns 200" "$([ "$LANDING_STATUS" = "200" ] && echo true || echo false)"
# ── Start workflow via public API ────────────
echo -e "\n${YELLOW}Phase 5: Start workflow (public entry)${NC}"
START_RESP=$(curl -sf -X POST "${SERVER_URL}/api/v1/workflow-entry/global/e2e-nochat-test" \
-H "Content-Type: application/json" \
-d '{}' 2>/dev/null || echo '{"error":"failed"}')
INST_ID=$(echo "$START_RESP" | node -e "process.stdin.resume(); let d=''; process.stdin.on('data',c=>d+=c; process.stdin.on('end',()=>{try{console.log(JSON.parse(d).id||'')}catch(e){console.log('')}})" 2>/dev/null)
assert "Instance created" "$([ -n "$INST_ID" ] && echo true || echo false)"
# ── Workflow page renders ────────────────────
echo -e "\n${YELLOW}Phase 6: Workflow execution page${NC}"
if [ -n "$INST_ID" ]; then
WF_PAGE_STATUS=$(curl -so /dev/null -w "%{http_code}" "${SERVER_URL}/w/${INST_ID}" 2>/dev/null || echo "000")
assert "Workflow page returns 200" "$([ "$WF_PAGE_STATUS" = "200" ] && echo true || echo false)"
fi
# ── Cleanup: delete workflow ─────────────────
echo -e "\n${YELLOW}Cleanup${NC}"
curl -sf -X DELETE "${SERVER_URL}/api/v1/workflows/${WF_ID}" \
-H "$AUTH" >/dev/null 2>&1 || true
echo -e " Deleted test workflow"
# ── Summary ──────────────────────────────────
echo ""
TOTAL=$((PASS + FAIL))
if [ $FAIL -eq 0 ]; then
echo -e "${GREEN}═══ All ${TOTAL} assertions passed ═══${NC}"
exit 0
else
echo -e "${RED}═══ ${FAIL}/${TOTAL} assertions failed ═══${NC}"
exit 1
fi