@imwz/wp-pattern-sentinel 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/login.js +26 -4
- package/src/main.js +17 -12
package/package.json
CHANGED
package/src/login.js
CHANGED
|
@@ -2,14 +2,36 @@ import { log } from './format.js';
|
|
|
2
2
|
|
|
3
3
|
export async function loginToWordPress(page, adminUrl, user, pass) {
|
|
4
4
|
try {
|
|
5
|
-
|
|
5
|
+
// Navigate to the editor — WordPress redirects to wp-login.php if unauthenticated,
|
|
6
|
+
// with redirect_to preserving the editor URL (important for multisite subsite context).
|
|
7
|
+
await page.goto(`${adminUrl}/wp-admin/post-new.php?post_type=page`, {
|
|
6
8
|
waitUntil: 'domcontentloaded',
|
|
7
|
-
timeout:
|
|
9
|
+
timeout: 60000,
|
|
8
10
|
});
|
|
11
|
+
|
|
12
|
+
// Already logged in — editor loaded directly
|
|
13
|
+
if (await page.locator('.edit-post-layout, .editor-styles-wrapper').count() > 0) {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Wait for the login form to be ready before filling
|
|
18
|
+
await page.waitForSelector('#user_login', { state: 'visible', timeout: 30000 });
|
|
9
19
|
await page.fill('#user_login', user);
|
|
10
20
|
await page.fill('#user_pass', pass);
|
|
11
|
-
|
|
12
|
-
|
|
21
|
+
|
|
22
|
+
// Start listening for navigation BEFORE clicking — avoids missing the redirect
|
|
23
|
+
await Promise.all([
|
|
24
|
+
page.waitForNavigation({ waitUntil: 'domcontentloaded', timeout: 60000 }),
|
|
25
|
+
page.click('#wp-submit'),
|
|
26
|
+
]);
|
|
27
|
+
|
|
28
|
+
const loggedIn = page.url().includes('/wp-admin/') && !page.url().includes('wp-login.php');
|
|
29
|
+
if (!loggedIn) {
|
|
30
|
+
const error = await page.textContent('#login_error').catch(() => null);
|
|
31
|
+
log(`Login failed: ${error?.trim() ?? 'unexpected URL after submit: ' + page.url()}`, 'red');
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
|
|
13
35
|
return true;
|
|
14
36
|
} catch (error) {
|
|
15
37
|
log(`Login failed: ${error.message}`, 'red');
|
package/src/main.js
CHANGED
|
@@ -30,20 +30,25 @@ export async function main() {
|
|
|
30
30
|
args: ['--disable-web-security'],
|
|
31
31
|
});
|
|
32
32
|
|
|
33
|
-
//
|
|
33
|
+
// Login once, then share the session cookies across all worker contexts.
|
|
34
|
+
// Concurrent logins to WordPress (even with valid credentials) trigger a
|
|
35
|
+
// reauth=1 redirect loop — serialising login avoids this entirely.
|
|
34
36
|
let contexts;
|
|
35
37
|
try {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
38
|
+
const firstContext = await browser.newContext({ viewport: options.viewport });
|
|
39
|
+
const loginPage = await firstContext.newPage();
|
|
40
|
+
loginPage.setDefaultTimeout(60000);
|
|
41
|
+
const ok = await loginToWordPress(loginPage, options.adminUrl, options.user, options.pass);
|
|
42
|
+
await loginPage.close();
|
|
43
|
+
if (!ok) throw new Error('Failed to authenticate with WordPress');
|
|
44
|
+
|
|
45
|
+
const cookies = await firstContext.cookies();
|
|
46
|
+
contexts = [firstContext];
|
|
47
|
+
for (let i = 1; i < options.concurrency; i++) {
|
|
48
|
+
const ctx = await browser.newContext({ viewport: options.viewport });
|
|
49
|
+
await ctx.addCookies(cookies);
|
|
50
|
+
contexts.push(ctx);
|
|
51
|
+
}
|
|
47
52
|
} catch (error) {
|
|
48
53
|
log(error.message, 'red');
|
|
49
54
|
await browser.close();
|