Skip to content

Commit

Permalink
initial commit migrating puppetear utils into playwright and typescript
Browse files Browse the repository at this point in the history
  • Loading branch information
MaggieCabrera committed Feb 3, 2023
1 parent 53a4d51 commit 552438f
Show file tree
Hide file tree
Showing 4 changed files with 333 additions and 3 deletions.
3 changes: 3 additions & 0 deletions packages/e2e-test-utils-playwright/src/request-utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { activateTheme } from './themes';
import { deleteAllBlocks } from './blocks';
import { createComment, deleteAllComments } from './comments';
import { createPost, deleteAllPosts } from './posts';
import { createMenu, deleteAllMenus } from './menus';
import { resetPreferences } from './preferences';
import { getSiteSettings, updateSiteSettings } from './site-settings';
import { deleteAllWidgets, addWidgetBlock } from './widgets';
Expand Down Expand Up @@ -125,6 +126,8 @@ class RequestUtils {
deleteAllBlocks = deleteAllBlocks;
createPost = createPost.bind( this );
deleteAllPosts = deleteAllPosts.bind( this );
createMenu = createMenu.bind( this );
deleteAllMenus = deleteAllMenus;
createComment = createComment.bind( this );
deleteAllComments = deleteAllComments.bind( this );
deleteAllWidgets = deleteAllWidgets.bind( this );
Expand Down
179 changes: 179 additions & 0 deletions packages/e2e-test-utils-playwright/src/request-utils/menus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
/**
* Internal dependencies
*/
import type { RequestUtils } from './index';

const MENUS_ENDPOINT = '/wp/v2/menus';
const MENU_ITEMS_ENDPOINT = '/wp/v2/menu-items';

export interface Menu {
name: string;
}

export interface MenuItem {
id: number;
title: string;
status: 'publish' | 'future' | 'draft' | 'pending' | 'private';
object: 'page';
menu_order: number;
}

export interface Post {
id: number;
content: string;
status: 'publish' | 'future' | 'draft' | 'pending' | 'private';
title: {
raw: string;
rendered: string;
};
}

export interface ObjectRequests extends Post {
method?: string;
path: string;
headers?: Record< string, string | string[] >;
link: string;
}

const menuItemObjectRequests = {
post: ( menuItem: MenuItem ) => ( {
path: '/wp/v2/posts',
method: 'POST',
data: {
title: menuItem.title,
status: 'publish',
},
} ),
page: ( menuItem: MenuItem ) => ( {
path: '/wp/v2/pages',
method: 'POST',
data: {
title: menuItem.title,
status: 'publish',
},
} ),
};

const menuItemObjectMatchers = {
post: ( menuItem: MenuItem, post: Post ) =>
menuItem.title === post.title.raw,
page: ( menuItem: MenuItem, page: Post ) =>
menuItem.title === page.title.raw,
};

/**
* Reset user preferences
*
*/
export async function deleteAllMenus( this: RequestUtils ) {
const menus = await this.rest( { path: MENUS_ENDPOINT } );

if ( ! menus?.length ) return;

await this.batchRest(
menus.map( ( menu: MenuItem ) => ( {
method: 'DELETE',
path: `${ MENUS_ENDPOINT }/${ menu.id }?force=true`,
} ) )
);
}

/**
* Create menus and all linked resources for the menu using the REST API.
*
* @param {} this RequestUtils.
* @param {Object} menu Rest payload for the menu
* @param {?Array} menuItems Data for any menu items to be created.
*/
export async function createMenu(
this: RequestUtils,
menu: Menu,
menuItems: MenuItem[]
) {
// Step 1. Create the menu.
const menuResponse = await this.rest( {
method: 'POST',
path: MENUS_ENDPOINT,
data: menu,
} );

if ( ! menuItems?.length ) {
return;
}

// Step 2. Create all the pages/posts/categories etc. that menu items
// are linked to. These items don't support rest batching so create them
// using individual requests.
const objectRequests = menuItems
.map( ( menuItem: MenuItem ) => {
const getRequest = menuItemObjectRequests[ menuItem.object ];
if ( ! getRequest ) {
return undefined;
}
return getRequest( menuItem );
} )
.filter( ( request ) => !! request );
const objectResponses: ObjectRequests[] = [];
for ( const objectRequest of objectRequests ) {
if ( ! objectRequest ) continue;
const objectResponse = await this.rest( objectRequest );
objectResponses.push( objectResponse );
}

// Step 3. Create the initial menu items without assigned parents. We need
// the ids of all the menu items first before being able to assign the
// correct id of the parent.
/*const menuItemsResponse =*/ await this.batchRest(
menuItems.map( ( menuItem: MenuItem ) => {
// If the menu item is linked to an 'object', get the id for that
// object.
const objectMatcher = menuItemObjectMatchers[ menuItem.object ];
let object;
if ( objectMatcher ) {
object = objectResponses.find( ( objectResponse ) => {
return objectMatcher( menuItem, objectResponse );
} );
}

return {
method: 'POST',
path: MENU_ITEMS_ENDPOINT,
body: {
menus: menuResponse.id,
object_id: object?.id,
url: object?.link,
...menuItem,
parent: undefined,
},
};
} )
);

// Step 4. Make another menu item request to assign parents.

/*await this.batchRest(
menuItems
.map( ( menuItem: MenuItem, index: number ) => {
// In the fixture data, the parent corresponds to the
// index in the array, dereference that to find the actual
// menu item id.
const fixtureParentIndex = menuItem?.parent !== undefined;
// Skip any menu items that are top level.
if ( ! fixtureParentIndex ) {
return undefined;
}
const parent = menuItemsResponse[ menuItem.parent ].body.id;
const menuItemResponse = menuItemsResponse[ index ];
const menuItemId = menuItemResponse.body.id;
return {
method: 'PUT',
path: `${ MENU_ITEMS_ENDPOINT }/${ menuItemId }`,
body: { ...menuItemResponse.body, parent },
};
} )
.filter( ( request ) => !! request )
);*/
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
module.exports = [
{
title: 'Home',
url: 'http://localhost:8889/',
menu_order: 1,
},
{
title: 'About',
type: 'post_type',
object: 'page',
menu_order: 2,
},
{
title: 'Our team',
type: 'post_type',
object: 'page',
menu_order: 3,
parent: 1,
},
{
title: 'Shop',
type: 'post_type',
object: 'page',
menu_order: 4,
},
{
title: 'Winter apparel',
type: 'post_type',
object: 'page',
menu_order: 5,
parent: 3,
},
{
title: 'Chunky socks',
type: 'post_type',
object: 'page',
menu_order: 6,
parent: 4,
},
{
title: 'Hideous hats',
type: 'post_type',
object: 'page',
menu_order: 7,
parent: 4,
},
{
title: 'Glorious gloves',
type: 'post_type',
object: 'page',
menu_order: 8,
parent: 4,
},
{
title: 'Jazzy Jumpers',
type: 'post_type',
object: 'page',
menu_order: 9,
parent: 4,
},
{
title: 'Shipping',
type: 'post_type',
object: 'page',
menu_order: 10,
},
{
title: 'Contact Us',
type: 'post_type',
object: 'page',
menu_order: 11,
},
{
title: 'WordPress.org',
url: 'https://wordpress.org',
menu_order: 12,
},
{
title: 'Google',
url: 'https://google.com',
menu_order: 13,
parent: 11,
},
];
70 changes: 67 additions & 3 deletions test/e2e/specs/editor/blocks/navigation.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,42 @@
*/
const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' );

/**
* Internal dependencies
*/
const menuItemsFixture = require( './fixtures/menu-items-request-fixture.js' );

test.use( {
navBlockUtils: async ( { page, requestUtils }, use ) => {
await use( new NavigationBlockUtils( { page, requestUtils } ) );
},
} );

test.describe(
'As a user I want the navigation block to fallback to the best possible default',
() => {
test.beforeAll( async ( { requestUtils } ) => {
await requestUtils.activateTheme( 'emptytheme' );
} );

test.beforeEach( async ( { admin } ) => {
await admin.createNewPost();
test.beforeEach( async ( { admin, requestUtils } ) => {
await Promise.all( [
requestUtils.deleteAllPosts(),
requestUtils.deleteAllPosts( 'pages' ),
requestUtils.deleteAllPosts( 'navigation' ),
requestUtils.deleteAllMenus(),
admin.createNewPost(),
] );
} );

test.afterAll( async ( { requestUtils } ) => {
await requestUtils.activateTheme( 'twentytwentyone' );
await Promise.all( [
requestUtils.deleteAllPosts(),
requestUtils.deleteAllPosts( 'pages' ),
requestUtils.deleteAllPosts( 'navigation' ),
requestUtils.deleteAllMenus(),
requestUtils.activateTheme( 'twentytwentyone' ),
] );
} );

test.afterEach( async ( { requestUtils } ) => {
Expand Down Expand Up @@ -48,5 +71,46 @@ test.describe(
<!-- /wp:navigation -->`
);
} );

test( 'default to my most recently created menu', async ( {
editor,
requestUtils,
} ) => {
//Create a menu
await requestUtils.createMenu(
{ name: 'Test Menu 1' },
menuItemsFixture
);
//insert navigation block
//check the markup of the block
//check the block in the list view?
//check the block in the frontend?
await editor.page.pause();
} );
}
);

class NavigationBlockUtils {
constructor( { editor, page, requestUtils } ) {
this.editor = editor;
this.page = page;
this.requestUtils = requestUtils;
}

/**
* Create a navigation menu
*
* @param {Object} menuData navigation menu post data.
* @return {string} Menu content.
*/
async createNavigationMenu( menuData ) {
return this.requestUtils.rest( {
method: 'POST',
path: `/wp/v2/navigation/`,
data: {
status: 'publish',
...menuData,
},
} );
}
}

0 comments on commit 552438f

Please sign in to comment.