1
- import { Page , Locator , expect } from '@playwright/test' ;
2
-
3
- export class SubgraphsPage {
4
- readonly page : Page ;
5
- readonly travelPlannerButton : Locator ;
6
- readonly chatInput : Locator ;
7
- readonly sendButton : Locator ;
8
- readonly agentGreeting : Locator ;
9
- readonly agentMessage : Locator ;
10
- readonly userMessage : Locator ;
11
-
12
- // Flight-related elements
13
- readonly flightOptions : Locator ;
14
- readonly klmFlightOption : Locator ;
15
- readonly unitedFlightOption : Locator ;
16
- readonly flightSelectionInterface : Locator ;
17
-
18
- // Hotel-related elements
19
- readonly hotelOptions : Locator ;
20
- readonly hotelZephyrOption : Locator ;
21
- readonly ritzCarltonOption : Locator ;
22
- readonly hotelZoeOption : Locator ;
23
- readonly hotelSelectionInterface : Locator ;
24
-
25
- // Itinerary and state elements
26
- readonly itineraryDisplay : Locator ;
27
- readonly selectedFlight : Locator ;
28
- readonly selectedHotel : Locator ;
29
- readonly experienceRecommendations : Locator ;
30
-
31
- // Subgraph activity indicators
32
- readonly activeAgent : Locator ;
33
- readonly supervisorIndicator : Locator ;
34
- readonly flightsAgentIndicator : Locator ;
35
- readonly hotelsAgentIndicator : Locator ;
36
- readonly experiencesAgentIndicator : Locator ;
37
-
38
- constructor ( page : Page ) {
39
- this . page = page ;
40
- this . travelPlannerButton = page . getByRole ( 'button' , { name : / t r a v e l .* p l a n n e r | s u b g r a p h s / i } ) ;
41
- this . agentGreeting = page . getByText ( / t r a v e l .* p l a n n i n g | s u p e r v i s o r .* c o o r d i n a t e / i) ;
42
- this . chatInput = page . getByRole ( 'textbox' , { name : 'Type a message...' } ) ;
43
- this . sendButton = page . locator ( '[data-test-id="copilot-chat-ready"]' ) ;
44
- this . agentMessage = page . locator ( '.copilotKitAssistantMessage' ) ;
45
- this . userMessage = page . locator ( '.copilotKitUserMessage' ) ;
46
-
47
- // Flight selection elements
48
- this . flightOptions = page . locator ( '[data-testid*="flight"], .flight-option' ) ;
49
- this . klmFlightOption = page . getByText ( / K L M .* \$ 6 5 0 .* 1 1 h 3 0 m / ) ;
50
- this . unitedFlightOption = page . getByText ( / U n i t e d .* \$ 7 2 0 .* 1 2 h 1 5 m / ) ;
51
- this . flightSelectionInterface = page . locator ( '[data-testid*="flight-select"], .flight-selection' ) ;
52
-
53
- // Hotel selection elements
54
- this . hotelOptions = page . locator ( '[data-testid*="hotel"], .hotel-option' ) ;
55
- this . hotelZephyrOption = page . getByText ( / H o t e l Z e p h y r .* F i s h e r m a n \' s W h a r f .* \$ 2 8 0 / ) ;
56
- this . ritzCarltonOption = page . getByText ( / R i t z - C a r l t o n .* N o b H i l l .* \$ 5 5 0 / ) ;
57
- this . hotelZoeOption = page . getByText ( / H o t e l Z o e .* U n i o n S q u a r e .* \$ 3 2 0 / ) ;
58
- this . hotelSelectionInterface = page . locator ( '[data-testid*="hotel-select"], .hotel-selection' ) ;
59
-
60
- // Itinerary elements
61
- this . itineraryDisplay = page . locator ( '[data-testid*="itinerary"], .itinerary' ) ;
62
- this . selectedFlight = page . locator ( '[data-testid*="selected-flight"], .selected-flight' ) ;
63
- this . selectedHotel = page . locator ( '[data-testid*="selected-hotel"], .selected-hotel' ) ;
64
- this . experienceRecommendations = page . locator ( '[data-testid*="experience"], .experience' ) ;
65
-
66
- // Agent activity indicators
67
- this . activeAgent = page . locator ( '[data-testid*="active-agent"], .active-agent' ) ;
68
- this . supervisorIndicator = page . locator ( '[data-testid*="supervisor"], .supervisor-active' ) ;
69
- this . flightsAgentIndicator = page . locator ( '[data-testid*="flights-agent"], .flights-agent-active' ) ;
70
- this . hotelsAgentIndicator = page . locator ( '[data-testid*="hotels-agent"], .hotels-agent-active' ) ;
71
- this . experiencesAgentIndicator = page . locator ( '[data-testid*="experiences-agent"], .experiences-agent-active' ) ;
72
- }
73
-
74
- async openChat ( ) {
75
- await this . travelPlannerButton . click ( ) ;
76
- }
77
-
78
- async sendMessage ( message : string ) {
79
- await this . chatInput . click ( ) ;
80
- await this . chatInput . fill ( message ) ;
81
- await this . sendButton . click ( ) ;
82
- }
83
-
84
- async selectFlight ( airline : 'KLM' | 'United' ) {
85
- const flightOption = airline === 'KLM' ? this . klmFlightOption : this . unitedFlightOption ;
86
-
87
- // Wait for flight options to be presented
88
- await expect ( this . flightOptions . first ( ) ) . toBeVisible ( { timeout : 15000 } ) ;
89
-
90
- // Click on the desired flight option
91
- await flightOption . click ( ) ;
92
- }
93
-
94
- async selectHotel ( hotel : 'Zephyr' | 'Ritz-Carlton' | 'Zoe' ) {
95
- let hotelOption : Locator ;
96
-
97
- switch ( hotel ) {
98
- case 'Zephyr' :
99
- hotelOption = this . hotelZephyrOption ;
100
- break ;
101
- case 'Ritz-Carlton' :
102
- hotelOption = this . ritzCarltonOption ;
103
- break ;
104
- case 'Zoe' :
105
- hotelOption = this . hotelZoeOption ;
106
- break ;
107
- }
108
-
109
- // Wait for hotel options to be presented
110
- await expect ( this . hotelOptions . first ( ) ) . toBeVisible ( { timeout : 15000 } ) ;
111
-
112
- // Click on the desired hotel option
113
- await hotelOption . click ( ) ;
114
- }
115
-
116
- async waitForFlightsAgent ( ) {
117
- // Wait for flights agent to become active (or look for flight-related content)
118
- // Use .first() to handle multiple matches in strict mode
119
- await expect (
120
- this . page . getByText ( / f l i g h t .* o p t i o n s | A m s t e r d a m .* S a n F r a n c i s c o | K L M | U n i t e d / i) . first ( )
121
- ) . toBeVisible ( { timeout : 20000 } ) ;
122
- }
123
-
124
- async waitForHotelsAgent ( ) {
125
- // Wait for hotels agent to become active (or look for hotel-related content)
126
- // Use .first() to handle multiple matches in strict mode
127
- await expect (
128
- this . page . getByText ( / h o t e l .* o p t i o n s | a c c o m m o d a t i o n | Z e p h y r | R i t z - C a r l t o n | H o t e l Z o e / i) . first ( )
129
- ) . toBeVisible ( { timeout : 20000 } ) ;
130
- }
131
-
132
- async waitForExperiencesAgent ( ) {
133
- // Wait for experiences agent to become active (or look for experience-related content)
134
- // Use .first() to handle multiple matches in strict mode
135
- await expect (
136
- this . page . getByText ( / e x p e r i e n c e | a c t i v i t i e s | r e s t a u r a n t | P i e r 3 9 | G o l d e n G a t e | S w a n O y s t e r | T a r t i n e / i) . first ( )
137
- ) . toBeVisible ( { timeout : 20000 } ) ;
138
- }
139
-
140
- async verifyStaticFlightData ( ) {
141
- // Verify the hardcoded flight options are present
142
- await expect ( this . page . getByText ( / K L M .* \$ 6 5 0 .* 1 1 h 3 0 m / ) . first ( ) ) . toBeVisible ( ) ;
143
- await expect ( this . page . getByText ( / U n i t e d .* \$ 7 2 0 .* 1 2 h 1 5 m / ) . first ( ) ) . toBeVisible ( ) ;
144
- }
145
-
146
- async verifyStaticHotelData ( ) {
147
- // Verify the hardcoded hotel options are present
148
- await expect ( this . page . getByText ( / H o t e l Z e p h y r .* \$ 2 8 0 / ) . first ( ) ) . toBeVisible ( ) ;
149
- await expect ( this . page . getByText ( / R i t z - C a r l t o n .* \$ 5 5 0 / ) . first ( ) ) . toBeVisible ( ) ;
150
- await expect ( this . page . getByText ( / H o t e l Z o e .* \$ 3 2 0 / ) . first ( ) ) . toBeVisible ( ) ;
151
- }
152
-
153
- async verifyStaticExperienceData ( ) {
154
- // Verify the hardcoded experience options are mentioned
155
- const experienceText = this . page . getByText ( / P i e r 3 9 | G o l d e n G a t e B r i d g e | S w a n O y s t e r D e p o t | T a r t i n e B a k e r y / i) ;
156
- await expect ( experienceText . first ( ) ) . toBeVisible ( ) ;
157
- }
158
-
159
- async verifyItineraryContainsFlight ( airline : 'KLM' | 'United' ) {
160
- // Check that the selected flight appears in the itinerary or conversation
161
- await expect ( this . page . getByText ( new RegExp ( airline , 'i' ) ) ) . toBeVisible ( ) ;
162
- }
163
-
164
- async verifyItineraryContainsHotel ( hotel : 'Zephyr' | 'Ritz-Carlton' | 'Zoe' ) {
165
- // Check that the selected hotel appears in the itinerary or conversation
166
- const hotelName = hotel === 'Ritz-Carlton' ? 'Ritz-Carlton' : `Hotel ${ hotel } ` ;
167
- await expect ( this . page . getByText ( new RegExp ( hotelName , 'i' ) ) ) . toBeVisible ( ) ;
168
- }
169
-
170
- async assertAgentReplyVisible ( expectedText : RegExp ) {
171
- await expect ( this . agentMessage . last ( ) . getByText ( expectedText ) ) . toBeVisible ( ) ;
172
- }
173
-
174
- async assertUserMessageVisible ( message : string ) {
175
- await expect ( this . page . getByText ( message ) ) . toBeVisible ( ) ;
176
- }
177
-
178
- async waitForSupervisorCoordination ( ) {
179
- // Wait for supervisor to appear in the conversation
180
- await expect (
181
- this . page . getByText ( / s u p e r v i s o r | c o o r d i n a t e | s p e c i a l i s t | r o u t i n g / i) . first ( )
182
- ) . toBeVisible ( { timeout : 15000 } ) ;
183
- }
184
-
185
- async waitForAgentCompletion ( ) {
186
- // Wait for the travel planning process to complete
187
- await expect (
188
- this . page . getByText ( / c o m p l e t e | f i n i s h e d | p l a n n i n g .* d o n e | i t i n e r a r y .* r e a d y / i) . first ( )
189
- ) . toBeVisible ( { timeout : 30000 } ) ;
190
- }
191
- }
1
+ export { SubgraphsPage } from '../langGraphPages/SubgraphsPage'
0 commit comments