1111 */
1212
1313import { expect , Locator , Page } from '@playwright/test' ;
14- import { getCurrentPath , waitForUrlNotContaining } from '../utils' ;
1514import { BasePage } from './base-page' ;
1615
1716export class HomePage extends BasePage {
@@ -20,7 +19,6 @@ export class HomePage extends BasePage {
2019 readonly helpSection : Locator ;
2120 readonly communitySection : Locator ;
2221 readonly createNewNoteButton : Locator ;
23- readonly filterInput : Locator ;
2422 readonly zeppelinLogo : Locator ;
2523 readonly anonymousUserIndicator : Locator ;
2624 readonly welcomeSection : Locator ;
@@ -29,10 +27,12 @@ export class HomePage extends BasePage {
2927 readonly helpCommunityColumn : Locator ;
3028 readonly welcomeDescription : Locator ;
3129 readonly refreshNoteButton : Locator ;
32- readonly notebookList : Locator ;
3330 readonly notebookHeading : Locator ;
3431 readonly helpHeading : Locator ;
3532 readonly communityHeading : Locator ;
33+ readonly createNoteModal : Locator ;
34+ readonly createNoteButton : Locator ;
35+ readonly notebookNameInput : Locator ;
3636 readonly externalLinks : {
3737 documentation : Locator ;
3838 mailingList : Locator ;
@@ -67,7 +67,6 @@ export class HomePage extends BasePage {
6767 this . helpSection = page . locator ( 'text=Help' ) . first ( ) ;
6868 this . communitySection = page . locator ( 'text=Community' ) . first ( ) ;
6969 this . createNewNoteButton = page . getByText ( 'Create new Note' , { exact : true } ) . first ( ) ;
70- this . filterInput = page . locator ( 'input[placeholder*="Filter"]' ) ;
7170 this . zeppelinLogo = page . locator ( 'text=Zeppelin' ) . first ( ) ;
7271 this . anonymousUserIndicator = page . locator ( 'text=anonymous' ) ;
7372 this . welcomeSection = page . locator ( '.welcome' ) ;
@@ -76,10 +75,12 @@ export class HomePage extends BasePage {
7675 this . helpCommunityColumn = page . locator ( '[nz-col]' ) . last ( ) ;
7776 this . welcomeDescription = page . locator ( '.welcome' ) . getByText ( 'Zeppelin is web-based notebook' ) ;
7877 this . refreshNoteButton = page . locator ( 'a.refresh-note' ) ;
79- this . notebookList = page . locator ( 'zeppelin-node-list' ) ;
8078 this . notebookHeading = this . notebookColumn . locator ( 'h3' ) ;
8179 this . helpHeading = page . locator ( 'h3' ) . filter ( { hasText : 'Help' } ) ;
8280 this . communityHeading = page . locator ( 'h3' ) . filter ( { hasText : 'Community' } ) ;
81+ this . createNoteModal = page . locator ( 'div.ant-modal-content' ) ;
82+ this . createNoteButton = this . createNoteModal . locator ( 'button' , { hasText : 'Create' } ) ;
83+ this . notebookNameInput = this . createNoteModal . locator ( 'input[name="noteName"]' ) ;
8384
8485 this . externalLinks = {
8586 documentation : page . locator ( 'a[href*="zeppelin.apache.org/docs"]' ) ,
@@ -110,45 +111,22 @@ export class HomePage extends BasePage {
110111 } ;
111112 }
112113
113- async navigateToHome ( ) : Promise < void > {
114- await this . page . goto ( '/#/' , {
115- waitUntil : 'load' ,
116- timeout : 60000
117- } ) ;
118- await this . waitForPageLoad ( ) ;
119- }
120-
121114 async navigateToLogin ( ) : Promise < void > {
122- await this . page . goto ( '/#/login' ) ;
123- await this . waitForPageLoad ( ) ;
115+ await this . navigateToRoute ( '/login' ) ;
124116 // Wait for potential redirect to complete by checking URL change
125- await waitForUrlNotContaining ( this . page , '#/login' ) ;
117+ await this . waitForUrlNotContaining ( '#/login' ) ;
126118 }
127119
128120 async isHomeContentDisplayed ( ) : Promise < boolean > {
129- try {
130- await expect ( this . welcomeHeading ) . toBeVisible ( ) ;
131- return true ;
132- } catch {
133- return false ;
134- }
121+ return this . welcomeHeading . isVisible ( ) ;
135122 }
136123
137124 async isAnonymousUser ( ) : Promise < boolean > {
138- try {
139- await expect ( this . anonymousUserIndicator ) . toBeVisible ( ) ;
140- return true ;
141- } catch {
142- return false ;
143- }
125+ return this . anonymousUserIndicator . isVisible ( ) ;
144126 }
145127
146128 async clickZeppelinLogo ( ) : Promise < void > {
147- await this . zeppelinLogo . click ( ) ;
148- }
149-
150- getCurrentPath ( ) : string {
151- return getCurrentPath ( this . page ) ;
129+ await this . zeppelinLogo . click ( { timeout : 15000 } ) ;
152130 }
153131
154132 async getWelcomeHeadingText ( ) : Promise < string > {
@@ -162,23 +140,57 @@ export class HomePage extends BasePage {
162140 }
163141
164142 async clickRefreshNotes ( ) : Promise < void > {
165- await this . refreshNoteButton . click ( ) ;
143+ await this . refreshNoteButton . click ( { timeout : 15000 } ) ;
166144 }
167145
168146 async isNotebookListVisible ( ) : Promise < boolean > {
169- return this . notebookList . isVisible ( ) ;
147+ return this . zeppelinNodeList . isVisible ( ) ;
170148 }
171149
172150 async clickCreateNewNote ( ) : Promise < void > {
173- await this . nodeList . createNewNoteLink . click ( ) ;
151+ await this . nodeList . createNewNoteLink . click ( { timeout : 15000 } ) ;
152+ await this . createNoteModal . waitFor ( { state : 'visible' } ) ;
153+ }
154+
155+ async createNote ( notebookName : string ) : Promise < void > {
156+ await this . clickCreateNewNote ( ) ;
157+
158+ // Wait for the modal form to be fully rendered with proper labels
159+ await this . page . waitForSelector ( 'nz-form-label' , { timeout : 10000 } ) ;
160+
161+ await this . page . waitForFunction (
162+ ( ) => {
163+ const labels = Array . from ( document . querySelectorAll ( 'nz-form-label' ) ) ;
164+ return labels . some (
165+ label => label . textContent ?. includes ( 'Note Name' ) || label . textContent ?. includes ( 'Clone Note' )
166+ ) ;
167+ } ,
168+ { timeout : 10000 }
169+ ) ;
170+
171+ // Wait for the input field to be ready and enabled
172+ await expect ( this . notebookNameInput ) . toBeVisible ( { timeout : 10000 } ) ;
173+ await expect ( this . notebookNameInput ) . toBeEnabled ( { timeout : 5000 } ) ;
174+
175+ // Clear any existing content and fill notebook name
176+ await this . notebookNameInput . clear ( ) ;
177+ await this . notebookNameInput . fill ( notebookName ) ;
178+
179+ // Verify the input was filled correctly
180+ await expect ( this . notebookNameInput ) . toHaveValue ( notebookName ) ;
181+
182+ // Click the 'Create' button in the modal
183+ await expect ( this . createNoteButton ) . toBeEnabled ( { timeout : 5000 } ) ;
184+ await this . createNoteButton . click ( { timeout : 15000 } ) ;
185+ await this . waitForPageLoad ( ) ;
174186 }
175187
176188 async clickImportNote ( ) : Promise < void > {
177- await this . nodeList . importNoteLink . click ( ) ;
189+ await this . nodeList . importNoteLink . click ( { timeout : 15000 } ) ;
178190 }
179191
180192 async filterNotes ( searchTerm : string ) : Promise < void > {
181- await this . nodeList . filterInput . fill ( searchTerm ) ;
193+ await this . nodeList . filterInput . fill ( searchTerm , { timeout : 15000 } ) ;
182194 }
183195
184196 async waitForRefreshToComplete ( ) : Promise < void > {
0 commit comments