Skip to content

Commit 2583ea0

Browse files
committed
Make the E2Es runnable against wp.com
1 parent 78f2af9 commit 2583ea0

3 files changed

Lines changed: 67 additions & 60 deletions

File tree

‎packages/e2e-test-utils-playwright/src/request-utils/login.ts‎

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,45 @@ export interface User {
99
}
1010

1111
async function login( this: RequestUtils, user: User = this.user ) {
12-
// Login to admin using request context.
13-
let response = await this.request.post( 'wp-login.php', {
14-
failOnStatusCode: true,
15-
form: {
16-
log: user.username,
17-
pwd: user.password,
18-
},
19-
} );
20-
await response.dispose();
12+
// Get the client ID and secret from the environment.
13+
const clientId = process.env.WP_CLIENT_ID;
14+
const clientSecret = process.env.WP_CLIENT_SECRET;
15+
if ( ! clientId || ! clientSecret ) {
16+
throw new Error(
17+
'WP_CLIENT_ID and WP_CLIENT_SECRET environment variables must be set.'
18+
);
19+
}
2120

22-
// Get the nonce.
23-
response = await this.request.get(
24-
'wp-admin/admin-ajax.php?action=rest-nonce',
21+
// Log in and get the bearer token.
22+
const response = await this.request.post(
23+
'https://wordpress.com/wp-login.php?action=login-endpoint',
2524
{
25+
headers: {
26+
Accept: 'application/json',
27+
'Content-Type': 'application/x-www-form-urlencoded',
28+
},
2629
failOnStatusCode: true,
30+
form: {
31+
username: user.username,
32+
password: user.password,
33+
client_id: clientId,
34+
client_secret: clientSecret,
35+
get_bearer_token: '1',
36+
},
2737
}
2838
);
29-
const nonce = await response.text();
3039

31-
return nonce;
40+
const payload = await response.json();
41+
42+
await response.dispose();
43+
44+
if ( ! payload?.data?.bearer_token ) {
45+
throw new Error(
46+
'Unable to log in. Please check your username and password.'
47+
);
48+
}
49+
50+
return payload.data.bearer_token as string;
3251
}
3352

3453
export { login };

‎packages/e2e-test-utils-playwright/src/request-utils/rest.ts‎

Lines changed: 23 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -21,34 +21,15 @@ function splitRequestsToChunks( requests: BatchRequest[], chunkSize: number ) {
2121
return cache;
2222
}
2323

24-
async function getAPIRootURL( request: APIRequestContext ) {
25-
// Discover the API root url using link header.
26-
// See https://developer.wordpress.org/rest-api/using-the-rest-api/discovery/#link-header
27-
const response = await request.head( WP_BASE_URL );
28-
const links = response.headers().link;
29-
const restLink = links?.match( /<([^>]+)>; rel="https:\/\/api\.w\.org\/"/ );
30-
31-
if ( ! restLink ) {
32-
throw new Error( `Failed to discover REST API endpoint.
33-
Link header: ${ links }` );
34-
}
35-
36-
const [ , rootURL ] = restLink;
37-
38-
return rootURL;
39-
}
40-
4124
async function setupRest( this: RequestUtils ): Promise< StorageState > {
42-
const [ nonce, rootURL ] = await Promise.all( [
43-
this.login(),
44-
getAPIRootURL( this.request ),
45-
] );
25+
const rootURL = 'https://public-api.wordpress.com/';
26+
const bearerToken = await this.login();
4627

4728
const { cookies } = await this.request.storageState();
4829

4930
const storageState: StorageState = {
5031
cookies,
51-
nonce,
32+
bearerToken,
5233
rootURL,
5334
};
5435

@@ -84,11 +65,18 @@ async function rest< RestResponse = any >(
8465
throw new Error( '"path" is required to make a REST call' );
8566
}
8667

87-
if ( ! this.storageState?.nonce || ! this.storageState?.rootURL ) {
68+
if ( ! this.storageState?.bearerToken || ! this.storageState?.rootURL ) {
8869
await this.setupRest();
8970
}
9071

91-
const relativePath = path.startsWith( '/' ) ? path.slice( 1 ) : path;
72+
const wpcomPath = path.replace(
73+
'/wp/v2/',
74+
`/wp/v2/sites/${ new URL( WP_BASE_URL ).host }/`
75+
);
76+
77+
const relativePath = wpcomPath.startsWith( '/' )
78+
? wpcomPath.slice( 1 )
79+
: wpcomPath;
9280

9381
const url = this.storageState!.rootURL + relativePath;
9482

@@ -97,7 +85,7 @@ async function rest< RestResponse = any >(
9785
...fetchOptions,
9886
failOnStatusCode: false,
9987
headers: {
100-
'X-WP-Nonce': this.storageState!.nonce,
88+
Authorization: `Bearer ${ this.storageState!.bearerToken }`,
10189
...( fetchOptions.headers || {} ),
10290
},
10391
} );
@@ -110,16 +98,16 @@ async function rest< RestResponse = any >(
11098
return json;
11199
} catch ( error ) {
112100
// Nonce in invalid, retry again with a renewed nonce.
113-
if (
114-
typeof error === 'object' &&
115-
error !== null &&
116-
Object.prototype.hasOwnProperty.call( error, 'code' ) &&
117-
( error as { code: string } ).code === 'rest_cookie_invalid_nonce'
118-
) {
119-
await this.setupRest();
120-
121-
return this.rest( options );
122-
}
101+
// if (
102+
// typeof error === 'object' &&
103+
// error !== null &&
104+
// Object.prototype.hasOwnProperty.call( error, 'code' ) &&
105+
// ( error as { code: string } ).code === 'rest_cookie_invalid_nonce'
106+
// ) {
107+
// await this.setupRest();
108+
109+
// return this.rest( options );
110+
// }
123111

124112
throw error;
125113
}

‎test/e2e/config/global-setup.ts‎

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,17 @@ async function globalSetup( config: FullConfig ) {
2626
await requestUtils.setupRest();
2727

2828
// Reset the test environment before running the tests.
29-
await Promise.all( [
30-
requestUtils.activateTheme( 'twentytwentyone' ),
31-
// Disable this test plugin as it's conflicting with some of the tests.
32-
// We already have reduced motion enabled and Playwright will wait for most of the animations anyway.
33-
requestUtils.deactivatePlugin(
34-
'gutenberg-test-plugin-disables-the-css-animations'
35-
),
36-
requestUtils.deleteAllPosts(),
37-
requestUtils.deleteAllBlocks(),
38-
requestUtils.resetPreferences(),
39-
] );
29+
// await Promise.all( [
30+
// requestUtils.activateTheme( 'twentytwentyone' ),
31+
// Disable this test plugin as it's conflicting with some of the tests.
32+
// We already have reduced motion enabled and Playwright will wait for most of the animations anyway.
33+
// requestUtils.deactivatePlugin(
34+
// 'gutenberg-test-plugin-disables-the-css-animations'
35+
// ),
36+
// requestUtils.deleteAllPosts(),
37+
// requestUtils.deleteAllBlocks(),
38+
// requestUtils.resetPreferences(),
39+
// ] );
4040

4141
await requestContext.dispose();
4242
}

0 commit comments

Comments
 (0)