linkedout/core-parser/navigation.js
tanyar09 8de65bc04c Add initial project structure for Job Market Intelligence platform
- Created core modules: `ai-analyzer`, `core-parser`, and `job-search-parser`.
- Implemented LinkedIn and job search parsers with integrated AI analysis.
- Added CLI tools for AI analysis and job parsing.
- Included comprehensive README files for each module detailing usage and features.
- Established a `.gitignore` file to exclude unnecessary files.
- Introduced sample data for testing and demonstration purposes.
- Set up package.json files for dependency management across modules.
- Implemented logging and error handling utilities for better debugging and user feedback.
2025-12-12 14:23:01 -05:00

132 lines
3.2 KiB
JavaScript

/**
* Navigation Manager
*
* Handles page navigation with error handling, retries, and logging
*/
class NavigationManager {
constructor(coreParser) {
this.coreParser = coreParser;
}
/**
* Navigate to URL with comprehensive error handling
*/
async navigateTo(url, options = {}) {
const {
pageId = "default",
waitUntil = "domcontentloaded",
retries = 1,
retryDelay = 2000,
timeout = this.coreParser.config.timeout,
} = options;
const page = this.coreParser.getPage(pageId);
if (!page) {
throw new Error(`Page with ID '${pageId}' not found`);
}
let lastError;
for (let attempt = 0; attempt <= retries; attempt++) {
try {
console.log(
`🌐 Navigating to: ${url} (attempt ${attempt + 1}/${retries + 1})`
);
await page.goto(url, {
waitUntil,
timeout,
});
console.log(`✅ Navigation successful: ${url}`);
return true;
} catch (error) {
lastError = error;
console.warn(
`⚠️ Navigation attempt ${attempt + 1} failed: ${error.message}`
);
if (attempt < retries) {
console.log(`🔄 Retrying in ${retryDelay}ms...`);
await this.delay(retryDelay);
}
}
}
// All attempts failed
const errorMessage = `Navigation failed after ${retries + 1} attempts: ${
lastError.message
}`;
console.error(`${errorMessage}`);
throw new Error(errorMessage);
}
/**
* Navigate and wait for specific selector
*/
async navigateAndWaitFor(url, selector, options = {}) {
await this.navigateTo(url, options);
const { pageId = "default", timeout = this.coreParser.config.timeout } =
options;
const page = this.coreParser.getPage(pageId);
try {
await page.waitForSelector(selector, { timeout });
console.log(`✅ Selector found: ${selector}`);
return true;
} catch (error) {
console.warn(`⚠️ Selector not found: ${selector} - ${error.message}`);
return false;
}
}
/**
* Check if current page has specific content
*/
async hasContent(content, options = {}) {
const { pageId = "default", timeout = 5000 } = options;
const page = this.coreParser.getPage(pageId);
try {
await page.waitForFunction(
(text) => document.body.innerText.includes(text),
content,
{ timeout }
);
return true;
} catch {
return false;
}
}
/**
* Utility delay function
*/
async delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
/**
* Get current page URL
*/
getCurrentUrl(pageId = "default") {
const page = this.coreParser.getPage(pageId);
return page ? page.url() : null;
}
/**
* Take screenshot for debugging
*/
async screenshot(filepath, pageId = "default") {
const page = this.coreParser.getPage(pageId);
if (page) {
await page.screenshot({ path: filepath });
console.log(`📸 Screenshot saved: ${filepath}`);
}
}
}
module.exports = NavigationManager;