Skip to content

Commit f077a73

Browse files
committed
👌 IMPROVE: Disembark
1 parent f14d4e1 commit f077a73

File tree

1 file changed

+40
-23
lines changed

1 file changed

+40
-23
lines changed

commands/disembark

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# ----------------------------------------------------
44
function run_disembark() {
55
local target_url="$1"
6+
local debug_flag="$2"
67

78
echo "🚀 Starting Disembark process for ${target_url}..."
89

@@ -59,31 +60,34 @@ const path = require('path');
5960
const PLUGIN_ZIP_URL = 'https://github.com/DisembarkHost/disembark-connector/releases/latest/download/disembark-connector.zip';
6061

6162
async function main() {
62-
const [, , targetUrl, username, password] = process.argv;
63+
const [, , targetUrl, username, password, debugFlag] = process.argv;
6364

6465
if (!targetUrl || !username || !password) {
65-
console.error('Usage: node disembark-browser.js <url> <username> <password>');
66+
console.error('Usage: node disembark-browser.js <url> <username> <password> [debug]');
6667
process.exit(1);
6768
}
6869

69-
const browser = await chromium.launch({ headless: true });
70+
const isHeadless = debugFlag !== 'true';
71+
const browser = await chromium.launch({ headless: isHeadless });
72+
7073
const context = await browser.newContext({
7174
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36'
7275
});
7376
const page = await context.newPage();
7477
try {
7578
// 1. LOGIN
7679
process.stdout.write(' - Step 1/5: Authenticating with WordPress...');
77-
await page.goto(`${targetUrl}/wp-login.php`, { waitUntil: 'domcontentloaded' });
80+
await page.goto(`${targetUrl}/wp-login.php`, { waitUntil: 'domcontentloaded' });
81+
await page.waitForSelector('#user_login', { state: 'visible', timeout: 30000 });
7882
await page.fill('#user_login', username);
83+
await page.waitForSelector('#user_pass', { state: 'visible', timeout: 30000 });
7984
await page.fill('#user_pass', password);
80-
// Click first, then wait for a specific element on the next page. This is more reliable.
81-
await page.click('#wp-submit');
82-
await page.waitForSelector('#wpadminbar', { timeout: 60000 }); // Wait 60s for admin bar
85+
await page.waitForSelector('#wp-submit', { state: 'visible', timeout: 30000 });
86+
await page.click('#wp-submit');
87+
await page.waitForSelector('#wpadminbar', { timeout: 60000 });
8388

84-
// Verify login by checking for the admin bar.
8589
if (!(await page.isVisible('#wpadminbar'))) {
86-
throw new Error('Authentication failed. Please check credentials or for 2FA/CAPTCHA.');
90+
throw new Error('Authentication failed. Please check credentials or for 2FA/CAPTCHA.');
8791
}
8892
console.log(' Success!');
8993

@@ -93,8 +97,7 @@ async function main() {
9397

9498
const pluginRow = page.locator('tr[data-slug="disembark-connector"]');
9599
if (await pluginRow.count() > 0) {
96-
console.log(' Plugin found.');
97-
// More robustly check if the 'Activate' link exists.
100+
console.log(' Plugin found.');
98101
const activateLink = pluginRow.locator('a.edit:has-text("Activate")');
99102
if (await activateLink.count() > 0) {
100103
process.stdout.write(' - Activating existing plugin...');
@@ -104,15 +107,14 @@ async function main() {
104107
]);
105108
console.log(' Activated!');
106109
} else {
107-
console.log(' - Plugin already active.');
110+
console.log(' - Plugin already active.');
108111
}
109112
} else {
110113
// 3. UPLOAD AND INSTALL PLUGIN
111-
console.log(' Plugin not found, proceeding with installation.');
114+
console.log(' Plugin not found, proceeding with installation.');
112115
process.stdout.write(' - Step 3/5: Downloading plugin...');
113116
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'disembark-'));
114117
const pluginZipPath = path.join(tempDir, 'disembark-connector.zip');
115-
// This promise-based downloader now correctly handles HTTP redirects.
116118
await new Promise((resolve, reject) => {
117119
const file = fs.createWriteStream(pluginZipPath);
118120
const request = (url) => {
@@ -139,15 +141,16 @@ async function main() {
139141

140142
await page.click('input#install-plugin-submit');
141143

142-
// Define selectors for possible outcomes after installation attempt.
144+
// Define selectors for all possible outcomes after installation attempt.
143145
const activationLinkSelector = 'a:has-text("Activate Plugin"), a.activate-now, .button.activate-now';
144146
const alreadyInstalledSelector = 'body:has-text("Destination folder already exists.")';
145-
const genericErrorSelector = '.wrap > .error, .wrap > #message.error'; // Common WP error notice selectors
147+
const mixedSuccessSelector = 'body:has-text("Plugin installed successfully.")'; // For your specific error case
148+
const genericErrorSelector = '.wrap > .error, .wrap > #message.error';
146149

147150
try {
148-
// Wait for any of the outcomes to appear on the page.
151+
// Wait for ANY of the outcomes to appear on the page.
149152
await page.waitForSelector(
150-
`${activationLinkSelector}, ${alreadyInstalledSelector}, ${genericErrorSelector}`,
153+
`${activationLinkSelector}, ${alreadyInstalledSelector}, ${mixedSuccessSelector}, ${genericErrorSelector}`,
151154
{ timeout: 90000 }
152155
);
153156
} catch (e) {
@@ -167,9 +170,23 @@ async function main() {
167170
} else if (await page.locator(alreadyInstalledSelector).count() > 0) {
168171
// Outcome 2: The plugin was already installed.
169172
console.log(' Plugin already installed.');
170-
// No action needed here, the script will proceed to the token retrieval step.
173+
} else if (await page.locator(mixedSuccessSelector).count() > 0) {
174+
// Outcome 3: Install was successful, but the page crashed.
175+
console.log(' Install succeeded, but page reported an error. Navigating to plugins page to activate...');
176+
await page.goto(`${targetUrl}/wp-admin/plugins.php`, { waitUntil: 'networkidle' });
177+
const pluginRow = page.locator('tr[data-slug="disembark-connector"]');
178+
const activateLink = pluginRow.locator('a.edit:has-text("Activate")');
179+
if (await activateLink.count() > 0) {
180+
await Promise.all([
181+
page.waitForNavigation({ waitUntil: 'networkidle' }),
182+
activateLink.click()
183+
]);
184+
console.log(' Activated!');
185+
} else {
186+
console.log(' - Plugin was already active on the plugins page.');
187+
}
171188
} else {
172-
// Outcome 3: A generic WordPress error occurred.
189+
// Outcome 4: A generic WordPress error occurred.
173190
const errorText = await page.locator(genericErrorSelector).first().textContent();
174191
throw new Error(`Plugin installation failed with a WordPress error: ${errorText.trim()}`);
175192
}
@@ -185,12 +202,12 @@ async function main() {
185202

186203
const tokenElement = page.locator('div#section-description > code');
187204
if (await tokenElement.count() === 0) {
188-
throw new Error('Could not find the connection token element on the page.');
205+
throw new Error('Could not find the connection token element on the page.');
189206
}
190207
const token = await tokenElement.first().textContent();
191208
console.log(' Token found!');
192209
// 5. OUTPUT TOKEN FOR BASH SCRIPT
193-
process.stdout.write(' - Step 5/5: Sending token back to script...');
210+
process.stdout.write(' - Step 5/5: Sending token back to script...');
194211
console.log(token.trim());
195212

196213
} catch (error) {
@@ -211,7 +228,7 @@ EOF
211228
# Enable pipefail to catch errors from the node script before the pipe to tee
212229
set -o pipefail
213230
local full_output
214-
full_output=$(echo "$PLAYWRIGHT_SCRIPT" | node - "$target_url" "$username" "$password" | tee /dev/tty)
231+
full_output=$(echo "$PLAYWRIGHT_SCRIPT" | node - "$target_url" "$username" "$password" "$debug_flag" | tee /dev/tty)
215232
local exit_code=$?
216233

217234
# Disable pipefail after the command to avoid affecting other parts of the script

0 commit comments

Comments
 (0)