All checks were successful
CI/CD / detect-changes (push) Successful in 4s
CI/CD / test-runners (push) Has been skipped
CI/CD / e2e-smoke (push) Has been skipped
CI/CD / test-frontend (push) Successful in 6s
CI/CD / test-go-pg (push) Successful in 2m49s
CI/CD / test-sqlite (push) Successful in 3m4s
CI/CD / build-and-deploy (push) Successful in 1m15s
Co-authored-by: Jeffrey Smith <jasafpro@gmail.com> Co-committed-by: Jeffrey Smith <jasafpro@gmail.com>
178 lines
7.0 KiB
Bash
Executable File
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
|