From d6e45c701e3c1f40e8622c65e540d0b0c1df094e Mon Sep 17 00:00:00 2001 From: adrapier03 Date: Tue, 7 Jul 2026 23:29:38 +0700 Subject: [PATCH] feat: add detailed step-by-step logs for headless execution --- automation.js | 54 +++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/automation.js b/automation.js index 2aba915..e84c469 100644 --- a/automation.js +++ b/automation.js @@ -53,52 +53,54 @@ async function run() { }); try { - // Primary page initialization + console.log('Initializing browser page...'); const page1 = await context.newPage(); + + console.log('Navigating to landing page: https://evolink.ai/ ...'); await page1.goto('https://evolink.ai/'); - // Click on a "Sign Up" + console.log('Clicking "Sign Up" link...'); await page1.getByRole('link', { name: 'Sign Up' }).click(); await page1.waitForTimeout(1000); - // Start waiting for Google Login window/tab to open before clicking + console.log('Setting up tab event listener...'); const page2Promise = context.waitForEvent('page'); - // Click on button "Sign up with Google" + console.log('Clicking "Sign up with Google" button...'); await page1.getByRole('button', { name: 'Sign up with Google' }).click(); - // Wait for the new tab to open + console.log('Waiting for Google Login tab to open...'); const page2 = await page2Promise; - console.log('Google login tab opened. Logging in...'); + console.log('Google login tab opened successfully.'); - // Fill email + console.log('Entering Google email: ' + account.email); await page2.locator('#identifierId').waitFor({ state: 'visible', timeout: 5000 }); await page2.locator('#identifierId').click(); await page2.locator('#identifierId').fill(account.email); - // Click on button "Next" + console.log('Submitting email...'); await page2.getByRole('button', { name: 'Next' }).click(); await page2.waitForTimeout(2000); // Wait for password input to load - // Fill password + console.log('Entering Google password...'); await page2.locator('div#password > div > div > div > input').waitFor({ state: 'visible', timeout: 5000 }); await page2.locator('div#password > div > div > div > input').fill(account.password); - // Click on button "Next" + console.log('Submitting password...'); await page2.getByRole('button', { name: 'Next' }).click(); await page2.waitForTimeout(2000); - // Click on button "I understand" (if Terms speedbump shows up) + console.log('Checking for Terms speedbump ("I understand")...'); try { await page2.getByRole('button', { name: 'I understand' }).waitFor({ state: 'visible', timeout: 3000 }); await page2.getByRole('button', { name: 'I understand' }).click(); await page2.waitForTimeout(1000); console.log('Clicked "I understand" button.'); } catch (e) { - console.log('Speedbump "I understand" not present, skipping...'); + console.log('Speedbump "I understand" not present, skipping.'); } - // Click on button "Continue" (OAuth consent page) + console.log('Checking for Google OAuth Continue/Lanjutkan/Allow button...'); try { const continueBtn = page2.getByRole('button', { name: /^(Sign in|Continue|Allow|Login|Masuk|Lanjutkan|Izinkan)$/i }); await continueBtn.waitFor({ state: 'visible', timeout: 5000 }); @@ -109,44 +111,43 @@ async function run() { console.log('Login/continue button not found or already bypassed.'); } - // Back on page1, wait for login state to reflect + console.log('Waiting for landing page to reflect login status...'); await page1.waitForTimeout(3000); - // Click on profile dropdown button (using the name-independent chevron selector) + console.log('Clicking profile dropdown button...'); const profileBtn = page1.locator(".w-4.h-4.text-gray-400.transition-transform.duration-200").first(); await profileBtn.waitFor({ state: 'visible', timeout: 7000 }); await profileBtn.click(); await page1.waitForTimeout(1000); - // Click on a "Dashboard" + console.log('Clicking "Dashboard" link...'); await page1.getByRole('link', { name: 'Dashboard' }).click(); await page1.waitForTimeout(1000); - // Click on a "API Keys" + console.log('Clicking "API Keys" section...'); await page1.getByRole('link', { name: 'API Keys' }).click(); await page1.waitForTimeout(1000); - // Click on button "Create New Key" + console.log('Clicking "Create New Key" button...'); await page1.getByRole('button', { name: 'Create New Key' }).click(); await page1.waitForTimeout(1000); - // Click on input + console.log('Selecting key name field...'); await page1.getByRole('textbox', { name: 'e.g.: Production Key' }).click(); await page1.waitForTimeout(500); - // Fill value in input + console.log('Entering API key name...'); await page1.getByRole('textbox', { name: 'e.g.: Production Key' }).fill('my api key'); - // Click on button "Create Key" + console.log('Submitting API key form...'); await page1.getByRole('button', { name: 'Create Key' }).click(); await page1.waitForTimeout(2000); - // Click copy/close button on modal - console.log('Clicking copy button...'); + console.log('Clicking copy button on modal...'); await page1.locator('html > body > div:nth-of-type(6) > div > div > div:nth-of-type(2) > div > button').click(); await page1.waitForTimeout(1000); // Wait for clipboard writing to complete - // Extract API key from clipboard and fallback to DOM + console.log('Extracting generated API Key...'); let apiKey = await page1.evaluate(async () => { try { return await navigator.clipboard.readText(); @@ -156,7 +157,7 @@ async function run() { }).catch(() => null); if (!apiKey || apiKey.trim().length === 0) { - // Fallback: search DOM inside the modal container + console.log('Clipboard reading failed. Using DOM extraction fallback...'); apiKey = await page1.evaluate(() => { const modal = document.querySelector('body > div:nth-of-type(6)'); if (!modal) return null; @@ -167,7 +168,6 @@ async function run() { const elements = Array.from(modal.querySelectorAll('span, div, code, p')); for (const el of elements) { const txt = el.innerText ? el.innerText.trim() : ''; - // API Keys are usually longer alphanumeric strings with no spaces if (txt.length > 20 && !txt.includes(' ') && /^[a-zA-Z0-9_\-\.]+$/.test(txt)) { return txt; } @@ -183,7 +183,7 @@ async function run() { console.log('[Warning] Could not extract API Key from clipboard or modal DOM.'); } - // Click on button "Complete" + console.log('Clicking "Complete" button to close modal...'); await page1.getByRole('button', { name: 'Complete' }).click(); await page1.waitForTimeout(1000);