164 lines
5.2 KiB
TypeScript
164 lines
5.2 KiB
TypeScript
/**
|
|
* Utility class for common WebDriver operations
|
|
*/
|
|
|
|
import { Builder, By, until, WebDriver } from 'selenium-webdriver';
|
|
import chrome from 'selenium-webdriver/chrome';
|
|
import { writeFileSync, existsSync, appendFileSync } from 'fs';
|
|
import * as path from 'path';
|
|
import { ContactInfo } from './types';
|
|
|
|
export class WebDriverUtils {
|
|
/**
|
|
* Wait for a specified number of seconds
|
|
* @param seconds Number of seconds to wait
|
|
* @returns Promise that resolves after the specified time
|
|
*/
|
|
static async wait(driver?: WebDriver): Promise<void> {
|
|
const seconds = Math.floor(Math.random() * 1000) % 3 + 3;
|
|
console.log(`Scrolling to bottom for ${seconds} seconds...`);
|
|
|
|
const endTime = Date.now() + seconds * 1000;
|
|
|
|
let scrollCounter = 0;
|
|
|
|
while (Date.now() < endTime) {
|
|
|
|
/*
|
|
try {
|
|
if (driver) {
|
|
await driver.executeScript(`
|
|
window.scrollBy(0, 10);
|
|
`);
|
|
|
|
scrollCounter++;
|
|
}
|
|
} catch (error) {
|
|
console.warn('Scroll failed:', error);
|
|
}
|
|
*/
|
|
|
|
// Wait a little between scrolls
|
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Wait for an element to be located on the page
|
|
* @param driver WebDriver instance
|
|
* @param selector CSS selector for the element
|
|
* @param timeoutMs Timeout in milliseconds (default: 10000)
|
|
* @returns Promise that resolves when the element is found
|
|
*/
|
|
static async waitForElement(driver: WebDriver, selector: string, timeoutMs: number = 10000) {
|
|
console.log(`Waiting for element: ${selector}`);
|
|
await driver.wait(until.elementLocated(By.css(selector)), timeoutMs);
|
|
}
|
|
}
|
|
|
|
export function saveContactInfoToCSV(city: string, contactInfo: ContactInfo, filePath: string): void {
|
|
const headers = 'City,Website URL,Email\n';
|
|
const line = `"${city}","${contactInfo.name}","${contactInfo.websiteUrl}","${contactInfo.email}"\n`;
|
|
|
|
if (!existsSync(filePath)) {
|
|
writeFileSync(filePath, headers + line);
|
|
} else {
|
|
appendFileSync(filePath, line);
|
|
}
|
|
|
|
console.log(`Contact info saved to ${filePath}`);
|
|
}
|
|
|
|
export async function disableCookiesInChrome(): Promise<WebDriver | null> {
|
|
// Set Chrome options
|
|
const options = new chrome.Options();
|
|
|
|
// 1. Block all cookies
|
|
//options.setUserPreferences({
|
|
// 'profile.default_content_setting_values.cookies': 2, // 2 = Block all
|
|
// 'profile.block_third_party_cookies': true
|
|
//});
|
|
|
|
// 2. Optional: Launch in incognito for extra privacy
|
|
options.addArguments('--incognito');
|
|
options.addArguments('--start-maximized');
|
|
|
|
let driver: WebDriver | null = null;
|
|
|
|
try {
|
|
driver = await new Builder()
|
|
.forBrowser('chrome')
|
|
.setChromeOptions(options)
|
|
.build();
|
|
|
|
await driver.get('https://www.tripadvisor.com/');
|
|
|
|
console.log('Chrome launched with cookies disabled.');
|
|
|
|
// Optional: Verify cookies are blocked by trying to set/get a cookie
|
|
await driver.manage().addCookie({ name: 'test', value: '123' });
|
|
const cookies = await driver.manage().getCookies();
|
|
console.log('Cookies after trying to add:', cookies); // Should be empty or restricted
|
|
|
|
return driver;
|
|
} catch (error) {
|
|
console.error('Error:', error);
|
|
return driver;
|
|
}
|
|
|
|
}
|
|
|
|
export async function useChrome(initialUrl: string = "https://www.tripadvisor.com/"): Promise<WebDriver | null> {
|
|
// Set Chrome options
|
|
const options = new chrome.Options();
|
|
|
|
// 1. Block all cookies
|
|
//options.setUserPreferences({
|
|
// 'profile.default_content_setting_values.cookies': 2, // 2 = Block all
|
|
// 'profile.block_third_party_cookies': true
|
|
//});
|
|
|
|
// 2. Optional: Launch in incognito for extra privacy
|
|
options.addArguments('--incognito');
|
|
options.addArguments('--start-maximized');
|
|
|
|
let driver: WebDriver | null = null;
|
|
|
|
try {
|
|
driver = await new Builder()
|
|
.forBrowser('chrome')
|
|
.setChromeOptions(options)
|
|
.build();
|
|
|
|
await driver.get(initialUrl);
|
|
|
|
console.log('Chrome launched with cookies disabled.');
|
|
|
|
// Optional: Verify cookies are blocked by trying to set/get a cookie
|
|
await driver.manage().addCookie({ name: 'test', value: '123' });
|
|
const cookies = await driver.manage().getCookies();
|
|
console.log('Cookies after trying to add:', cookies); // Should be empty or restricted
|
|
|
|
return driver;
|
|
} catch (error) {
|
|
console.error('Error:', error);
|
|
return driver;
|
|
}
|
|
|
|
}
|
|
|
|
export async function useExistingChrome(): Promise<WebDriver> {
|
|
// Connect to an existing Chrome browser running in debug mode on port 9222
|
|
const options = new chrome.Options();
|
|
|
|
// Set the debugger address to connect to the existing Chrome instance
|
|
options.debuggerAddress('localhost:9222');
|
|
|
|
// Create WebDriver instance that connects to the existing browser
|
|
const driver: WebDriver = await new Builder()
|
|
.forBrowser('chrome')
|
|
.setChromeOptions(options)
|
|
.build();
|
|
|
|
return driver;
|
|
} |