import type { ElementHandle, PuppeteerLifeCycleEvent } from "puppeteer"; import type { IDriverAction } from "./base-action"; import type { DebugOpts } from "../../../types"; import { ElementAction } from "./element-action"; import { gotoUrl } from "./definitions/goto-url"; export interface IGotoUrlAction extends IDriverAction {} export type GotoUrlOpts = DebugOpts & {}; export class GotoUrlAction extends ElementAction implements IGotoUrlAction { waitUntil: PuppeteerLifeCycleEvent = "load"; interactiveElements?: ElementHandle[]; name = "goto_url"; definition = gotoUrl; onStart(url: string) { this.logTask(`Going to ${url}`); } async execute() { const url = this.fnArgs.url; if (!url) { throw new Error("Missing url to go to"); } this.onStart(url); if (!this.page) { throw new Error("Missing page"); } try { await this.gotoUrl(url); const pageUrl = await this.getUrl(); this.setMessage(`You are now on ${pageUrl}`); } catch (error) { const errMessage = this.downloadError(error) || this.defaultGotoErrorMessage; this.setMessage(errMessage); } this.onStartScraping(); this.interactiveElements = await this.getTabbableElements(); } async gotoUrl(url: string) { const { waitUntil } = this; await this.page?.goto(url, { waitUntil, }); } async getUrl() { return await this.page?.url(); } onStartScraping() { this.logTask("Scraping page..."); } get defaultGotoErrorMessage() { return "There was an error going to the URL"; } protected async getTabbableElements() { if (!this.page) { throw new Error("Missing page"); } return await this.elementSelector?.getElements(this.page); } downloadError(error: unknown): string | undefined { if ( error instanceof Error && error.message.startsWith("net::ERR_ABORTED") ) { return "NOTICE: The connection was aborted. If you clicked on a download link, the file has been downloaded to the default Chrome downloads location."; } this.log(error); return; } }