Skip to content

Commit

Permalink
add playwright in github actions (#669)
Browse files Browse the repository at this point in the history
* add playwright in github actions

* Refactor BrowserManager initialization and add URL ellipsis function for verbose logging

* Update @types/node, type-fest, and Playwright dependencies; refine browser installation and types handling in scripts

* Add manual dependency installation instructions and refactor BrowserManager in CLI

* Add playwright smoke tests and remove browse-text from ollama workflow

* update retry order

* more logging in test

* Enhance BrowserManager logging and update browse-text.genai script to convert HTML to text

* Await launching browser explicitly in BrowserManager

* adding concurrency flags
  • Loading branch information
pelikhan authored Aug 28, 2024
1 parent 22e0c56 commit 62fd789
Show file tree
Hide file tree
Showing 26 changed files with 300 additions and 118 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ollama.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ on:
- "packages/cli/**/*"
- "packages/samples/**/*"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
group: ${{ github.workflow }}-${{ github.ref }}-ollama
cancel-in-progress: true
jobs:
tests:
Expand Down
43 changes: 43 additions & 0 deletions .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: playwright smoke tests
on:
workflow_dispatch:
pull_request:
paths:
- yarn.lock
- ".github/workflows/playwright.yml"
- "packages/core/**/*"
- "packages/cli/**/*"
push:
branches:
- main
paths:
- yarn.lock
- ".github/workflows/playwright.yml"
- "packages/core/**/*"
- "packages/cli/**/*"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-playwright
cancel-in-progress: true
jobs:
tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: "recursive"
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: yarn
- run: yarn install --frozen-lockfile
- name: typecheck
run: yarn typecheck
- name: compile
run: yarn compile
- name: run browse-text
run: yarn run:script browse-text --out ./temp/browse-text
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
OPENAI_API_TYPE: ${{ secrets.OPENAI_API_TYPE }}
OPENAI_API_BASE: ${{ secrets.OPENAI_API_BASE }}
4 changes: 2 additions & 2 deletions THIRD_PARTY_LICENSES.md
Original file line number Diff line number Diff line change
Expand Up @@ -1458,7 +1458,7 @@ The following npm packages may be included in this product:
- @types/http-cache-semantics@4.0.4
- @types/jsonfile@6.1.4
- @types/mute-stream@0.0.4
- @types/node@22.5.0
- @types/node@22.5.1
- @types/turndown@5.0.5
- @types/yauzl@2.10.3

Expand Down Expand Up @@ -1551,7 +1551,7 @@ MIT License
The following npm packages may be included in this product:

- [email protected]
- type-fest@4.25.0
- type-fest@4.26.0

These packages each contain the following license and notice below:

Expand Down
10 changes: 9 additions & 1 deletion docs/genaisrc/genaiscript.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 16 additions & 2 deletions docs/src/content/docs/reference/scripts/browse.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,24 @@ $`Analyze DATA.`

## Installation

You will need to install Playright locally before using the `browse` function.
Playwright needs to [install the browsers and dependencies](https://playwright.dev/docs/browsers#install-system-dependencies) before execution. GenAIScript will automatically try to install them if it fails to load the browser;
but you can also do it manually using the following command:

```bash
npx playwright install-deps chromium
npx playwright install --with-deps chromium
```

If you see this error message, you might have to install the dependencies manually.

```text
╔═════════════════════════════════════════════════════════════════════════╗
║ Looks like Playwright Test or Playwright was just installed or updated. ║
║ Please run the following command to download new browsers: ║
║ ║
║ yarn playwright install ║
║ ║
║ <3 Playwright Team ║
╚═════════════════════════════════════════════════════════════════════════╝
```

## `host.browse`
Expand Down
60 changes: 30 additions & 30 deletions docs/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -81,24 +81,24 @@
vfile "^6.0.2"

"@astrojs/mdx@^3.1.3":
version "3.1.4"
resolved "https://registry.yarnpkg.com/@astrojs/mdx/-/mdx-3.1.4.tgz#1340e1f01b8bdcbe9077ed7c148513c1bc875523"
integrity sha512-AcdcAlDpzTM5LHpur7A3NWoIqyfhH1gZNbTvvjiUlDEo7eJjIxl4gdWrb/kZZRfLBEuM8cptCB+Qk11ncQL4IA==
version "3.1.5"
resolved "https://registry.yarnpkg.com/@astrojs/mdx/-/mdx-3.1.5.tgz#2968535b9ab8ec857ee5a6ae539bc1d60270aae7"
integrity sha512-Fu6oShqcDpi0D1b2/3Pg3ao1I+Q2YqKhFsSsuDzn0YhdGrry5oUyABUyCyGq/OayP2P/34Vwj+GCQ/n9h8FlTQ==
dependencies:
"@astrojs/markdown-remark" "5.2.0"
"@mdx-js/mdx" "^3.0.1"
acorn "^8.12.1"
es-module-lexer "^1.5.4"
estree-util-visit "^2.0.0"
gray-matter "^4.0.3"
hast-util-to-html "^9.0.1"
hast-util-to-html "^9.0.2"
kleur "^4.1.5"
rehype-raw "^7.0.0"
remark-gfm "^4.0.0"
remark-smartypants "^3.0.2"
source-map "^0.7.4"
unist-util-visit "^5.0.0"
vfile "^6.0.2"
vfile "^6.0.3"

"@astrojs/[email protected]":
version "3.1.0"
Expand Down Expand Up @@ -205,7 +205,7 @@
json5 "^2.2.3"
semver "^6.3.1"

"@babel/generator@^7.25.0", "@babel/generator@^7.25.4":
"@babel/generator@^7.25.0", "@babel/generator@^7.25.4", "@babel/generator@^7.25.5":
version "7.25.5"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.25.5.tgz#b31cf05b3fe8c32d206b6dad03bb0aacbde73450"
integrity sha512-abd43wyLfbWoxC6ahM8xTkqLpGB2iWBVyuKC9/srhFunCd1SDNrV1s72bBpK4hLj8KLzHBBcOblvLQZBNw9r3w==
Expand Down Expand Up @@ -297,7 +297,7 @@
js-tokens "^4.0.0"
picocolors "^1.0.0"

"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.25.0", "@babel/parser@^7.25.3", "@babel/parser@^7.25.4":
"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.25.0", "@babel/parser@^7.25.4":
version "7.25.4"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.4.tgz#af4f2df7d02440286b7de57b1c21acfb2a6f257a"
integrity sha512-nq+eWrOgdtu3jG5Os4TQP3x3cLA8hR8TvJNjD8vnPa20WGycimcparWnLK4jJhElTK6SDyuJo1weMKO/5LpmLA==
Expand Down Expand Up @@ -331,7 +331,7 @@
"@babel/parser" "^7.25.0"
"@babel/types" "^7.25.0"

"@babel/traverse@^7.24.7", "@babel/traverse@^7.25.2", "@babel/traverse@^7.25.3":
"@babel/traverse@^7.24.7", "@babel/traverse@^7.25.2", "@babel/traverse@^7.25.4":
version "7.25.4"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.4.tgz#648678046990f2957407e3086e97044f13c3e18e"
integrity sha512-VJ4XsrD+nOvlXyLzmLzUs/0qjFS4sK30te5yEFlvbbUNEgKaVb2BHZUpAL+ttLPQAHNrsI3zZisbfha5Cvr8vg==
Expand Down Expand Up @@ -998,9 +998,9 @@
"@types/unist" "*"

"@types/node@*", "@types/node@>=20":
version "22.5.0"
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.5.0.tgz#10f01fe9465166b4cab72e75f60d8b99d019f958"
integrity sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg==
version "22.5.1"
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.5.1.tgz#de01dce265f6b99ed32b295962045d10b5b99560"
integrity sha512-KkHsxej0j9IW1KKOOAA/XBA0z08UFSrRQHErzEfA3Vgq57eXIMYboIlHJuYIfd+lwCQjtKqUu3UnmKbtUc9yRw==
dependencies:
undici-types "~6.19.2"

Expand Down Expand Up @@ -1221,20 +1221,20 @@ [email protected]:
ultrahtml "^1.5.3"

astro@^4.14.5:
version "4.14.5"
resolved "https://registry.yarnpkg.com/astro/-/astro-4.14.5.tgz#d0e6302fdae72d31be6a916b8b30eb9bb2092b2a"
integrity sha512-sv47kPE6FnvyxxHHcCePNwTKpOMKBq0r1m6WZYg6ag9j3yF9m72ov64NFB7c+hAMDUKgsHfVdLKjOOqDC/c+fA==
version "4.14.6"
resolved "https://registry.yarnpkg.com/astro/-/astro-4.14.6.tgz#ff2feda4864ab103dcd5dc0b53f8104f4d4deb45"
integrity sha512-MIDyNhtu3L4uakHvlTprh21eQPehYOtZSuSLtd+r6xZcl3lB+mlBz/hs1W3iHEQAORyJnKArWSY/aVOBKUyflA==
dependencies:
"@astrojs/compiler" "^2.10.3"
"@astrojs/internal-helpers" "0.4.1"
"@astrojs/markdown-remark" "5.2.0"
"@astrojs/telemetry" "3.1.0"
"@babel/core" "^7.25.2"
"@babel/generator" "^7.25.0"
"@babel/parser" "^7.25.3"
"@babel/generator" "^7.25.5"
"@babel/parser" "^7.25.4"
"@babel/plugin-transform-react-jsx" "^7.25.2"
"@babel/traverse" "^7.25.3"
"@babel/types" "^7.25.2"
"@babel/traverse" "^7.25.4"
"@babel/types" "^7.25.4"
"@oslojs/encoding" "^0.4.1"
"@rollup/pluginutils" "^5.1.0"
"@types/babel__core" "^7.20.5"
Expand Down Expand Up @@ -1267,10 +1267,10 @@ astro@^4.14.5:
js-yaml "^4.1.0"
kleur "^4.1.5"
magic-string "^0.30.11"
micromatch "^4.0.7"
micromatch "^4.0.8"
mrmime "^2.0.0"
neotraverse "^0.6.18"
ora "^8.0.1"
ora "^8.1.0"
p-limit "^6.1.0"
p-queue "^8.0.1"
path-to-regexp "^6.2.2"
Expand All @@ -1283,8 +1283,8 @@ astro@^4.14.5:
strip-ansi "^7.1.0"
tsconfck "^3.1.1"
unist-util-visit "^5.0.0"
vfile "^6.0.2"
vite "^5.4.1"
vfile "^6.0.3"
vite "^5.4.2"
vitefu "^0.2.5"
which-pm "^3.0.0"
xxhash-wasm "^1.0.2"
Expand Down Expand Up @@ -2063,7 +2063,7 @@ hast-util-to-estree@^3.0.0:
unist-util-position "^5.0.0"
zwitch "^2.0.0"

hast-util-to-html@^9.0.0, hast-util-to-html@^9.0.1:
hast-util-to-html@^9.0.0, hast-util-to-html@^9.0.1, hast-util-to-html@^9.0.2:
version "9.0.2"
resolved "https://registry.yarnpkg.com/hast-util-to-html/-/hast-util-to-html-9.0.2.tgz#314d8c125c36cf736e4389850b4f73871965d0c3"
integrity sha512-RP5wNpj5nm1Z8cloDv4Sl4RS8jH5HYa0v93YB6Wb4poEzgMo/dAAL0KcT4974dCjcNG5pkLqTImeFHHCwwfY3g==
Expand Down Expand Up @@ -3062,7 +3062,7 @@ micromark@^4.0.0:
micromark-util-symbol "^2.0.0"
micromark-util-types "^2.0.0"

micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.7:
micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202"
integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==
Expand Down Expand Up @@ -3155,7 +3155,7 @@ onetime@^7.0.0:
dependencies:
mimic-function "^5.0.0"

ora@^8.0.1:
ora@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/ora/-/ora-8.1.0.tgz#c3db2f9f83a2bec9e8ab71fe3b9ae234d65ca3a8"
integrity sha512-GQEkNkH/GHOhPFXcqZs3IDahXEQcQxsSjEkK4KvEEST4t7eNzoMjxTzef+EZ+JluDEV+Raoi3WQ2CflnRdSVnQ==
Expand Down Expand Up @@ -3841,9 +3841,9 @@ style-to-object@^0.4.0:
inline-style-parser "0.1.1"

style-to-object@^1.0.0:
version "1.0.6"
resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-1.0.6.tgz#0c28aed8be1813d166c60d962719b2907c26547b"
integrity sha512-khxq+Qm3xEyZfKd/y9L3oIWQimxuc4STrQKtQn8aSDRHb8mFgpukgX1hdzfrMEW6JCjyJ8p89x+IUMVnCBI1PA==
version "1.0.7"
resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-1.0.7.tgz#8604fb6018ac3db83e97207a4f85f579068f661c"
integrity sha512-uSjr59G5u6fbxUfKbb8GcqMGT3Xs9v5IbPkjb0S16GyOeBLAzSRK0CixBv5YrYvzO6TDLzIS6QCn78tkqWngPw==
dependencies:
inline-style-parser "0.2.3"

Expand Down Expand Up @@ -4036,15 +4036,15 @@ vfile-message@^4.0.0:
"@types/unist" "^3.0.0"
unist-util-stringify-position "^4.0.0"

vfile@^6.0.0, vfile@^6.0.2:
vfile@^6.0.0, vfile@^6.0.2, vfile@^6.0.3:
version "6.0.3"
resolved "https://registry.yarnpkg.com/vfile/-/vfile-6.0.3.tgz#3652ab1c496531852bf55a6bac57af981ebc38ab"
integrity sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==
dependencies:
"@types/unist" "^3.0.0"
vfile-message "^4.0.0"

vite@^5.4.1:
vite@^5.4.2:
version "5.4.2"
resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.2.tgz#8acb6ec4bfab823cdfc1cb2d6c53ed311bc4e47e"
integrity sha512-dDrQTRHp5C1fTFzcSaMxjk6vdpKvT+2/mIdE07Gw2ykehT49O0z/VHS3zZ8iV/Gh8BJJKHWOe5RjaNrW5xf/GA==
Expand Down
10 changes: 9 additions & 1 deletion genaisrc/genaiscript.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

51 changes: 38 additions & 13 deletions packages/cli/src/playwright.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,55 @@
import type { Browser, BrowserContext, Page } from "playwright"
import type { Browser, Page } from "playwright"
import { TraceOptions } from "../../core/src/trace"
import { logError, logVerbose } from "../../core/src/util"

type PlaywrightModule = typeof import("playwright")
import { runtimeHost } from "../../core/src/host"
import { PLAYWRIGHT_VERSION } from "./version"
import { ellipseUri } from "../../core/src/url"
import { PLAYWRIGHT_DEFAULT_BROWSER } from "../../core/src/constants"
import { log } from "node:console"

export class BrowserManager {
private _playwright: PlaywrightModule
private _browsers: Browser[] = []
private _pages: Page[] = []

constructor() {}

private async init() {
if (this._playwright) return
const p = await import("playwright")
if (!p) throw new Error("playwright installation not completed")
this._playwright = p
return p
}

private async launchBrowser(options?: {}) {
await this.init()
const browser = await this._playwright.chromium.launch()
return browser
private async installDependencies(vendor: string) {
const res = await runtimeHost.exec(
undefined,
"npx",
[
`playwright@${PLAYWRIGHT_VERSION}`,
"install",
"--with-deps",
vendor,
],
{
label: `installing playwright ${vendor}`,
}
)
if (res.exitCode) throw new Error("playwright installation failed")
}

async stopAndRemove() {
if (!this._playwright) return
private async launchBrowser(options?: BrowserOptions): Promise<Browser> {
const { browser = PLAYWRIGHT_DEFAULT_BROWSER, ...rest } = options || {}
try {
const playwright = await this.init()
return await playwright[browser].launch(rest)
} catch {
logVerbose("trying to install playwright...")
await this.installDependencies(browser)
const playwright = await this.init()
return await playwright[browser].launch(rest)
}
}

async stopAndRemove() {
const browsers = this._browsers.slice(0)
const pages = this._pages.slice(0)

Expand Down Expand Up @@ -61,8 +84,9 @@ export class BrowserManager {
): Promise<BrowserPage> {
const { trace, incognito, ...rest } = options || {}

logVerbose(`browsing`)
logVerbose(`browsing ${ellipseUri(url)}`)
const browser = await this.launchBrowser(options)
logVerbose(`navigating...`)
let page: BrowserPage
if (incognito) {
const context = await browser.newContext(rest)
Expand All @@ -71,6 +95,7 @@ export class BrowserManager {
page = await browser.newPage(rest)
}
if (url) await page.goto(url)
logVerbose(`page ready`)
return page
}
}
Loading

0 comments on commit 62fd789

Please sign in to comment.