This release is 1 version behind 0.4.8 — the latest version of @astral/astral. Jump to latest
Built and signed on GitHub ActionsBuilt and signed on GitHub Actions
Built and signed on GitHub Actions
Astral is the browser automation library for Deno
This package works with Deno
JSR Score
100%
Published
a month ago (0.4.7)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177# Astral <img src="./docs/static/icon.png" height="200" width="200" align="right"/> Astral is a high-level puppeteer/playwright-like library that allows for control over a web browser (primarily for automation and testing). It is written from scratch with Deno in mind. ## Usage Take a screenshot of a website. ```ts // Import Astral import { launch } from "jsr:@astral/astral"; // Launch the browser const browser = await launch(); // Open a new page const page = await browser.newPage("https://deno.land"); // Take a screenshot of the page and save that to disk const screenshot = await page.screenshot(); Deno.writeFileSync("screenshot.png", screenshot); // Close the browser await browser.close(); ``` You can use the evaluate function to run code in the context of the browser. ```ts // Import Astral import { launch } from "jsr:@astral/astral"; // Launch the browser const browser = await launch(); // Open a new page const page = await browser.newPage("https://deno.land"); // Run code in the context of the browser const value = await page.evaluate(() => { return document.body.innerHTML; }); console.log(value); // Run code with args const result = await page.evaluate((x, y) => { return `The result of adding ${x}+${y} = ${x + y}`; }, { args: [10, 15], }); console.log(result); // Close the browser await browser.close(); ``` You can navigate to a page and interact with it. ```ts // Import Astral import { launch } from "jsr:@astral/astral"; // Launch browser in headfull mode const browser = await launch({ headless: false }); // Open the webpage const page = await browser.newPage("https://deno.land"); // Click the search button const button = await page.$("button"); await button!.click(); // Type in the search input const input = await page.$("#search-input"); await input!.type("pyro", { delay: 1000 }); // Wait for the search results to come back await page.waitForNetworkIdle({ idleConnections: 0, idleTime: 1000 }); // Click the 'pyro' link const xLink = await page.$("a.justify-between:nth-child(1)"); await Promise.all([ page.waitForNavigation(), xLink!.click(), ]); // Click the link to 'pyro.deno.dev' const dLink = await page.$( ".markdown-body > p:nth-child(8) > a:nth-child(1)", ); await Promise.all([ page.waitForNavigation(), dLink!.click(), ]); // Close browser await browser.close(); ``` TODO: Document the locator API. ## Advanced Usage If you already have a browser process running somewhere else or you're using a service that provides remote browsers for automation (such as [browserless.io](https://www.browserless.io/)), it is possible to directly connect to its endpoint rather than spawning a new process. ```ts // Import Astral import { launch } from "jsr:@astral/astral"; // Connect to remote endpoint const browser = await launch({ wsEndpoint: "wss://remote-browser-endpoint.example.com", }); // Do stuff const page = await browser.newPage("http://example.com"); console.log(await page.evaluate(() => document.title)); // Close connection await browser.close(); ``` If you'd like to instead re-use a browser that you already launched, astral exposes the WebSocket endpoint through `browser.wsEndpoint()`. ```ts // Spawn a browser process const browser = await launch(); // Connect to first browser instead const anotherBrowser = await launch({ wsEndpoint: browser.wsEndpoint() }); ``` ## BYOB - Bring Your Own Browser Essentially the process is as simple as running a chromium-like binary with the following flags: ``` chromium --remote-debugging-port=1337 \ --headless=new \ --no-first-run \ --password-store=basic \ --use-mock-keychain \ --hide-scrollbars ``` Technically, only the first flag is necessary, though I've found that these flags generally get the best result. Once your browser process is running, connecting to it is as simple as ```typescript // Import Astral import { launch } from "jsr:@astral/astral"; // Connect to remote endpoint const browser = await launch({ wsEndpoint: "<WS-ENDPOINT>", headless: false, }); console.log(browser.wsEndpoint()); // Do stuff const page = await browser.newPage("http://example.com"); console.log(await page.evaluate(() => document.title)); // Close connection await browser.close(); ```