1010 * limitations under the License.
1111 */
1212
13- import { expect , Locator , Page } from '@playwright/test' ;
14- import { getCurrentPath , waitForUrlNotContaining } from '../utils' ;
13+ import { Locator , Page } from '@playwright/test' ;
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 . isElementVisible ( this . welcomeHeading ) ;
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 . isElementVisible ( this . anonymousUserIndicator ) ;
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 . clickElement ( this . zeppelinLogo ) ;
152130 }
153131
154132 async getWelcomeHeadingText ( ) : Promise < string > {
@@ -162,23 +140,42 @@ export class HomePage extends BasePage {
162140 }
163141
164142 async clickRefreshNotes ( ) : Promise < void > {
165- await this . refreshNoteButton . click ( ) ;
143+ await this . clickElement ( this . refreshNoteButton ) ;
166144 }
167145
168146 async isNotebookListVisible ( ) : Promise < boolean > {
169- return this . notebookList . isVisible ( ) ;
147+ return this . isElementVisible ( this . zeppelinNodeList ) ;
170148 }
171149
172150 async clickCreateNewNote ( ) : Promise < void > {
173- await this . nodeList . createNewNoteLink . click ( ) ;
151+ await this . clickElement ( this . nodeList . createNewNoteLink ) ;
152+ await this . createNoteModal . waitFor ( { state : 'visible' } ) ;
153+ }
154+
155+ async createNote ( notebookName : string ) : Promise < void > {
156+ await this . clickCreateNewNote ( ) ;
157+ await this . fillInput ( this . notebookNameInput , notebookName , { force : true } ) ;
158+
159+ // Wait for input value to be set (especially important for Webkit)
160+ await this . page . waitForFunction (
161+ name => {
162+ const input = document . querySelector ( 'input[name="noteName"]' ) as HTMLInputElement ;
163+ return input && input . value === name ;
164+ } ,
165+ notebookName ,
166+ { timeout : 5000 }
167+ ) ;
168+
169+ await this . clickElement ( this . createNoteButton ) ;
170+ await this . waitForPageLoad ( ) ;
174171 }
175172
176173 async clickImportNote ( ) : Promise < void > {
177- await this . nodeList . importNoteLink . click ( ) ;
174+ await this . clickElement ( this . nodeList . importNoteLink ) ;
178175 }
179176
180177 async filterNotes ( searchTerm : string ) : Promise < void > {
181- await this . nodeList . filterInput . fill ( searchTerm ) ;
178+ await this . fillInput ( this . nodeList . filterInput , searchTerm ) ;
182179 }
183180
184181 async waitForRefreshToComplete ( ) : Promise < void > {
0 commit comments