Files
AOS/aos-verify5.sh
Z User e45b68bb8b feat: IMAP mail sync with thread-to-contact matching (PRD §6.1)
Real IMAP connection via imapflow library:
- Connects to IMAP server (IMAPFlow, TLS on port 993)
- Fetches recent messages (configurable limit, default 20)
- Extracts: from, fromEmail, subject, date, snippet (200 chars)
- Thread-to-contact matching (PRD §6.1):
  1. Match sender email against persons table
  2. If no person match, extract domain and match against company.website
  3. Returns matchedCompany + matchedPerson for each email
- Audit-logged (action: crm.mailsync:imap)
- Zod validated (host, port, user, password, folder, limit)
- 502 on IMAP connection failure with detail
- 400 on validation failure

Tested: invalid creds → 502 'IMAP connection failed', missing host → 400
2026-10-27 22:50:50 +00:00

179 lines
7.9 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# Cleaner verification: robust selectors, screenshot analysis of each new feature.
set -u
cd /home/z/my-project
BASE=http://127.0.0.1:3000
SHOTS=/home/z/my-project/aos-shots
mkdir -p "$SHOTS"
echo "=== Start server + reseed ==="
pkill -f "next dev" 2>/dev/null; sleep 1
bun run dev > dev.log 2>&1 &
SRV=$!
for i in $(seq 1 90); do curl -s -o /dev/null "$BASE/" 2>/dev/null && break; sleep 1; done
echo " ready after ${i}s"
curl -s -X POST "$BASE/api/aos/seed" >/dev/null 2>&1 && echo " reseeded"
sleep 2
agent-browser open "$BASE/" >/dev/null 2>&1
agent-browser wait --load networkidle >/dev/null 2>&1 || true
agent-browser wait 2500 >/dev/null 2>&1
agent-browser set viewport 1440 900 >/dev/null 2>&1
echo ""
echo "=== TEST 1: Audit view ==="
agent-browser snapshot -i >/tmp/s.txt 2>&1
AUDREF=$(grep -i 'button "Audit-Protokoll"' /tmp/s.txt | grep -oE 'ref=e[0-9]+' | head -1)
agent-browser click "$AUDREF" >/dev/null 2>&1
agent-browser wait 2500 >/dev/null 2>&1
H1=$(agent-browser get text h1 2>/dev/null | head -1)
echo " H1=$H1"
agent-browser screenshot --full "$SHOTS/v4-audit.png" >/dev/null 2>&1 && echo " shot OK"
echo ""
echo "=== TEST 2: CRM → company drawer ==="
agent-browser snapshot -i >/tmp/s.txt 2>&1
CRMREF=$(grep -i 'button "CRM"' /tmp/s.txt | grep -oE 'ref=e[0-9]+' | head -1)
agent-browser click "$CRMREF" >/dev/null 2>&1
agent-browser wait 2000 >/dev/null 2>&1
# click Firmen tab
agent-browser snapshot -i >/tmp/s.txt 2>&1
TABREF=$(grep -i 'tab "Firmen"' /tmp/s.txt | grep -oE 'ref=e[0-9]+' | head -1)
echo " Firmen tab: $TABREF"
[ -n "$TABREF" ] && agent-browser click "$TABREF" >/dev/null 2>&1
agent-browser wait 1500 >/dev/null 2>&1
# click first company row by finding a button/link in tbody
agent-browser snapshot -i >/tmp/s.txt 2>&1
# find buttons that contain company names — use eval to click first tbody row
agent-browser eval "document.querySelector('tbody tr')?.click()" >/dev/null 2>&1
agent-browser wait 2000 >/dev/null 2>&1
agent-browser screenshot --full "$SHOTS/v4-company-drawer.png" >/dev/null 2>&1 && echo " shot OK"
DRAWER=$(agent-browser eval "!!document.querySelector('[role=dialog]') ? 'OPEN' : 'CLOSED'" 2>/dev/null | tail -1)
echo " drawer state: $DRAWER"
# close drawer
agent-browser press Escape >/dev/null 2>&1
agent-browser wait 500 >/dev/null 2>&1
echo ""
echo "=== TEST 3: Create Deal modal ==="
agent-browser snapshot -i >/tmp/s.txt 2>&1
# find the "Deal" button in the page header
DEALBTN=$(grep -i 'button "Deal"' /tmp/s.txt | grep -oE 'ref=e[0-9]+' | head -1)
echo " Deal button: $DEALBTN"
[ -n "$DEALBTN" ] && agent-browser click "$DEALBTN" >/dev/null 2>&1
agent-browser wait 1500 >/dev/null 2>&1
agent-browser screenshot --full "$SHOTS/v4-create-deal.png" >/dev/null 2>&1 && echo " shot OK"
MODAL=$(agent-browser eval "!!document.querySelector('[role=dialog]') ? 'OPEN' : 'CLOSED'" 2>/dev/null | tail -1)
echo " modal state: $MODAL"
# fill the title input
agent-browser snapshot -i >/tmp/s.txt 2>&1
TITLEREF=$(grep -iE 'textbox' /tmp/s.txt | grep -iE 'Titel|z.B' | head -1 | grep -oE 'ref=e[0-9]+' | head -1)
echo " title input: $TITLEREF"
if [ -n "$TITLEREF" ]; then
agent-browser fill "$TITLEREF" "E2E Test-Deal" >/dev/null 2>&1
agent-browser wait 500 >/dev/null 2>&1
agent-browser screenshot --full "$SHOTS/v4-create-deal-filled.png" >/dev/null 2>&1 && echo " filled shot OK"
fi
agent-browser press Escape >/dev/null 2>&1
agent-browser wait 500 >/dev/null 2>&1
echo ""
echo "=== TEST 4: Finance → invoice dialog → finalize ==="
agent-browser snapshot -i >/tmp/s.txt 2>&1
FINREF=$(grep -i 'button "Finanzen"' /tmp/s.txt | grep -oE 'ref=e[0-9]+' | head -1)
agent-browser click "$FINREF" >/dev/null 2>&1
agent-browser wait 2000 >/dev/null 2>&1
agent-browser eval "document.querySelector('tbody tr')?.click()" >/dev/null 2>&1
agent-browser wait 1500 >/dev/null 2>&1
agent-browser screenshot --full "$SHOTS/v4-invoice-dialog.png" >/dev/null 2>&1 && echo " shot OK"
DIALOG=$(agent-browser eval "document.querySelector('[role=dialog]')?.textContent?.slice(0,120) || 'closed'" 2>/dev/null | tail -1)
echo " dialog: $(echo "$DIALOG" | head -c 120)"
agent-browser press Escape >/dev/null 2>&1
agent-browser wait 500 >/dev/null 2>&1
echo ""
echo "=== TEST 5: Projects → add task + log time ==="
agent-browser snapshot -i >/tmp/s.txt 2>&1
PROJREF=$(grep -i 'button "Projekte"' /tmp/s.txt | grep -oE 'ref=e[0-9]+' | head -1)
agent-browser click "$PROJREF" >/dev/null 2>&1
agent-browser wait 2000 >/dev/null 2>&1
# find the task input by placeholder
agent-browser snapshot -i >/tmp/s.txt 2>&1
TASKINPUT=$(grep -iE 'textbox.*Neue' /tmp/s.txt | head -1 | grep -oE 'ref=e[0-9]+' | head -1)
echo " task input: $TASKINPUT"
if [ -n "$TASKINPUT" ]; then
agent-browser fill "$TASKINPUT" "E2E-Aufgabe" >/dev/null 2>&1
agent-browser wait 500 >/dev/null 2>&1
agent-browser find text "Hinzufügen" click >/dev/null 2>&1
agent-browser wait 2500 >/dev/null 2>&1
echo " task added"
fi
agent-browser screenshot --full "$SHOTS/v4-projects-task.png" >/dev/null 2>&1 && echo " shot OK"
# switch to time tab and log time
agent-browser snapshot -i >/tmp/s.txt 2>&1
TIMETAB=$(grep -i 'tab "Zeit"' /tmp/s.txt | grep -oE 'ref=e[0-9]+' | head -1)
[ -n "$TIMETAB" ] && agent-browser click "$TIMETAB" >/dev/null 2>&1
agent-browser wait 1500 >/dev/null 2>&1
agent-browser snapshot -i >/tmp/s.txt 2>&1
DESCINPUT=$(grep -iE 'textbox.*Beschreibung|textbox.*SSO' /tmp/s.txt | head -1 | grep -oE 'ref=e[0-9]+' | head -1)
MININPUT=$(grep -iE 'spinbutton.*Minuten|textbox.*90' /tmp/s.txt | head -1 | grep -oE 'ref=e[0-9]+' | head -1)
echo " desc input: $DESCINPUT, min input: $MININPUT"
if [ -n "$DESCINPUT" ] && [ -n "$MININPUT" ]; then
agent-browser fill "$DESCINPUT" "E2E-Zeitbuchung" >/dev/null 2>&1
agent-browser fill "$MININPUT" "60" >/dev/null 2>&1
agent-browser wait 500 >/dev/null 2>&1
agent-browser find text "Buchen" click >/dev/null 2>&1
agent-browser wait 2500 >/dev/null 2>&1
echo " time logged"
fi
agent-browser screenshot --full "$SHOTS/v4-projects-time.png" >/dev/null 2>&1 && echo " time shot OK"
echo ""
echo "=== TEST 6: Command palette global search ==="
agent-browser eval "window.dispatchEvent(new KeyboardEvent('keydown',{key:'k',metaKey:true}))" >/dev/null 2>&1
agent-browser wait 1000 >/dev/null 2>&1
agent-browser snapshot -i >/tmp/s.txt 2>&1
PALINPUT=$(grep -iE 'textbox.*Suche|textbox.*Firmen' /tmp/s.txt | head -1 | grep -oE 'ref=e[0-9]+' | head -1)
echo " palette input: $PALINPUT"
if [ -n "$PALINPUT" ]; then
agent-browser fill "$PALINPUT" "Hamburg" >/dev/null 2>&1
agent-browser wait 1500 >/dev/null 2>&1
agent-browser screenshot --full "$SHOTS/v4-command-search.png" >/dev/null 2>&1 && echo " shot OK"
agent-browser snapshot -i >/tmp/s.txt 2>&1
echo " --- search result count ---"
grep -ciE "Firmen|Rechnungen|Projekte|Leads|Ansprech" /tmp/s.txt
fi
agent-browser press Escape >/dev/null 2>&1
echo ""
echo "=== TEST 7: Leads → approve → convert ==="
agent-browser snapshot -i >/tmp/s.txt 2>&1
LEADSREF=$(grep -i 'button "Leads Finder' /tmp/s.txt | grep -oE 'ref=e[0-9]+' | head -1)
agent-browser click "$LEADSREF" >/dev/null 2>&1
agent-browser wait 2500 >/dev/null 2>&1
# click Genehmigen
agent-browser find text "Genehmigen" click >/dev/null 2>&1
agent-browser wait 2000 >/dev/null 2>&1
# now a Convert button should appear
agent-browser screenshot --full "$SHOTS/v4-lead-approved.png" >/dev/null 2>&1 && echo " approved shot OK"
agent-browser find text "In CRM konvertieren" click >/dev/null 2>&1
agent-browser wait 3000 >/dev/null 2>&1
agent-browser screenshot --full "$SHOTS/v4-lead-converted.png" >/dev/null 2>&1 && echo " converted shot OK"
echo ""
echo "=== Errors ==="
agent-browser errors 2>&1 | head -10
echo "--- console (last 5) ---"
agent-browser console 2>&1 | tail -5
echo ""
echo "=== Cleanup ==="
agent-browser close >/dev/null 2>&1
kill $SRV 2>/dev/null
echo "=== dev.log (errors only) ==="
grep -iE "error|⨯|500" dev.log | tail -8
echo ""
echo "=== Screenshots ==="
ls -la "$SHOTS"/v4-* 2>/dev/null | tail -12
echo "=== DONE ==="