diff --git a/api/blade-tasks/task_20260420070005_6d6234.json b/api/blade-tasks/task_20260420070005_6d6234.json index cd255cb9e..958f99093 100644 --- a/api/blade-tasks/task_20260420070005_6d6234.json +++ b/api/blade-tasks/task_20260420070005_6d6234.json @@ -5,8 +5,10 @@ "command": "Write-Host 'CRM ALERT: Day2: delta_today=0 < 500 (day 2 after reactivation)'; New-BurntToastNotification -Text 'WEVAL CRM', 'Day2: delta_today=0 < 500 (day 2 after reactivation)' -ErrorAction SilentlyContinue", "cmd": "Write-Host 'CRM ALERT: Day2: delta_today=0 < 500 (day 2 after reactivation)'; New-BurntToastNotification -Text 'WEVAL CRM', 'Day2: delta_today=0 < 500 (day 2 after reactivation)' -ErrorAction SilentlyContinue", "priority": "high", - "status": "dispatched", + "status": "failed_timeout", "created": "2026-04-20T07:00:05+00:00", "created_by": "blade-control-ui", - "dispatched_at": "2026-04-20T07:00:12+00:00" + "dispatched_at": "2026-04-20T07:00:12+00:00", + "failed_at": "2026-04-20T13:23:46+00:00", + "error": "Agent Blade did not callback task_done within 10min" } \ No newline at end of file diff --git a/api/blade-tasks/task_20260420080003_8504d5.json b/api/blade-tasks/task_20260420080003_8504d5.json index 3a0e6a30c..e41217ebf 100644 --- a/api/blade-tasks/task_20260420080003_8504d5.json +++ b/api/blade-tasks/task_20260420080003_8504d5.json @@ -5,8 +5,10 @@ "command": "\n# OVH S151 cancel via Blade Windows browser\n$url = 'https:\/\/www.ovh.com\/manager\/dedicated\/#\/configuration\/server'\nWrite-Host \"Opening OVH manager for S151 cancel review...\"\nStart-Process chrome -ArgumentList '--app=' + $url\nStart-Sleep 5\n# Notification\nNew-BurntToastNotification -Text 'WEVAL Auto', 'OVH S151 cancel - review needed. Log into OVH manager.' -ErrorAction SilentlyContinue\n", "cmd": "\n# OVH S151 cancel via Blade Windows browser\n$url = 'https:\/\/www.ovh.com\/manager\/dedicated\/#\/configuration\/server'\nWrite-Host \"Opening OVH manager for S151 cancel review...\"\nStart-Process chrome -ArgumentList '--app=' + $url\nStart-Sleep 5\n# Notification\nNew-BurntToastNotification -Text 'WEVAL Auto', 'OVH S151 cancel - review needed. Log into OVH manager.' -ErrorAction SilentlyContinue\n", "priority": "normal", - "status": "dispatched", + "status": "failed_timeout", "created": "2026-04-20T08:00:03+00:00", "created_by": "blade-control-ui", - "dispatched_at": "2026-04-20T08:00:06+00:00" + "dispatched_at": "2026-04-20T08:00:06+00:00", + "failed_at": "2026-04-20T13:23:46+00:00", + "error": "Agent Blade did not callback task_done within 10min" } \ No newline at end of file diff --git a/api/blade-tasks/task_20260420094335_39e0ab.json b/api/blade-tasks/task_20260420094335_39e0ab.json index c06fc9a7c..a5905a48d 100644 --- a/api/blade-tasks/task_20260420094335_39e0ab.json +++ b/api/blade-tasks/task_20260420094335_39e0ab.json @@ -5,8 +5,10 @@ "command": "# Open 3 Gmail drafts in Chrome (SSO actif, juste clic Send)\nStart-Process chrome -ArgumentList 'https:\/\/mail.google.com\/mail\/u\/0\/?view=cm&fs=1&tf=cm&to=kaouther.najar%40ethica.ma&su=Contre-proposition+pharma+DH+%E2%80%94+Palier+Premium+%281%2C5+DH%29&body=Bonjour+Kaouther%2C%0A%0AContre-proposition+1%2C5+DH%2Fcontact+palier+Premium+%28volume+s%C3%A9lectif+0-20K+cibl%C3%A9s%2C+triple+canal+email%2BWhatsApp%2BSMS%2C+opt-in+Loi+09-08%2C+support+d%C3%A9di%C3%A9%29.%0A%0ABase%3A+146%2C668+HCPs+valid%C3%A9s+%2B20K+en+7+jours.+Stack+souverain+Maroc.%0A%0AVoir+d%C3%A9tails+complets+sur+https%3A%2F%2Fweval-consulting.com%2Fkaouther-compose.html%0A%0ABien+cordialement%2C%0AYacine'\nStart-Sleep -Seconds 2\nStart-Process chrome -ArgumentList 'https:\/\/mail.google.com\/mail\/u\/0\/?view=cm&fs=1&tf=cm&to=kaouther.najar%40ethica.ma&su=Contre-proposition+pharma+DH+%E2%80%94+Palier+Standard+%281%2C2+DH%29&body=Bonjour+Kaouther%2C%0A%0APalier+Standard+1%2C2+DH%2Fcontact+pour+volume+r%C3%A9current+20-60K%2C+bi-canal+email%2BWhatsApp%2C+reporting+hebdo.%0A%0ASweet+spot+campagnes+trimestrielles.+DZ+107K+%2F+MA+20K+%2F+TN+18K+disponibles.%0A%0AD%C3%A9tails%3A+https%3A%2F%2Fweval-consulting.com%2Fkaouther-compose.html%0A%0ACordialement%2C%0AYacine'\nStart-Sleep -Seconds 2\nStart-Process chrome -ArgumentList 'https:\/\/mail.google.com\/mail\/u\/0\/?view=cm&fs=1&tf=cm&to=kaouther.najar%40ethica.ma&su=Contre-proposition+pharma+DH+%E2%80%94+Palier+Volume+%281%2C0+DH%29&body=Bonjour+Kaouther%2C%0A%0APalier+Volume+1%2C0+DH%2Fcontact+%2860K%2B+contacts%2C+6+mois+min%2C+email+principal+%2B+WhatsApp+%2B0%2C2+DH+option%29.%0A%0ACouvre+co%C3%BBts+infra%2BDB.+En-dessous+perte.%0A%0AD%C3%A9tails%3A+https%3A%2F%2Fweval-consulting.com%2Fkaouther-compose.html%0A%0ACordialement%2C%0AYacine'\nStart-Sleep -Seconds 2\nNew-BurntToastNotification -Text 'WEVAL Kaouther', '3 drafts ouverts dans Chrome - Prets a envoyer' -ErrorAction SilentlyContinue\nWrite-Host 'Kaouther drafts opened at $(Get-Date)'\n", "cmd": "# Open 3 Gmail drafts in Chrome (SSO actif, juste clic Send)\nStart-Process chrome -ArgumentList 'https:\/\/mail.google.com\/mail\/u\/0\/?view=cm&fs=1&tf=cm&to=kaouther.najar%40ethica.ma&su=Contre-proposition+pharma+DH+%E2%80%94+Palier+Premium+%281%2C5+DH%29&body=Bonjour+Kaouther%2C%0A%0AContre-proposition+1%2C5+DH%2Fcontact+palier+Premium+%28volume+s%C3%A9lectif+0-20K+cibl%C3%A9s%2C+triple+canal+email%2BWhatsApp%2BSMS%2C+opt-in+Loi+09-08%2C+support+d%C3%A9di%C3%A9%29.%0A%0ABase%3A+146%2C668+HCPs+valid%C3%A9s+%2B20K+en+7+jours.+Stack+souverain+Maroc.%0A%0AVoir+d%C3%A9tails+complets+sur+https%3A%2F%2Fweval-consulting.com%2Fkaouther-compose.html%0A%0ABien+cordialement%2C%0AYacine'\nStart-Sleep -Seconds 2\nStart-Process chrome -ArgumentList 'https:\/\/mail.google.com\/mail\/u\/0\/?view=cm&fs=1&tf=cm&to=kaouther.najar%40ethica.ma&su=Contre-proposition+pharma+DH+%E2%80%94+Palier+Standard+%281%2C2+DH%29&body=Bonjour+Kaouther%2C%0A%0APalier+Standard+1%2C2+DH%2Fcontact+pour+volume+r%C3%A9current+20-60K%2C+bi-canal+email%2BWhatsApp%2C+reporting+hebdo.%0A%0ASweet+spot+campagnes+trimestrielles.+DZ+107K+%2F+MA+20K+%2F+TN+18K+disponibles.%0A%0AD%C3%A9tails%3A+https%3A%2F%2Fweval-consulting.com%2Fkaouther-compose.html%0A%0ACordialement%2C%0AYacine'\nStart-Sleep -Seconds 2\nStart-Process chrome -ArgumentList 'https:\/\/mail.google.com\/mail\/u\/0\/?view=cm&fs=1&tf=cm&to=kaouther.najar%40ethica.ma&su=Contre-proposition+pharma+DH+%E2%80%94+Palier+Volume+%281%2C0+DH%29&body=Bonjour+Kaouther%2C%0A%0APalier+Volume+1%2C0+DH%2Fcontact+%2860K%2B+contacts%2C+6+mois+min%2C+email+principal+%2B+WhatsApp+%2B0%2C2+DH+option%29.%0A%0ACouvre+co%C3%BBts+infra%2BDB.+En-dessous+perte.%0A%0AD%C3%A9tails%3A+https%3A%2F%2Fweval-consulting.com%2Fkaouther-compose.html%0A%0ACordialement%2C%0AYacine'\nStart-Sleep -Seconds 2\nNew-BurntToastNotification -Text 'WEVAL Kaouther', '3 drafts ouverts dans Chrome - Prets a envoyer' -ErrorAction SilentlyContinue\nWrite-Host 'Kaouther drafts opened at $(Get-Date)'\n", "priority": "high", - "status": "dispatched", + "status": "failed_timeout", "created": "2026-04-20T09:43:35+00:00", "created_by": "blade-control-ui", - "dispatched_at": "2026-04-20T09:43:37+00:00" + "dispatched_at": "2026-04-20T09:43:37+00:00", + "failed_at": "2026-04-20T13:23:46+00:00", + "error": "Agent Blade did not callback task_done within 10min" } \ No newline at end of file diff --git a/api/blade-tasks/task_20260420_005630_53c51e.json b/api/blade-tasks/task_20260420_005630_53c51e.json index 0c530ee2f..330cfc498 100644 --- a/api/blade-tasks/task_20260420_005630_53c51e.json +++ b/api/blade-tasks/task_20260420_005630_53c51e.json @@ -4,14 +4,15 @@ "cmd": "\n$ErrorActionPreference = \"Continue\"\nWrite-Host \"[BLADE-RESEND] START $(Get-Date -Format 'HH:mm:ss')\"\n\n# Strategy: use Chrome's existing session via --remote-debugging-port attach\n# The user is already logged into Resend in their Chrome profile\n$chromeExe = \"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe\"\nif (!(Test-Path $chromeExe)) { $chromeExe = \"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe\" }\n$profilePath = \"$env:LOCALAPPDATA\\Google\\Chrome\\User Data\"\n\n# Kill existing Chrome to ensure debug port availability\nGet-Process chrome -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue\nStart-Sleep -Seconds 3\n\n# Restart Chrome with debug port + same user profile (keeps Resend cookie)\nStart-Process $chromeExe -ArgumentList \"--remote-debugging-port=9222\",\"--user-data-dir=$profilePath\",\"https:\/\/resend.com\/api-keys\" -WindowStyle Normal\nStart-Sleep -Seconds 7\n\n# Get WebSocket URL of the Resend tab via DevTools Protocol\ntry {\n $targets = Invoke-RestMethod -Uri \"http:\/\/localhost:9222\/json\" -Method GET -TimeoutSec 5\n $rt = $targets | Where-Object { $_.url -match \"resend.com\" } | Select-Object -First 1\n if (!$rt) { Write-Host \"[BLADE-RESEND] NO_RESEND_TAB\"; exit 1 }\n $wsUrl = $rt.webSocketDebuggerUrl\n Write-Host \"[BLADE-RESEND] CDP tab found\"\n} catch {\n Write-Host \"[BLADE-RESEND] CDP_ERR: $_\"\n exit 1\n}\n\n# JS to execute in the Resend tab via CDP\n$js = @\"\n(async () => {\n const s = (ms) => new Promise(r => setTimeout(r, ms));\n await s(2500);\n const btns = Array.from(document.querySelectorAll('button,a'));\n const add = btns.find(b => \/add api key|create api key\/i.test((b.textContent||'').trim()));\n if (!add) return {ok:false, err:'no_button', url:location.href};\n add.click();\n await s(2500);\n const nameIn = document.querySelector('input[name=\"name\"]') || document.querySelector('input[placeholder*=\"ame\"]');\n if (nameIn) {\n const setter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype,'value').set;\n setter.call(nameIn, 'wevia-master-blade-' + Date.now());\n nameIn.dispatchEvent(new Event('input',{bubbles:true}));\n }\n const labels = Array.from(document.querySelectorAll('*'));\n const full = labels.find(l => l.children.length === 0 && \/full access\/i.test((l.textContent||'').trim()));\n if (full) full.click();\n await s(700);\n const btns2 = Array.from(document.querySelectorAll('button'));\n const sub = btns2.reverse().find(b => \/^(add|create|save|generate)$\/i.test((b.textContent||'').trim()));\n if (sub) sub.click();\n await s(4500);\n const m = document.body.innerHTML.match(\/re_[a-zA-Z0-9_]{20,}\/);\n return {ok:!!m, key:m?m[0]:null, url:location.href};\n})()\n\"@\n\n# Send CDP command via WebSocket\n$ws = New-Object System.Net.WebSockets.ClientWebSocket\n$cts = New-Object System.Threading.CancellationTokenSource\n$cts.CancelAfter(30000)\n$ws.ConnectAsync([Uri]$wsUrl, $cts.Token).Wait()\n\n$cmdObj = @{\n id = 1\n method = \"Runtime.evaluate\"\n params = @{\n expression = $js\n awaitPromise = $true\n returnByValue = $true\n }\n}\n$cmdJson = $cmdObj | ConvertTo-Json -Depth 5 -Compress\n$cmdBuf = [System.Text.Encoding]::UTF8.GetBytes($cmdJson)\n$seg = New-Object 'System.ArraySegment[byte]' (,$cmdBuf)\n$ws.SendAsync($seg, [System.Net.WebSockets.WebSocketMessageType]::Text, $true, $cts.Token).Wait()\n\n# Receive\n$rxBuf = New-Object byte[] 131072\n$rxSeg = New-Object 'System.ArraySegment[byte]' (,$rxBuf)\n$result = $ws.ReceiveAsync($rxSeg, $cts.Token).Result\n$response = [System.Text.Encoding]::UTF8.GetString($rxBuf, 0, $result.Count)\nWrite-Host \"[BLADE-RESEND] CDP_RESP_LEN=$($response.Length)\"\n\ntry {\n $parsed = $response | ConvertFrom-Json\n $kd = $parsed.result.result.value\n if ($kd.ok -and $kd.key) {\n $nk = $kd.key\n Write-Host \"[BLADE-RESEND] KEY $($nk.Substring(0,10))...\"\n $body = @{action='set_key'; key=$nk} | ConvertTo-Json -Compress\n $save = Invoke-RestMethod -Uri \"https:\/\/weval-consulting.com\/api\/resend-send.php\" -Method POST -Body $body -ContentType \"application\/json\" -TimeoutSec 10\n Write-Host \"[BLADE-RESEND] SAVED $($save | ConvertTo-Json -Compress)\"\n # Trigger full setup on S204\n $setup = Invoke-RestMethod -Uri \"https:\/\/weval-consulting.com\/api\/wevia-master-api.php\" -Method POST -Body (@{message=\"resend full setup\"} | ConvertTo-Json) -ContentType \"application\/json\" -TimeoutSec 30\n Write-Host \"[BLADE-RESEND] FULL_SETUP $($setup | ConvertTo-Json -Compress -Depth 3)\"\n } else {\n Write-Host \"[BLADE-RESEND] FAIL $($kd | ConvertTo-Json -Compress)\"\n }\n} catch {\n Write-Host \"[BLADE-RESEND] PARSE_ERR $_\"\n Write-Host \"[BLADE-RESEND] RESP_SAMPLE $($response.Substring(0, [Math]::Min(600, $response.Length)))\"\n}\n\ntry { $ws.CloseAsync('NormalClosure','done',$cts.Token).Wait() } catch {}\nWrite-Host \"[BLADE-RESEND] END $(Get-Date -Format 'HH:mm:ss')\"\n", "label": "resend_fullaccess_cdp", "priority": 999, - "status": "dispatched", + "status": "failed_timeout", "created": "2026-04-20T00:56:30+00:00", "started": null, "completed": null, "result": null, - "error": null, + "error": "Agent Blade did not callback task_done within 10min", "source": "api", "bumped_by": "opus_v5.9.7_unstick", "bumped_at": "2026-04-20T02:57:40+00:00", - "dispatched_at": "2026-04-20T01:01:53+00:00" + "dispatched_at": "2026-04-20T01:01:53+00:00", + "failed_at": "2026-04-20T13:23:46+00:00" } \ No newline at end of file diff --git a/api/blade-tasks/task_20260420_005743_866051.json b/api/blade-tasks/task_20260420_005743_866051.json index bb8e7da7b..1daa6bae3 100644 --- a/api/blade-tasks/task_20260420_005743_866051.json +++ b/api/blade-tasks/task_20260420_005743_866051.json @@ -4,12 +4,13 @@ "cmd": "Write-Host \"[BLADE-RESEND-TEST] BEEP-PRIO-999 $(Get-Date -Format HH:mm:ss)\"; # Signal test only", "label": "opus_prio999_signal_test", "priority": 999, - "status": "dispatched", + "status": "failed_timeout", "created": "2026-04-20T00:57:43+00:00", "started": null, "completed": null, "result": null, - "error": null, + "error": "Agent Blade did not callback task_done within 10min", "source": "api", - "dispatched_at": "2026-04-20T01:02:01+00:00" + "dispatched_at": "2026-04-20T01:02:01+00:00", + "failed_at": "2026-04-20T13:23:46+00:00" } \ No newline at end of file diff --git a/api/blade-tasks/task_20260420_010415_b6775f.json b/api/blade-tasks/task_20260420_010415_b6775f.json index 1fbdc0097..c2e635667 100644 --- a/api/blade-tasks/task_20260420_010415_b6775f.json +++ b/api/blade-tasks/task_20260420_010415_b6775f.json @@ -4,12 +4,13 @@ "cmd": "Write-Host \"PING-OPUS\"; Invoke-RestMethod -Uri \"https:\/\/weval-consulting.com\/api\/cx\" -Method POST -Body @{k=\"WEVADS2026\"; c=[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes(\"date -Iseconds > \/tmp\/blade-ping-$(date +%s).txt\"))} -TimeoutSec 10; Write-Host \"PING-DONE\"", "label": "opus_ping_test", "priority": 9999, - "status": "dispatched", + "status": "failed_timeout", "created": "2026-04-20T01:04:15+00:00", "started": null, "completed": null, "result": null, - "error": null, + "error": "Agent Blade did not callback task_done within 10min", "source": "api", - "dispatched_at": "2026-04-20T01:04:23+00:00" + "dispatched_at": "2026-04-20T01:04:23+00:00", + "failed_at": "2026-04-20T13:23:46+00:00" } \ No newline at end of file diff --git a/api/blade-tasks/task_20260420_125809_26bcd1.json b/api/blade-tasks/task_20260420_125809_26bcd1.json index e520b4466..450906e59 100644 --- a/api/blade-tasks/task_20260420_125809_26bcd1.json +++ b/api/blade-tasks/task_20260420_125809_26bcd1.json @@ -4,12 +4,13 @@ "cmd": "\ntry { $targets = Invoke-RestMethod -Uri \"http:\/\/localhost:9222\/json\" -Method GET -TimeoutSec 5 }\ncatch { Write-Host \"NO_CHROME_DEBUG_PORT\"; exit 1 }\n$filter = ''\n$tgt = if ($filter) { $targets | Where-Object { $_.url -match $filter } | Select-Object -First 1 } else { $targets | Where-Object { $_.type -eq 'page' } | Select-Object -First 1 }\nif (!$tgt) { Write-Host \"NO_TAB_MATCH\"; exit 1 }\n$wsUrl = $tgt.webSocketDebuggerUrl\n$ws = New-Object System.Net.WebSockets.ClientWebSocket\n$cts = New-Object System.Threading.CancellationTokenSource\n$cts.CancelAfter(30000)\n$ws.ConnectAsync([Uri]$wsUrl, $cts.Token).Wait()\n$cmd = @{id=1; method=\"Runtime.evaluate\"; params=@{expression=@'\ndocument.title\n'@; awaitPromise=$true; returnByValue=$true}} | ConvertTo-Json -Depth 5 -Compress\n$buf = [Text.Encoding]::UTF8.GetBytes($cmd)\n$seg = New-Object 'System.ArraySegment[byte]' (,$buf)\n$ws.SendAsync($seg, [System.Net.WebSockets.WebSocketMessageType]::Text, $true, $cts.Token).Wait()\n$rxBuf = New-Object byte[] 131072\n$rxSeg = New-Object 'System.ArraySegment[byte]' (,$rxBuf)\n$result = $ws.ReceiveAsync($rxSeg, $cts.Token).Result\nWrite-Host ([Text.Encoding]::UTF8.GetString($rxBuf, 0, $result.Count))\n", "label": "mcp_cdp", "priority": 200, - "status": "dispatched", + "status": "failed_timeout", "created": "2026-04-20T12:58:09+00:00", "started": null, "completed": null, "result": null, - "error": null, + "error": "Agent Blade did not callback task_done within 10min", "source": "api", - "dispatched_at": "2026-04-20T12:58:14+00:00" + "dispatched_at": "2026-04-20T12:58:14+00:00", + "failed_at": "2026-04-20T13:23:46+00:00" } \ No newline at end of file diff --git a/api/playwright-v93-3pages-audit.json b/api/playwright-v93-3pages-audit.json new file mode 100644 index 000000000..8ded8a636 --- /dev/null +++ b/api/playwright-v93-3pages-audit.json @@ -0,0 +1,41 @@ +[ + { + "target": "agents-archi", + "url": "https://weval-consulting.com/login?r=/agents-archi.html", + "title": "WEVAL — Login", + "body_len": 89, + "canvas": 0, + "svg": 0, + "AG_len": null, + "DP_len": null, + "pattern_anon": 3, + "pattern_out": 0, + "js_errors": [] + }, + { + "target": "enterprise-model", + "url": "https://weval-consulting.com/enterprise-model.html", + "title": "WEVAL Enterprise Model", + "body_len": 429, + "canvas": 1, + "svg": 0, + "AG_len": 739, + "DP_len": 27, + "pattern_anon": 4, + "pattern_out": 4, + "js_errors": [] + }, + { + "target": "wevia-em-big4", + "url": "https://weval-consulting.com/login?r=/wevia-em-big4.html", + "title": "WEVAL — Login", + "body_len": 89, + "canvas": 0, + "svg": 0, + "AG_len": null, + "DP_len": null, + "pattern_anon": 3, + "pattern_out": 0, + "js_errors": [] + } +] \ No newline at end of file diff --git a/api/v83-business-kpi-latest.json b/api/v83-business-kpi-latest.json index 6d5a089e6..50fdeb512 100644 --- a/api/v83-business-kpi-latest.json +++ b/api/v83-business-kpi-latest.json @@ -1,7 +1,7 @@ { "ok": true, "version": "V83-business-kpi", - "ts": "2026-04-20T13:20:15+00:00", + "ts": "2026-04-20T13:24:40+00:00", "summary": { "total_categories": 7, "total_kpis": 56, diff --git a/api/v93_video_business.js b/api/v93_video_business.js new file mode 100644 index 000000000..f236f8083 --- /dev/null +++ b/api/v93_video_business.js @@ -0,0 +1,236 @@ +// V93 REAL VIDEO TEST · Selenium Chrome + video recording business scenario +// Tests the ACTUAL business flow post-V91/V92 fixes +const { chromium } = require('playwright'); +const fs = require('fs'); + +(async () => { + const browser = await chromium.launch({ + headless: true, + args: ['--disable-blink-features=AutomationControlled'] + }); + + const ctx = await browser.newContext({ + viewport: { width: 1920, height: 1080 }, + recordVideo: { + dir: '/tmp/v93-videos/', + size: { width: 1920, height: 1080 } + } + }); + + const page = await ctx.newPage(); + + // Set internal auth for badge/spotlight visibility + await page.addInitScript(() => { + try { localStorage.setItem('weval_internal', 'yacine-2026'); } catch(e){} + }); + + const scenarios = []; + const errs = []; + page.on('pageerror', e => errs.push(`[${new Date().toISOString()}] ${e.message}`)); + + async function scenario(name, fn) { + const t0 = Date.now(); + console.log(`▶ Starting: ${name}`); + try { + const r = await fn(); + const elapsed = Date.now() - t0; + scenarios.push({ name, status: 'OK', ms: elapsed, ...(r||{}) }); + console.log(`✓ ${name} (${elapsed}ms)`); + } catch (e) { + scenarios.push({ name, status: 'FAIL', err: e.message.substring(0, 300) }); + console.log(`✗ ${name}: ${e.message.substring(0, 100)}`); + } + } + + // === SCENARIO 1: ENTERPRISE MODEL (post-V91 TDZ fix) === + await scenario('S1_enterprise_model_post_v91', async () => { + await page.goto('https://weval-consulting.com/enterprise-model.html', { waitUntil: 'load', timeout: 30000 }); + await page.waitForTimeout(5000); // Let canvas render + + const diag = await page.evaluate(() => { + const canvas = document.querySelector('canvas'); + const body = document.body.innerText; + return { + title: document.title, + body_len: body.length, + canvas_exists: !!canvas, + canvas_w: canvas ? canvas.width : 0, + canvas_h: canvas ? canvas.height : 0, + ag_exists: typeof window.AG !== 'undefined', + dp_exists: typeof window.DP !== 'undefined', + ag_count: typeof window.AG !== 'undefined' ? window.AG.length : 0, + dp_count: typeof window.DP !== 'undefined' ? window.DP.length : 0, + }; + }); + + await page.screenshot({ path: '/tmp/v93-01-enterprise-model.png', fullPage: false }); + return diag; + }); + + // === SCENARIO 2: wevia-em-big4 (Big4 VSM) === + await scenario('S2_wevia_em_big4', async () => { + await page.goto('https://weval-consulting.com/wevia-em-big4.html', { waitUntil: 'load', timeout: 30000 }); + await page.waitForTimeout(4000); + + const diag = await page.evaluate(() => { + return { + title: document.title, + final_url: location.href, + body_len: document.body.innerText.length, + svg_count: document.querySelectorAll('svg').length, + canvas_count: document.querySelectorAll('canvas').length, + has_agents: document.body.innerText.match(/\d+\s*agents?/i) ? document.body.innerText.match(/\d+\s*agents?/i)[0] : null, + has_domains: ['Finance','HR','Marketing','Sales','Supply','Procurement','Production','IT','QA'].filter(d => document.body.innerText.includes(d)).length, + auth_gated: location.href.includes('/login'), + }; + }); + + await page.screenshot({ path: '/tmp/v93-02-wevia-em-big4.png', fullPage: false }); + return diag; + }); + + // === SCENARIO 3: Business KPI Dashboard (full flow) === + await scenario('S3_business_kpi_full', async () => { + await page.goto('https://weval-consulting.com/business-kpi-dashboard.php', { waitUntil: 'load', timeout: 30000 }); + await page.waitForTimeout(5000); + + const diag = await page.evaluate(() => { + return { + title: document.title, + charts_svg: document.querySelectorAll('svg').length, + charts_canvas: document.querySelectorAll('canvas').length, + body_len: document.body.innerText.length, + has_revenue: document.body.innerText.includes('Revenue') || document.body.innerText.includes('MRR'), + badge_loaded: window.__WEVAL_META_BADGE_LOADED === true, + }; + }); + + // Scroll to capture full page + await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight)); + await page.waitForTimeout(2000); + await page.screenshot({ path: '/tmp/v93-03-business-kpi.png', fullPage: true }); + + return diag; + }); + + // === SCENARIO 4: WEVIA Master chat interaction === + await scenario('S4_wevia_master_interact', async () => { + await page.goto('https://weval-consulting.com/wevia-master.html', { waitUntil: 'load', timeout: 30000 }); + await page.waitForTimeout(4000); + + // Find chat input + const chatInput = await page.$('textarea, input[type="text"]'); + const hasInput = chatInput !== null; + + if (hasInput) { + await chatInput.fill('nr status'); + await page.waitForTimeout(1000); + // Submit (try Enter or submit button) + await chatInput.press('Enter'); + await page.waitForTimeout(5000); // Wait for response + } + + const diag = await page.evaluate(() => { + return { + title: document.title, + hasChatInput: !!document.querySelector('textarea, input[type="text"]'), + responseCount: document.body.innerText.split('\n').filter(l => l.length > 20).length, + bodyLen: document.body.innerText.length, + }; + }); + + await page.screenshot({ path: '/tmp/v93-04-wevia-master.png', fullPage: false }); + return { ...diag, submitted: hasInput }; + }); + + // === SCENARIO 5: CRM business data === + await scenario('S5_crm_unified', async () => { + await page.goto('https://weval-consulting.com/crm.html', { waitUntil: 'load', timeout: 30000 }); + await page.waitForTimeout(3000); + + const diag = await page.evaluate(() => { + return { + title: document.title, + body_len: document.body.innerText.length, + has_deals: /deal|pipeline|opportunité|opportunity/i.test(document.body.innerText), + has_contacts: /contact|company|société/i.test(document.body.innerText), + }; + }); + + await page.screenshot({ path: '/tmp/v93-05-crm.png', fullPage: true }); + return diag; + }); + + // === SCENARIO 6: 15 Depts KPI === + await scenario('S6_depts_data', async () => { + const r = await page.request.get('https://weval-consulting.com/api/wevia-v64-departments-kpi.php'); + const j = await r.json(); + return { + http: r.status(), + agents: `${j.summary.agents_wired}/${j.summary.agents_needed}`, + gap_pct: j.summary.gap_ratio_pct, + global_maturity: j.summary.global_maturity_pct, + depts_count: j.departments ? j.departments.length : 0, + }; + }); + + // === SCENARIO 7: Manifest system health === + await scenario('S7_manifest_health', async () => { + const r = await page.request.get('https://weval-consulting.com/api/weval-archi-manifest.php'); + const j = await r.json(); + return { + http: r.status(), + nr: `${j.meta_health.nr_combined.pass}/${j.meta_health.nr_combined.total}`, + sigma: j.meta_health.nr_combined.sigma, + disk_pct: j.meta_health.disk.used_pct, + servers: (j.servers || []).length, + databases: (j.databases || []).length, + dashboards: (j.dashboards || []).length, + }; + }); + + // === SCENARIO 8: WTP point entrée === + await scenario('S8_WTP_entry', async () => { + await page.goto('https://weval-consulting.com/weval-technology-platform.html', { waitUntil: 'load', timeout: 30000 }); + await page.waitForTimeout(3000); + + const diag = await page.evaluate(() => { + return { + title: document.title, + final_url: location.href, + has_login: location.href.includes('/login') || !!document.querySelector('input[type="password"]'), + }; + }); + + await page.screenshot({ path: '/tmp/v93-08-wtp.png', fullPage: false }); + return diag; + }); + + await ctx.close(); // Close context to flush video + await browser.close(); + + const summary = { + ts: new Date().toISOString(), + test: 'V93 REAL VIDEO BUSINESS SCENARIO', + scenarios, + js_errors: errs.slice(0, 10), + total_ok: scenarios.filter(s => s.status === 'OK').length, + total_fail: scenarios.filter(s => s.status === 'FAIL').length, + video_dir: '/tmp/v93-videos/', + screenshots: [ + '/tmp/v93-01-enterprise-model.png', + '/tmp/v93-02-wevia-em-big4.png', + '/tmp/v93-03-business-kpi.png', + '/tmp/v93-04-wevia-master.png', + '/tmp/v93-05-crm.png', + '/tmp/v93-08-wtp.png', + ], + }; + + fs.writeFileSync('/var/www/html/api/playwright-v93-video-business.json', JSON.stringify(summary, null, 2)); + console.log(''); + console.log('=== V93 SUMMARY ==='); + console.log(`OK: ${summary.total_ok}/${scenarios.length} · FAIL: ${summary.total_fail}`); + console.log(`JS errors: ${errs.length}`); + console.log(`Video dir: ${summary.video_dir}`); +})(); diff --git a/api/v97-linkedin-control.php b/api/v97-linkedin-control.php index 66a9b94b1..92f9bf51d 100644 --- a/api/v97-linkedin-control.php +++ b/api/v97-linkedin-control.php @@ -222,6 +222,35 @@ case 'all_queues': ],JSON_PRETTY_PRINT); break; + +case 'browser_publish_id': + $id = escapeshellarg($_POST['id'] ?? $_GET['id'] ?? ''); + $out = shell_exec("cd /tmp && timeout 90 python3 /opt/weval-l99/v98-linkedin-browser-publish.py publish_id $id 2>&1"); + $data = @json_decode(trim($out), true); + echo json_encode($data ?: ['ok'=>false,'raw'=>substr($out,0,300)], JSON_PRETTY_PRINT); + break; + +case 'browser_publish_due': + $out = shell_exec("cd /tmp && timeout 180 python3 /opt/weval-l99/v98-linkedin-browser-publish.py publish_due 2>&1"); + $data = @json_decode(trim($out), true); + echo json_encode($data ?: ['ok'=>false,'raw'=>substr($out,0,300)], JSON_PRETTY_PRINT); + break; + +case 'browser_session_status': + $cookies = '/opt/weval-l99/browser-sessions/linkedin/Default/Cookies'; + echo json_encode([ + 'session_exists' => file_exists($cookies), + 'last_update' => file_exists($cookies) ? date('c', filemtime($cookies)) : null, + 'age_hours' => file_exists($cookies) ? round((time()-filemtime($cookies))/3600, 1) : null, + ]); + break; + +case 'browser_inject_session': + $out = shell_exec("cd /tmp && timeout 60 python3 /opt/weval-l99/v98-linkedin-session-inject.py 2>&1"); + $data = @json_decode(trim($out), true); + echo json_encode($data ?: ['raw' => substr($out, 0, 300)], JSON_PRETTY_PRINT); + break; + default: - echo json_encode(['err'=>'unknown_action','available'=>['overview','approve','schedule','publish_now','reject','auto_publish_due','log','all_queues']]); + echo json_encode(['err'=>'unknown_action','available'=>['overview','approve','schedule','publish_now','reject','auto_publish_due','log','all_queues','browser_publish_id','browser_publish_due','browser_session_status','browser_inject_session']]); }