1- <!doctype html>
1+ <!DOCTYPE html>
22< html lang ="en ">
3+
34< head >
4- < meta charset ="utf-8 ">
5- < meta name ="viewport " content ="width=device-width, initial-scale=1 ">
6- < title > Portal Demo App</ title >
7- < link rel ="stylesheet " href ="/style.css ">
5+ < meta charset ="UTF-8 ">
6+ < meta name ="viewport " content ="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no ">
7+ < meta name ="apple-mobile-web-app-capable " content ="yes ">
8+ < meta name ="mobile-web-app-capable " content ="yes ">
9+ < title > Portal Demo Connectivity</ title >
10+ < link rel ="stylesheet " href ="style.css ">
811</ head >
12+
913< body >
10- < main class ="shell ">
11- < header >
12- < p class ="eyebrow "> Portal Demo</ p >
13- < h1 > Relay-backed demo application</ h1 >
14- < p > Use this page to verify static assets, cookies, fetches, and websocket echo.</ p >
15- </ header >
16-
17- < section class ="card ">
18- < h2 > HTTP</ h2 >
19- < button id ="ping "> Fetch /api/ping</ button >
20- < button id ="cookies "> Set cookies</ button >
21- < pre id ="output "> Ready.</ pre >
22- </ section >
23-
24- < section class ="card ">
25- < h2 > WebSocket</ h2 >
26- < input id ="ws-input " value ="hello portal ">
27- < button id ="ws-send "> Send</ button >
28- < pre id ="ws-output "> Disconnected.</ pre >
29- </ section >
30- </ main >
31-
32- < script >
33- const output = document . getElementById ( 'output' ) ;
34- const wsOutput = document . getElementById ( 'ws-output' ) ;
35-
36- document . getElementById ( 'ping' ) . addEventListener ( 'click' , async ( ) => {
37- const res = await fetch ( '/api/ping' ) ;
38- output . textContent = JSON . stringify ( await res . json ( ) , null , 2 ) ;
39- } ) ;
40-
41- document . getElementById ( 'cookies' ) . addEventListener ( 'click' , async ( ) => {
42- const res = await fetch ( '/api/test-cookies' ) ;
43- output . textContent = JSON . stringify ( await res . json ( ) , null , 2 ) ;
44- } ) ;
45-
46- const proto = location . protocol === 'https:' ? 'wss://' : 'ws://' ;
47- const ws = new WebSocket ( proto + location . host + '/ws' ) ;
48- ws . onopen = ( ) => { wsOutput . textContent = 'Connected.' ; } ;
49- ws . onmessage = ( event ) => { wsOutput . textContent = event . data ; } ;
50- ws . onclose = ( ) => { wsOutput . textContent = 'Disconnected.' ; } ;
51-
52- document . getElementById ( 'ws-send' ) . addEventListener ( 'click' , ( ) => {
53- ws . send ( document . getElementById ( 'ws-input' ) . value ) ;
54- } ) ;
55- </ script >
14+ < div class ="container ">
15+ < h1 > Portal Demo Connectivity</ h1 >
16+
17+ < div class ="toolbar ">
18+ < button id ="httpPingBtn "> HTTP Ping</ button >
19+ < button id ="testCookiesBtn "> Test Cookies</ button >
20+ < button id ="wsConnectBtn "> WS Connect</ button >
21+ < button id ="wsSendBtn " disabled > WS Send "hello"</ button >
22+ </ div >
23+
24+ < div class ="canvas-wrapper ">
25+ < pre id ="log " class ="log "> </ pre >
26+ </ div >
27+
28+ < div id ="status " class ="status "> Idle</ div >
29+ </ div >
30+
31+ < script >
32+ const statusEl = document . getElementById ( 'status' ) ;
33+ const logEl = document . getElementById ( 'log' ) ;
34+ const httpPingBtn = document . getElementById ( 'httpPingBtn' ) ;
35+ const wsConnectBtn = document . getElementById ( 'wsConnectBtn' ) ;
36+ const wsSendBtn = document . getElementById ( 'wsSendBtn' ) ;
37+
38+ let ws = null ;
39+
40+ function log ( message ) {
41+ const time = new Date ( ) . toISOString ( ) ;
42+ logEl . textContent += `[${ time } ] ${ message } \n` ;
43+ logEl . scrollTop = logEl . scrollHeight ;
44+ }
45+
46+ httpPingBtn . addEventListener ( 'click' , async ( ) => {
47+ statusEl . textContent = 'HTTP: Pinging...' ;
48+ try {
49+ const res = await fetch ( '/api/ping' ) ;
50+ const json = await res . json ( ) ;
51+ statusEl . textContent = 'HTTP: OK' ;
52+ log ( `HTTP /api/ping -> ${ JSON . stringify ( json ) } ` ) ;
53+ } catch ( err ) {
54+ statusEl . textContent = 'HTTP: Error' ;
55+ log ( `HTTP error: ${ err } ` ) ;
56+ }
57+ } ) ;
58+
59+ document . getElementById ( 'testCookiesBtn' ) . addEventListener ( 'click' , async ( ) => {
60+ statusEl . textContent = 'Cookies: Testing...' ;
61+ try {
62+ const res = await fetch ( '/api/test-cookies' ) ;
63+ const json = await res . json ( ) ;
64+ statusEl . textContent = 'Cookies: OK' ;
65+ log ( `HTTP /api/test-cookies -> ${ JSON . stringify ( json ) } ` ) ;
66+
67+ // Log response headers
68+ log ( `Response headers:` ) ;
69+ for ( const [ key , value ] of res . headers . entries ( ) ) {
70+ log ( ` ${ key } : ${ value } ` ) ;
71+ }
72+
73+ // Log current cookies
74+ log ( `Current document.cookie: ${ document . cookie || '(empty)' } ` ) ;
75+ } catch ( err ) {
76+ statusEl . textContent = 'Cookies: Error' ;
77+ log ( `HTTP error: ${ err } ` ) ;
78+ }
79+ } ) ;
80+
81+ wsConnectBtn . addEventListener ( 'click' , ( ) => {
82+ if ( ws && ws . readyState === WebSocket . OPEN ) {
83+ ws . close ( ) ;
84+ return ;
85+ }
86+
87+ const protocol = window . location . protocol === 'https:' ? 'wss:' : 'ws:' ;
88+ const basePath = location . pathname . endsWith ( '/' ) ? location . pathname : ( location . pathname + '/' ) ;
89+ const url = protocol + '//' + window . location . host + basePath + 'ws' ;
90+
91+ statusEl . textContent = 'WS: Connecting...' ;
92+ log ( `WS connecting to ${ url } ` ) ;
93+
94+ ws = new WebSocket ( url ) ;
95+
96+ ws . onopen = ( ) => {
97+ statusEl . textContent = 'WS: Connected' ;
98+ log ( 'WS connected' ) ;
99+ wsSendBtn . disabled = false ;
100+ wsConnectBtn . textContent = 'WS Disconnect' ;
101+ } ;
102+
103+ ws . onclose = ( ) => {
104+ statusEl . textContent = 'WS: Disconnected' ;
105+ log ( 'WS disconnected' ) ;
106+ wsSendBtn . disabled = true ;
107+ wsConnectBtn . textContent = 'WS Connect' ;
108+ } ;
109+
110+ ws . onerror = ( err ) => {
111+ log ( `WS error: ${ err . message || err } ` ) ;
112+ } ;
113+
114+ ws . onmessage = ( event ) => {
115+ log ( `WS recv: ${ event . data } ` ) ;
116+ } ;
117+ } ) ;
118+
119+ wsSendBtn . addEventListener ( 'click' , ( ) => {
120+ if ( ! ws || ws . readyState !== WebSocket . OPEN ) {
121+ log ( 'WS send skipped: not connected' ) ;
122+ return ;
123+ }
124+ const msg = 'hello' ;
125+ ws . send ( msg ) ;
126+ log ( `WS send: ${ msg } ` ) ;
127+ } ) ;
128+ </ script >
56129</ body >
57- </ html >
130+
131+ </ html >
0 commit comments