-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
E2E Utils: add setPreferences and editPost utils #55099
Changes from all commits
fe70678
aecd765
ecef484
86c8f79
a3c356e
8ac5f11
148c15b
c3f20f5
ddfd869
256f5b9
34f93b3
6e5feb7
59720fe
d2aba51
9559d8e
7658a0a
36b26c2
99c2b2d
8b7ffd2
fa96ad2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/** | ||
* Internal dependencies | ||
*/ | ||
import type { Admin } from './'; | ||
|
||
interface NewPostOptions { | ||
postType?: string; | ||
title?: string; | ||
content?: string; | ||
excerpt?: string; | ||
showWelcomeGuide?: boolean; | ||
} | ||
|
||
/** | ||
* Creates new post. | ||
* | ||
* @param this | ||
* @param options Options to create new post. | ||
*/ | ||
export async function createNewPost( | ||
this: Admin, | ||
options: NewPostOptions = {} | ||
) { | ||
const query = new URLSearchParams(); | ||
const { postType, title, content, excerpt } = options; | ||
|
||
if ( postType ) query.set( 'post_type', postType ); | ||
if ( title ) query.set( 'post_title', title ); | ||
if ( content ) query.set( 'content', content ); | ||
if ( excerpt ) query.set( 'excerpt', excerpt ); | ||
|
||
await this.visitAdminPage( 'post-new.php', query.toString() ); | ||
|
||
await this.editor.setPreferences( 'core/edit-post', { | ||
welcomeGuide: options.showWelcomeGuide ?? false, | ||
fullscreenMode: false, | ||
} ); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/** | ||
* Internal dependencies | ||
*/ | ||
import type { Admin } from '.'; | ||
|
||
/** | ||
* Open the post with given ID in the editor. | ||
* | ||
* @param this | ||
* @param postId Post ID to visit. | ||
*/ | ||
export async function editPost( this: Admin, postId: string | number ) { | ||
const query = new URLSearchParams(); | ||
|
||
query.set( 'post', String( postId ) ); | ||
query.set( 'action', 'edit' ); | ||
|
||
await this.visitAdminPage( 'post.php', query.toString() ); | ||
|
||
await this.editor.setPreferences( 'core/edit-post', { | ||
welcomeGuide: false, | ||
fullscreenMode: false, | ||
} ); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,72 +1,51 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { addQueryArgs } from '@wordpress/url'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import type { Admin } from './'; | ||
|
||
export interface SiteEditorQueryParams { | ||
postId: string | number; | ||
postType: string; | ||
interface SiteEditorOptions { | ||
postId?: string | number; | ||
postType?: string; | ||
path?: string; | ||
canvas?: string; | ||
showWelcomeGuide?: boolean; | ||
} | ||
|
||
const CANVAS_SELECTOR = 'iframe[title="Editor canvas"i] >> visible=true'; | ||
|
||
/** | ||
* Visits the Site Editor main page | ||
* | ||
* By default, it also skips the welcome guide. The option can be disabled if need be. | ||
* Visits the Site Editor main page. | ||
* | ||
* @param this | ||
* @param query Query params to be serialized as query portion of URL. | ||
* @param skipWelcomeGuide Whether to skip the welcome guide as part of the navigation. | ||
* @param options Options to visit the site editor. | ||
*/ | ||
export async function visitSiteEditor( | ||
this: Admin, | ||
query: SiteEditorQueryParams, | ||
skipWelcomeGuide = true | ||
options: SiteEditorOptions = {} | ||
) { | ||
const path = addQueryArgs( '', { | ||
...query, | ||
} ).slice( 1 ); | ||
|
||
await this.visitAdminPage( 'site-editor.php', path ); | ||
|
||
if ( skipWelcomeGuide ) { | ||
await this.page.evaluate( () => { | ||
window.wp.data | ||
.dispatch( 'core/preferences' ) | ||
.set( 'core/edit-site', 'welcomeGuide', false ); | ||
|
||
window.wp.data | ||
.dispatch( 'core/preferences' ) | ||
.set( 'core/edit-site', 'welcomeGuideStyles', false ); | ||
|
||
window.wp.data | ||
.dispatch( 'core/preferences' ) | ||
.set( 'core/edit-site', 'welcomeGuidePage', false ); | ||
|
||
window.wp.data | ||
.dispatch( 'core/preferences' ) | ||
.set( 'core/edit-site', 'welcomeGuideTemplate', false ); | ||
const { postId, postType, path, canvas } = options; | ||
const query = new URLSearchParams(); | ||
|
||
if ( postId ) query.set( 'postId', String( postId ) ); | ||
if ( postType ) query.set( 'postType', postType ); | ||
if ( path ) query.set( 'path', path ); | ||
if ( canvas ) query.set( 'canvas', canvas ); | ||
|
||
await this.visitAdminPage( 'site-editor.php', query.toString() ); | ||
|
||
if ( ! options.showWelcomeGuide ) { | ||
await this.editor.setPreferences( 'core/edit-site', { | ||
welcomeGuide: false, | ||
welcomeGuideStyles: false, | ||
welcomeGuidePage: false, | ||
welcomeGuideTemplate: false, | ||
} ); | ||
} | ||
|
||
// Check if the current page has an editor canvas first. | ||
if ( ( await this.page.locator( CANVAS_SELECTOR ).count() ) > 0 ) { | ||
// The site editor initially loads with an empty body, | ||
// we need to wait for the editor canvas to be rendered. | ||
await this.page | ||
.frameLocator( CANVAS_SELECTOR ) | ||
.locator( 'body > *' ) | ||
.first() | ||
.waitFor(); | ||
} | ||
|
||
Comment on lines
-58
to
-67
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This code removal doesn't look related to the changes proposed in this PR. As discussed in #54911, there were usually good reasons for introducing similar guardrails. Maybe we should split this into a separate PR. What do you think? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ugh, nice catch! I actually forgot to restore this part. I wasn't planning on removing it in this PR, only running a single round without it to see how it goes. Restoring it now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's good, though, that now we know only perf tests fail without it - these tests require specific handling, so it might be good to move this safeguard there if it's not necessary here for the regular E2Es. Anyway, it's just a note for myself, I guess - let's leave that for another PR. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I had to remove it as the slight timing change caused by using
ℹ️ The other iframes are previews of the patterns created in that test. |
||
// TODO: Ideally the content underneath the canvas loader should be marked inert until it's ready. | ||
/** | ||
* @todo This is a workaround for the fact that the editor canvas is seen as | ||
* ready and visible before the loading spinner is hidden. Ideally, the | ||
* content underneath the loading overlay should be marked inert until the | ||
* loading is done. | ||
*/ | ||
await this.page | ||
.locator( '.edit-site-canvas-loader' ) | ||
// Bigger timeout is needed for larger entities, for example the large | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/** | ||
* Internal dependencies | ||
*/ | ||
import type { Editor } from './index'; | ||
|
||
type PreferencesContext = | ||
| 'core/edit-post' | ||
| 'core/edit-site' | ||
| 'core/customize-widgets'; | ||
|
||
/** | ||
* Set the preferences of the editor. | ||
* | ||
* @param this | ||
* @param context Context to set preferences for. | ||
* @param preferences Preferences to set. | ||
*/ | ||
export async function setPreferences( | ||
this: Editor, | ||
context: PreferencesContext, | ||
preferences: Record< string, any > | ||
) { | ||
await this.page.waitForFunction( () => window?.wp?.data ); | ||
|
||
await this.page.evaluate( | ||
async ( props ) => { | ||
for ( const [ key, value ] of Object.entries( | ||
props.preferences | ||
) ) { | ||
await window.wp.data | ||
.dispatch( 'core/preferences' ) | ||
.set( props.context, key, value ); | ||
} | ||
}, | ||
{ context, preferences } | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious to know if we need to do this every time, seems wasteful to me. Could we just do this in
global-setup
with a network request? I know that the preference API doesn't seem stable in e2e tests though 😅,There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the idea. The only time the welcome guide needs to be enabled is when we're actually testing it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there an existing util for setting prefs via a network request? 🤔