@auto-browse/auto-browse
Version:
AI-powered browser automation
130 lines (129 loc) • 4.57 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.context = exports.Context = void 0;
const test_1 = require("@playwright/test");
const session_manager_1 = require("./session-manager");
class Context {
constructor() {
this._lastSnapshotFrames = [];
this._listenerInitialized = false;
}
initializeListener() {
if (!this._listenerInitialized) {
const page = session_manager_1.sessionManager.getPage();
page.on("filechooser", (chooser) => (this._fileChooser = chooser));
this._listenerInitialized = true;
}
}
static getInstance() {
if (!Context.instance) {
Context.instance = new Context();
}
return Context.instance;
}
async allFramesSnapshot() {
const page = session_manager_1.sessionManager.getPage();
const visibleFrames = await page
.locator("iframe")
.filter({ visible: true })
.all();
this._lastSnapshotFrames = visibleFrames.map((frame) => frame.contentFrame());
const snapshots = await Promise.all([
page.locator("html").ariaSnapshot({ ref: true }),
...this._lastSnapshotFrames.map(async (frame, index) => {
const snapshot = await frame.locator("html").ariaSnapshot({
ref: true,
});
const args = [];
const src = await frame.owner().getAttribute("src");
if (src)
args.push(`src=${src}`);
const name = await frame.owner().getAttribute("name");
if (name)
args.push(`name=${name}`);
return (`\n# iframe ${args.join(" ")}\n` +
snapshot.replaceAll("[ref=", `[ref=f${index}`));
}),
]);
return snapshots.join("\n");
}
refLocator(ref) {
const page = session_manager_1.sessionManager.getPage();
let frame = page.mainFrame();
const match = ref.match(/^f(\d+)(.*)/);
if (match) {
const frameIndex = parseInt(match[1], 10);
if (!this._lastSnapshotFrames[frameIndex])
throw new Error(`Frame does not exist. Provide ref from the most current snapshot.`);
frame = this._lastSnapshotFrames[frameIndex];
ref = match[2];
}
return frame.locator(`aria-ref=${ref}`);
}
async createPage() {
if (this._page) {
return this._page;
}
const { browser, page } = await this._createPage();
this._browser = browser;
this._page = page;
session_manager_1.sessionManager.setPage(page);
// Initialize listeners
page.on("filechooser", (chooser) => (this._fileChooser = chooser));
page.on("close", () => this._onPageClose());
this._listenerInitialized = true;
return page;
}
async _createPage() {
const browser = await test_1.chromium.launch({
channel: "chrome",
headless: false,
});
const context = await browser.newContext({});
const page = await context.newPage();
return { browser, page };
}
_onPageClose() {
const browser = this._browser;
const page = this._page;
void page
?.context()
?.close()
.then(() => browser?.close())
.catch(() => { });
this._browser = undefined;
this._page = undefined;
this._fileChooser = undefined;
this._lastSnapshotFrames = [];
this._listenerInitialized = false;
}
existingPage() {
// Try standalone page first, fall back to session manager
return this._page || session_manager_1.sessionManager.getPage();
}
async close() {
if (this._page) {
await this._page.close();
return;
}
const page = session_manager_1.sessionManager.getPage();
await page.close();
}
async submitFileChooser(paths) {
this.initializeListener();
if (!this._fileChooser) {
throw new Error("No file chooser visible");
}
await this._fileChooser.setFiles(paths);
this._fileChooser = undefined;
}
hasFileChooser() {
this.initializeListener();
return !!this._fileChooser;
}
clearFileChooser() {
this._fileChooser = undefined;
}
}
exports.Context = Context;
exports.context = Context.getInstance();