@@ -7,6 +7,7 @@ class SettingsMenu extends BasePage {
77 readonly postUrlInput : Locator ;
88 readonly publishDateInput : Locator ;
99 readonly publishTimeInput : Locator ;
10+ readonly customExcerptInput : Locator ;
1011 readonly deletePostButton : Locator ;
1112 readonly deletePostConfirmButton : Locator ;
1213
@@ -16,6 +17,7 @@ class SettingsMenu extends BasePage {
1617 this . postUrlInput = page . getByRole ( 'textbox' , { name : 'Post URL' } ) ;
1718 this . publishDateInput = page . getByLabel ( 'Date Picker' ) ;
1819 this . publishTimeInput = page . getByLabel ( 'Time Picker' ) ;
20+ this . customExcerptInput = page . locator ( '[data-test-field="custom-excerpt"]' ) ;
1921 this . deletePostButton = page . locator ( '[data-test-button="delete-post"]' ) ;
2022 this . deletePostConfirmButton = page . locator ( '[data-test-button="delete-post-confirm"]' ) ;
2123 }
@@ -30,6 +32,10 @@ class PublishFlow extends BasePage {
3032 readonly publishButton : Locator ;
3133 readonly publishTypeSetting : Locator ;
3234 readonly publishTypeButton : Locator ;
35+ readonly publishAtButton : Locator ;
36+ readonly scheduleSummary : Locator ;
37+ readonly scheduleDateInput : Locator ;
38+ readonly scheduleTimeInput : Locator ;
3339 readonly emailRecipientsSetting : Locator ;
3440 readonly continueButton : Locator ;
3541 readonly confirmButton : Locator ;
@@ -42,6 +48,10 @@ class PublishFlow extends BasePage {
4248 this . publishButton = page . locator ( '[data-test-button="publish-flow"]' ) . first ( ) ;
4349 this . publishTypeSetting = page . locator ( '[data-test-setting="publish-type"]' ) ;
4450 this . publishTypeButton = this . publishTypeSetting . locator ( '> button' ) ;
51+ this . publishAtButton = page . locator ( '[data-test-setting="publish-at"] > button' ) ;
52+ this . scheduleSummary = page . locator ( '[data-test-setting="publish-at"] [data-test-setting-title]' ) ;
53+ this . scheduleDateInput = page . locator ( '[data-test-date-time-picker-date-input]' ) ;
54+ this . scheduleTimeInput = page . locator ( '[data-test-date-time-picker-time-input]' ) ;
4555 this . emailRecipientsSetting = page . locator ( '[data-test-setting="email-recipients"]' ) ;
4656 this . continueButton = page . locator ( '[data-test-modal="publish-flow"] [data-test-button="continue"]' ) ;
4757 this . confirmButton = page . locator ( '[data-test-modal="publish-flow"] [data-test-button="confirm-publish"]' ) ;
@@ -62,6 +72,26 @@ class PublishFlow extends BasePage {
6272 await this . page . locator ( `[data-test-publish-type="${ type } "] + label` ) . click ( ) ;
6373 }
6474
75+ async schedule ( { date, time} : { date ?: string ; time ?: string } ) : Promise < void > {
76+ await this . publishAtButton . click ( ) ;
77+
78+ const textBeforeScheduleToggle = await this . scheduleSummary . textContent ( ) ;
79+ await this . page . locator ( '[data-test-radio="schedule"] + label' ) . click ( ) ;
80+ await this . waitForScheduleSummaryChange ( textBeforeScheduleToggle ) ;
81+
82+ if ( date ) {
83+ const textBeforeDateChange = await this . scheduleSummary . textContent ( ) ;
84+ await this . scheduleDateInput . fill ( date ) ;
85+ await this . scheduleDateInput . blur ( ) ;
86+ await this . waitForScheduleSummaryChange ( textBeforeDateChange ) ;
87+ }
88+
89+ if ( time ) {
90+ await this . scheduleTimeInput . fill ( time ) ;
91+ await this . scheduleTimeInput . blur ( ) ;
92+ }
93+ }
94+
6595 async confirm ( ) : Promise < void > {
6696 await this . continueButton . click ( ) ;
6797 await this . confirmButton . click ( { force : true } ) ;
@@ -75,6 +105,14 @@ class PublishFlow extends BasePage {
75105 ] ) ;
76106 return frontendPage ;
77107 }
108+
109+ private async waitForScheduleSummaryChange ( previousText : string | null ) : Promise < void > {
110+ await this . page . waitForFunction ( ( text ) => {
111+ const element = document . querySelector ( '[data-test-setting="publish-at"] [data-test-setting-title]' ) ;
112+ const currentText = element ?. textContent ?. trim ( ) ;
113+ return Boolean ( currentText && currentText !== text ?. trim ( ) ) ;
114+ } , previousText ) ;
115+ }
78116}
79117
80118export class PostEditorPage extends AdminPage {
@@ -87,14 +125,15 @@ export class PostEditorPage extends AdminPage {
87125 readonly screenTitle : Locator ;
88126 readonly lexicalEditor : Locator ;
89127 readonly secondaryEditor : Locator ;
128+ readonly publishSaveButton : Locator ;
90129
91130 readonly settingsMenu : SettingsMenu ;
92131
93132 constructor ( page : Page ) {
94133 super ( page ) ;
95134 this . pageUrl = '/ghost/#/editor/post/' ;
96135
97- this . titleInput = page . getByRole ( 'textbox' , { name : 'Post title' } ) ;
136+ this . titleInput = page . locator ( '[data-test-editor- title-input]' ) ;
98137 this . postStatus = page . locator ( '[data-test-editor-post-status]' ) ;
99138 this . previewButton = page . getByRole ( 'button' , { name : 'Preview' } ) ;
100139 this . previewModal = new PostPreviewModal ( page ) ;
@@ -103,6 +142,7 @@ export class PostEditorPage extends AdminPage {
103142 this . screenTitle = page . locator ( '[data-test-screen-title]' ) ;
104143 this . lexicalEditor = page . locator ( '[data-kg="editor"]' ) . first ( ) ;
105144 this . secondaryEditor = page . locator ( '[data-secondary-instance="true"]' ) ;
145+ this . publishSaveButton = page . locator ( '[data-test-button="publish-save"]' ) . first ( ) ;
106146
107147 this . settingsMenu = new SettingsMenu ( page ) ;
108148 }
@@ -141,7 +181,28 @@ export class PostEditorPage extends AdminPage {
141181 await this . postStatus . filter ( { hasText : / S a v e d / } ) . waitFor ( { timeout : 30000 } ) ;
142182 }
143183
184+ async appendToBody ( text : string ) : Promise < void > {
185+ await this . lexicalEditor . click ( ) ;
186+ await this . page . keyboard . type ( text ) ;
187+ }
188+
144189 get previewModalDesktopFrame ( ) : DesktopPreviewFrame {
145190 return this . previewModal . desktopPreview ;
146191 }
147192}
193+
194+ export class PageEditorPage extends PostEditorPage {
195+ readonly newPageButton : Locator ;
196+
197+ constructor ( page : Page ) {
198+ super ( page ) ;
199+ this . pageUrl = '/ghost/#/pages' ;
200+ this . newPageButton = page . locator ( '[data-test-new-page-button]' ) ;
201+ }
202+
203+ async gotoNew ( ) : Promise < void > {
204+ await this . page . goto ( this . pageUrl ) ;
205+ await this . newPageButton . click ( ) ;
206+ await this . titleInput . waitFor ( { state : 'visible' } ) ;
207+ }
208+ }
0 commit comments