1
- import { Page , Locator , expect } from ' @playwright/test' ;
1
+ import { Page , Locator , expect } from " @playwright/test" ;
2
2
3
3
export class ToolBaseGenUIPage {
4
4
readonly page : Page ;
5
5
readonly haikuAgentIntro : Locator ;
6
6
readonly messageBox : Locator ;
7
7
readonly sendButton : Locator ;
8
8
readonly applyButton : Locator ;
9
- readonly appliedButton : Locator ;
10
9
readonly haikuBlock : Locator ;
11
10
readonly japaneseLines : Locator ;
11
+ readonly mainHaikuDisplay : Locator ;
12
12
13
13
constructor ( page : Page ) {
14
14
this . page = page ;
15
- this . haikuAgentIntro = page . getByText ( "I'm a haiku generator 👋. How can I help you?" ) ;
16
- this . messageBox = page . getByRole ( 'textbox' , { name : ' Type a message...' } ) ;
17
- this . sendButton = page . locator ( '[data-test-id="copilot-chat-ready"]' ) ;
15
+ this . haikuAgentIntro = page . getByText ( "I'm a haiku generator 👋. How can I help you?" ) . first ( ) ;
16
+ this . messageBox = page . getByPlaceholder ( " Type a message..." ) . first ( ) ;
17
+ this . sendButton = page . locator ( '[data-test-id="copilot-chat-ready"]' ) . first ( ) ;
18
18
this . haikuBlock = page . locator ( '[data-testid="haiku-card"]' ) ;
19
- this . applyButton = page . getByRole ( 'button' , { name : 'Apply' } ) ;
20
- this . japaneseLines = page . locator ( '[data-testid="haiku-line"]' ) ;
19
+ this . applyButton = page . getByRole ( "button" , { name : "Apply" } ) ;
20
+ this . japaneseLines = page . locator ( '[data-testid="haiku-japanese-line"]' ) ;
21
+ this . mainHaikuDisplay = page . locator ( '[data-testid="haiku-carousel"]' ) ;
21
22
}
22
23
23
24
async generateHaiku ( message : string ) {
25
+ // Wait for either sidebar or popup to be ready
26
+ await this . page . waitForTimeout ( 2000 ) ;
27
+ await this . messageBox . waitFor ( { state : "visible" , timeout : 15000 } ) ;
24
28
await this . messageBox . click ( ) ;
25
29
await this . messageBox . fill ( message ) ;
30
+ await this . page . waitForTimeout ( 1000 ) ;
31
+ await this . sendButton . waitFor ( { state : "visible" , timeout : 15000 } ) ;
26
32
await this . sendButton . click ( ) ;
33
+ await this . page . waitForTimeout ( 2000 ) ;
27
34
}
28
35
29
36
async checkGeneratedHaiku ( ) {
30
- await this . page . locator ( '[data-testid="haiku-card"]' ) . last ( ) . isVisible ( ) ;
31
- const mostRecentCard = this . page . locator ( '[data-testid="haiku-card"]' ) . last ( ) ;
32
- await mostRecentCard . locator ( '[data-testid="haiku-line"]' ) . first ( ) . waitFor ( { state : 'visible' , timeout : 10000 } ) ;
37
+ await this . page . waitForTimeout ( 3000 ) ;
38
+ const cards = this . page . locator ( '[data-testid="haiku-card"]' ) ;
39
+ await cards . last ( ) . waitFor ( { state : "visible" , timeout : 20000 } ) ;
40
+ const mostRecentCard = cards . last ( ) ;
41
+ await mostRecentCard
42
+ . locator ( '[data-testid="haiku-japanese-line"]' )
43
+ . first ( )
44
+ . waitFor ( { state : "visible" , timeout : 20000 } ) ;
33
45
}
34
46
35
47
async extractChatHaikuContent ( page : Page ) : Promise < string > {
36
- await page . waitForTimeout ( 3000 ) ;
37
- await page . locator ( '[data-testid="haiku-card"]' ) . first ( ) . waitFor ( { state : 'visible' } ) ;
48
+ await page . waitForTimeout ( 4000 ) ;
38
49
const allHaikuCards = page . locator ( '[data-testid="haiku-card"]' ) ;
50
+ await allHaikuCards . first ( ) . waitFor ( { state : "visible" , timeout : 15000 } ) ;
39
51
const cardCount = await allHaikuCards . count ( ) ;
40
52
let chatHaikuContainer ;
41
53
let chatHaikuLines ;
42
54
43
55
for ( let cardIndex = cardCount - 1 ; cardIndex >= 0 ; cardIndex -- ) {
44
56
chatHaikuContainer = allHaikuCards . nth ( cardIndex ) ;
45
- chatHaikuLines = chatHaikuContainer . locator ( '[data-testid="haiku-line"]' ) ;
57
+ chatHaikuLines = chatHaikuContainer . locator ( '[data-testid="haiku-japanese- line"]' ) ;
46
58
const linesCount = await chatHaikuLines . count ( ) ;
47
59
48
60
if ( linesCount > 0 ) {
49
61
try {
50
- await chatHaikuLines . first ( ) . waitFor ( { state : ' visible' , timeout : 5000 } ) ;
62
+ await chatHaikuLines . first ( ) . waitFor ( { state : " visible" , timeout : 8000 } ) ;
51
63
break ;
52
64
} catch ( error ) {
53
65
continue ;
@@ -56,59 +68,94 @@ export class ToolBaseGenUIPage {
56
68
}
57
69
58
70
if ( ! chatHaikuLines ) {
59
- throw new Error ( ' No haiku cards with visible lines found' ) ;
71
+ throw new Error ( " No haiku cards with visible lines found" ) ;
60
72
}
61
73
62
74
const count = await chatHaikuLines . count ( ) ;
63
75
const lines : string [ ] = [ ] ;
64
76
65
77
for ( let i = 0 ; i < count ; i ++ ) {
66
78
const haikuLine = chatHaikuLines . nth ( i ) ;
67
- const japaneseText = await haikuLine . locator ( 'p' ) . first ( ) . innerText ( ) ;
79
+ const japaneseText = await haikuLine . innerText ( ) ;
68
80
lines . push ( japaneseText ) ;
69
81
}
70
82
71
- const chatHaikuContent = lines . join ( '' ) . replace ( / \s / g, '' ) ;
83
+ const chatHaikuContent = lines . join ( "" ) . replace ( / \s / g, "" ) ;
72
84
return chatHaikuContent ;
73
85
}
74
86
75
87
async extractMainDisplayHaikuContent ( page : Page ) : Promise < string > {
76
- const mainDisplayLines = page . locator ( '[data-testid="main-haiku-line"]' ) ;
88
+ await page . waitForTimeout ( 2000 ) ;
89
+ const carousel = page . locator ( '[data-testid="haiku-carousel"]' ) ;
90
+ await carousel . waitFor ( { state : "visible" , timeout : 10000 } ) ;
91
+
92
+ // Find the visible carousel item (the active slide)
93
+ const carouselItems = carousel . locator ( '[data-testid^="carousel-item-"]' ) ;
94
+ const itemCount = await carouselItems . count ( ) ;
95
+ let activeCard = null ;
96
+
97
+ // Find the visible/active carousel item
98
+ for ( let i = 0 ; i < itemCount ; i ++ ) {
99
+ const item = carouselItems . nth ( i ) ;
100
+ const isVisible = await item . isVisible ( ) ;
101
+ if ( isVisible ) {
102
+ activeCard = item . locator ( '[data-testid="haiku-card"]' ) ;
103
+ break ;
104
+ }
105
+ }
106
+
107
+ if ( ! activeCard ) {
108
+ // Fallback to first card if none found visible
109
+ activeCard = carousel . locator ( '[data-testid="haiku-card"]' ) . first ( ) ;
110
+ }
111
+
112
+ const mainDisplayLines = activeCard . locator ( '[data-testid="haiku-japanese-line"]' ) ;
77
113
const mainCount = await mainDisplayLines . count ( ) ;
78
114
const lines : string [ ] = [ ] ;
79
115
80
116
if ( mainCount > 0 ) {
81
117
for ( let i = 0 ; i < mainCount ; i ++ ) {
82
118
const haikuLine = mainDisplayLines . nth ( i ) ;
83
- const japaneseText = await haikuLine . locator ( 'p' ) . first ( ) . innerText ( ) ;
119
+ const japaneseText = await haikuLine . innerText ( ) ;
84
120
lines . push ( japaneseText ) ;
85
121
}
86
122
}
87
123
88
- const mainHaikuContent = lines . join ( '' ) . replace ( / \s / g, '' ) ;
124
+ const mainHaikuContent = lines . join ( "" ) . replace ( / \s / g, "" ) ;
89
125
return mainHaikuContent ;
90
126
}
91
127
92
128
async checkHaikuDisplay ( page : Page ) : Promise < void > {
93
129
const chatHaikuContent = await this . extractChatHaikuContent ( page ) ;
94
130
95
- await page . waitForTimeout ( 5000 ) ;
131
+ await page . waitForTimeout ( 3000 ) ;
96
132
97
- const mainHaikuContent = await this . extractMainDisplayHaikuContent ( page ) ;
133
+ // Check that the haiku exists somewhere in the carousel
134
+ const carousel = page . locator ( '[data-testid="haiku-carousel"]' ) ;
135
+ await carousel . waitFor ( { state : "visible" , timeout : 10000 } ) ;
98
136
99
- if ( mainHaikuContent === '' ) {
100
- expect ( chatHaikuContent . length ) . toBeGreaterThan ( 0 ) ;
101
- return ;
102
- }
137
+ const allCarouselCards = carousel . locator ( '[data-testid="haiku-card"]' ) ;
138
+ const cardCount = await allCarouselCards . count ( ) ;
103
139
104
- if ( chatHaikuContent === mainHaikuContent ) {
105
- expect ( mainHaikuContent ) . toBe ( chatHaikuContent ) ;
106
- } else {
107
- await page . waitForTimeout ( 3000 ) ;
140
+ let foundMatch = false ;
141
+ for ( let i = 0 ; i < cardCount ; i ++ ) {
142
+ const card = allCarouselCards . nth ( i ) ;
143
+ const lines = card . locator ( '[data-testid="haiku-japanese-line"]' ) ;
144
+ const lineCount = await lines . count ( ) ;
145
+ const cardLines : string [ ] = [ ] ;
108
146
109
- const updatedMainContent = await this . extractMainDisplayHaikuContent ( page ) ;
147
+ for ( let j = 0 ; j < lineCount ; j ++ ) {
148
+ const text = await lines . nth ( j ) . innerText ( ) ;
149
+ cardLines . push ( text ) ;
150
+ }
110
151
111
- expect ( updatedMainContent ) . toBe ( chatHaikuContent ) ;
152
+ const cardContent = cardLines . join ( "" ) . replace ( / \s / g, "" ) ;
153
+ if ( cardContent === chatHaikuContent ) {
154
+ foundMatch = true ;
155
+ break ;
156
+ }
112
157
}
158
+
159
+ expect ( foundMatch ) . toBe ( true ) ;
113
160
}
114
- }
161
+ }
0 commit comments