
    V5i)                         d Z ddlZddlmc mZ ddlZddlZddl	m
Z
  G d d      Z G d d      Z G d d	      Z G d
 d      Z G d d      Zej                   j#                  d       G d d             Zy)z
E2E Tests for ReceptionistAI Voice Widget.

Tests the widget UI, interactions, and voice connectivity based on:
- /mnt/e/genesis-system/RECEPTIONISTAI/QUICK_START.md
- /mnt/e/genesis-system/RECEPTIONISTAI/widget/demo.html
    N)expectc                   .    e Zd ZdZd Zd Zd Zd Zd Zy)TestWidgetBasicsz$Basic widget rendering and UI tests.c                    |j                  | d      }|j                  }d}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                  d      dz   d	|iz  }t        t        j                  |            d
x}x}}t        |      j                  d       y
)z$Verify demo page loads successfully.
/demo.html   ==)z.%(py2)s
{%(py2)s = %(py0)s.status
} == %(py5)sresponse)py0py2py5zDemo page failed to loadz
>assert %(py7)spy7NzReceptionistAI Widget Demo)gotostatus
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_saferepr_format_assertmsgAssertionError_format_explanationr   to_have_title)	selfpage
widget_urlr   @py_assert1@py_assert4@py_assert3@py_format6@py_format8s	            ./mnt/e/genesis-system/tests/e2e/test_widget.pytest_widget_page_loadsz'TestWidgetBasics.test_widget_page_loads   s    99
|:67A#A#%AAA#AAAAAAxAAAxAAAAAA#AAA'AAAAAAAA 	t""#?@    c                     |j                  | d       |j                  d      }t        |      j                          |j                  d      }t        |      j                          y)z&Verify widget UI elements are present.r   z#receptionist-widgetzMbutton[aria-label*="microphone"], button[aria-label*="call"], .widget-triggerN)r   locatorr   to_be_visible)r   r   r   widget
mic_buttons        r$   test_widget_ui_rendersz'TestWidgetBasics.test_widget_ui_renders   sX    		ZL
+, 45v$$& \\"qr
z((*r&   c                    |j                  | d       |j                  d      j                  }t        |      j	                          |j                          |j                  d      }t        |      j                  d       y)z*Verify widget trigger button is clickable.r   1button.widget-trigger, button[aria-label*="call"]1.chat-interface, .chat-window, .message-container  timeoutN)r   r(   firstr   to_be_enabledclickr)   )r   r   r   triggerchat_interfaces        r$   test_widget_button_clickablez-TestWidgetBasics.test_widget_button_clickable$   sl    		ZL
+, ,,RSYYw%%' &YZ~,,T,:r&   c                     |j                  | d       |j                  d      j                  j                          |j                  d      }t	        |      j                  d       y)z#Verify text input field is present.r   r.   ;input[type="text"], textarea, input[placeholder*="message"]r0   r1   Nr   r(   r3   r5   r   r)   )r   r   r   
text_inputs       r$   test_text_input_visiblez(TestWidgetBasics.test_text_input_visible2   sZ    		ZL
+, 	HIOOUUW \\"_`
z(((6r&   c                     |j                  | d       |j                  d      j                  j                          |j                  d      }t	        |      j                  d       y)zVerify send button exists.r   r.   Jbutton[aria-label*="send"], button:has-text("Send"), button[type="submit"]r0   r1   Nr;   )r   r   r   send_buttons       r$   test_send_button_presentz)TestWidgetBasics.test_send_button_present=   sZ    		ZL
+, 	HIOOUUW ll#op{))$)7r&   N)	__name__
__module____qualname____doc__r%   r,   r8   r=   rA    r&   r$   r   r      s    .A
+;	7	8r&   r   c                   "    e Zd ZdZd Zd Zd Zy)TestWidgetInteractionz'Test user interactions with the widget.c                    |j                  | d       |j                  d      j                  j                          |j	                  d       |j                  d      j                  }|j                  d       |j                  d      j                  }|j                          |j	                  d       |j                  d      }|j                  } |       }d	}||kD  }	|	st        j                  d
|	fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }
t        j                  d      dz   d|
iz  }t        t        j                  |            dx}x}x}	}y)z/Test sending a text message through the widget.r   r.     r:   What are your hours?r?     +.message, .chat-message, [class*="message"]r   >zC%(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.count
}()
} > %(py7)smessagesr   r   py4r   zNo messages found after sendingz
>assert %(py9)spy9N)r   r(   r3   r5   wait_for_timeoutfillcountr   r   r   r   r   r   r   r   r   r   r   r   r<   r@   rQ   r   r!   @py_assert6@py_assert5r#   @py_format10s               r$   test_text_message_flowz,TestWidgetInteraction.test_text_message_flowL   s8   		ZL
+, 	HIOOUUWd# \\"_`ff
./ ll#opvv 	d# << MN~~F~F!F!#FFF!FFFFFFxFFFxFFF~FFFFFF!FFF%FFFFFFFFr&   c           	         |j                  | d       |j                  d      j                  j                          |j	                  d       g d}|D ]j  }|j                  d      j                  }|j                  |       |j                  d      j                  }|j                          |j	                  d       l |j                  d      }|j                  } |       }	t        |      }
|	|
k\  }|sat        j                  d	|fd
|	|
f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |	      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |
      dz  }t        j                  d      dz   d|iz  }t        t        j                   |            dx}x}	x}}
y)z+Test sending multiple messages in sequence.r   r.   rJ   )rK   z!How much does a leak repair cost?zDo you service Bondi?r:   r?   i  rM   )>=)zb%(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.count
}()
} >= %(py9)s
{%(py9)s = %(py6)s(%(py7)s)
}rQ   lentest_messages)r   r   rS   py6r   rT   zNot all messages appearedz
>assert %(py11)spy11N)r   r(   r3   r5   rU   rV   rW   r_   r   r   r   r   r   r   r   r   r   )r   r   r   r`   msgr<   r@   rQ   r   r!   @py_assert8rZ   r[   @py_format12s                 r$   test_multiple_messagesz,TestWidgetInteraction.test_multiple_messagesc   s   		ZL
+, 	HIOOUUWd#
 ! 	(C&cdjjJOOC ,,'stzzK!!$'	( << MN~~R~R3}#5R#55RRR#5RRRRRRxRRRxRRR~RRRRRRRRR3RRR3RRRRRR}RRR}RRR#5RRR7RRRRRRRRr&   c                 \   |j                  | d       |j                  d      j                  j                          |j	                  d       |j                  d      j                  }|j                  d       |j                  d      j                  }|j                          |j	                  d       |j                  d      }|j                  } |       }d	}||kD  }	|	st        j                  d
|	fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }
dd|
iz  }t        t        j                  |            dx}x}x}	}y)z7Test message with phone number (lead capture scenario).r   r.   rJ   r:   z'My name is Sarah, call me on 0412345678r?   rL   rM   r   rN   rP   rQ   rR   assert %(py9)srT   Nr   r(   r3   r5   rU   rV   rW   r   r   r   r   r   r   r   r   rX   s               r$   test_lead_capture_messagez/TestWidgetInteraction.test_lead_capture_message~   s(   		ZL
+, 	HIOOUUWd# \\"_`ff
ABll#opvvd# << MN~~#~#!#!####!######x###x###~######!#######r&   N)rB   rC   rD   rE   r\   rf   rj   rF   r&   r$   rH   rH   I   s    1G.S6$r&   rH   c                   "    e Zd ZdZd Zd Zd Zy)TestWidgetResponsivez&Test widget on different screen sizes.c                     |j                  | d       |j                  d      }t        |      j                          |j                  d      j                  }t        |      j                          y)zTest widget on mobile viewport.r   '#receptionist-widget, .widget-containerr.   Nr   r(   r   r)   r3   )r   mobile_pager   r*   r6   s        r$   test_mobile_renderingz*TestWidgetResponsive.test_mobile_rendering   c    J<z23 $$%NOv$$& %%&YZ``w%%'r&   c                     |j                  | d       |j                  d      }t        |      j                          |j                  d      j                  }t        |      j                          y)zTest widget on tablet viewport.r   rn   r.   Nro   )r   tablet_pager   r*   r6   s        r$   test_tablet_renderingz*TestWidgetResponsive.test_tablet_rendering   rr   r&   c                 \   |j                  | d       |j                  d      j                  j                          |j	                  d       |j                  d      j                  }|j                  d       |j                  d      j                  }|j                          |j	                  d       |j                  d      }|j                  } |       }d	}||kD  }	|	st        j                  d
|	fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }
dd|
iz  }t        t        j                  |            dx}x}x}	}y)z%Test full interaction flow on mobile.r   r.   rJ   r:   zTest mobile messagez3button[aria-label*="send"], button:has-text("Send")rL   rM   r   rN   rP   rQ   rR   rh   rT   Nri   )r   rp   r   r<   r@   rQ   r   r!   rY   rZ   r#   r[   s               r$   test_mobile_interactionz,TestWidgetResponsive.test_mobile_interaction   s2   J<z23 	OPVV\\^$$T* !(()fgmm
-.!))*_`ff$$T* &&'TU~~#~#!#!####!######x###x###~######!#######r&   N)rB   rC   rD   rE   rq   ru   rw   rF   r&   r$   rl   rl      s    0
(
($r&   rl   c                   "    e Zd ZdZd Zd Zd Zy)TestWidgetPerformancezPerformance and loading tests.c                    t        j                          }|j                  | d       t        j                          |z
  }d}||k  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d|dd	      d
z   d|iz  }t        t        j                  |            dx}}y)z%Verify page loads in under 3 seconds.r   g      @<z%(py0)s < %(py3)s	load_timer   py3zPage load took .2fzs (target: <3s)
>assert %(py5)sr   N)timer   r   r   r   r   r   r   r   r   r   )	r   r   r   
start_timer~   @py_assert2r   @py_format4r"   s	            r$   test_page_load_timez)TestWidgetPerformance.test_page_load_time   s    YY[
		ZL
+,IIK*,	Py3PPPy3PPPPPPyPPPyPPP3PPP/)C PPPPPPPr&   c                 n  
 g 
|j                  d
fd       |j                  | d       |j                  d       
D cg c]!  }d|j                  j	                         vs |# }}t        |      }d}||k(  }|s't        j                  d|fd||f      d	t        j                         v st        j                  t
              rt        j                  t
              nd	d
t        j                         v st        j                  |      rt        j                  |      nd
t        j                  |      t        j                  |      dz  }t        j                  d|D cg c]  }|j                   c}       dz   d|iz  }	t        t        j                  |	            dx}x}}yc c}w c c}w )z,Verify no JavaScript console errors on load.consolec                 H    | j                   dk(  rj                  |       S d S )Nerror)typeappend)rc   errorss    r$   <lambda>z>TestWidgetPerformance.test_no_console_errors.<locals>.<lambda>   s     SXX=Pv}}S'9 VZ r&   r   rL   faviconr   r	   )z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)sr_   critical_errorsr   py1r   ra   zConsole errors found: 
>assert %(py8)spy8N)onr   rU   textlowerr_   r   r   r   r   r   r   r   r   r   )r   r   r   er   r   rZ   r    @py_format7@py_format9r   s             @r$   test_no_console_errorsz,TestWidgetPerformance.test_no_console_errors   s   	Z[		ZL
+,d# '-P	0O1PP?#fqf#q(fff#qffffffsfffsffffff?fff?fff#fffqfff,BTcCdqAFFCdBe*ffffffff QCds   !F-$F-$F2
c                 `   t        j                          }|j                  | d       |j                  d      j                  }|j	                  dd       t        j                          |z
  }d}||k  }|st        j                  d|fd||f      d	t        j                         v st        j                  |      rt        j                  |      nd	t        j                  |      d
z  }t        j                  d|dd      dz   d|iz  }	t        t        j                  |	            dx}}y)z,Test how quickly widget becomes interactive.r   r.   visiblei  )stater2   g       @r{   r}   	init_timer   zWidget initialization took r   zs (target: <2s)r   r   N)r   r   r(   r3   wait_forr   r   r   r   r   r   r   r   r   )
r   r   r   r   r6   r   r   r   r   r"   s
             r$    test_widget_initialization_speedz6TestWidgetPerformance.test_widget_initialization_speed   s    YY[
		ZL
+, ,,RSYYy$7IIK*,	\y3\\\y3\\\\\\y\\\y\\\3\\\"=i_O \\\\\\\r&   N)rB   rC   rD   rE   r   r   r   rF   r&   r$   ry   ry      s    (Qg
]r&   ry   c                       e Zd ZdZd Zd Zy)TestWidgetAccessibilityz(Accessibility and ARIA compliance tests.c                     |j                  | d       |j                  j                  d       |j                  j                  d       |j                  d      }t	        |      j                  d       y)z(Test widget can be opened with keyboard.r   TabEnterr/   r0   r1   N)r   keyboardpressr(   r   r)   )r   r   r   r7   s       r$   test_keyboard_navigationz0TestWidgetAccessibility.test_keyboard_navigation   sd    		ZL
+, 	E" 	G$ &YZ~,,T,:r&   c                 H   |j                  | d       |j                  d      j                  }|j                  d      }d}||u}|st	        j
                  d|fd||f      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      dz  }t	        j                  d	      d
z   d|iz  }t        t	        j                  |            dx}}t        |      }d}	||	kD  }
|
st	        j
                  d|
fd||	f      dt        j                         v st	        j                  t              rt	        j                  t              nddt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      t	        j                  |	      dz  }t	        j                  d      dz   d|iz  }t        t	        j                  |            dx}x}
}	y)z&Verify ARIA labels for screen readers.r   z)button.widget-trigger, button[aria-label]z
aria-labelN)is not)z%(py0)s is not %(py3)s
aria_labelr   z!Widget trigger missing aria-labelr   r   r   rN   )z/%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} > %(py6)sr_   r   zaria-label is emptyr   r   )r   r(   r3   get_attributer   r   r   r   r   r   r   r   r   r_   )r   r   r   r6   r   r   r   r   r"   rZ   r    r   r   s                r$   test_aria_labels_presentz0TestWidgetAccessibility.test_aria_labels_present   s6   		ZL
+, ,,JKQQ**<8
!%Jz%JJJzJJJJJJzJJJzJJJJJJ'JJJJJJJ:99"999999999s999s999999:999:999999999$99999999r&   N)rB   rC   rD   rE   r   r   rF   r&   r$   r   r      s    2;	:r&   r   z7Requires microphone permissions and Telnyx WebRTC setup)reasonc                       e Zd ZdZd Zd Zy)TestVoiceIntegrationz3Voice call integration tests (requires microphone).c                 ,    |j                  | d       y)z'Verify audio permissions are requested.r   N)r   r   r   r   s      r$   test_audio_permissions_promptz2TestVoiceIntegration.test_audio_permissions_prompt  s    		ZL
+, 	r&   c                      y)z*Test connection to Telnyx WebRTC endpoint.NrF   r   s      r$   test_telnyx_webrtc_connectionz2TestVoiceIntegration.test_telnyx_webrtc_connection  s     	r&   N)rB   rC   rD   rE   r   r   rF   r&   r$   r   r     s    =r&   r   )rE   builtinsr   _pytest.assertion.rewrite	assertionrewriter   pytestr   playwright.sync_apir   r   rH   rl   ry   r   markskipr   rF   r&   r$   <module>r      s       &98 98xH$ H$V.$ .$b"] "]J: :: RS  Tr&   