Skip to content

Commit e987ff0

Browse files
authored
try base64 cdp screenshots directly (browser-use#2362)
2 parents a2fc886 + 8d662c5 commit e987ff0

3 files changed

Lines changed: 84 additions & 41 deletions

File tree

.github/workflows/eval.yaml

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -80,23 +80,31 @@ jobs:
8080
id: playwright_version
8181
run: echo "VERSION=$(uv pip list --format json | jq -r '.[] | select(.name == "playwright") | .version')" >> $GITHUB_OUTPUT
8282

83-
- name: Cache Playwright browsers
84-
uses: actions/cache@v4
83+
- name: Cache chrome binaries
84+
uses: actions/cache@v3
8585
with:
86-
path: ~/.cache/ms-playwright
87-
key: ${{ runner.os }}-playwright-${{ steps.playwright_version.outputs.VERSION }}
88-
restore-keys: |
89-
${{ runner.os }}-playwright-
86+
path: |
87+
/tmp/google-chrome-stable_current_amd64.deb
88+
key: ${{ runner.os }}-${{ runner.arch }}-chrome-stable
9089

91-
- name: Install Playwright browser dependencies
90+
- name: Install Chrome stable binary
9291
run: |
93-
echo "Installing Playwright browsers..."
94-
# comment out some based on whether stealth=True is used for evals or not
95-
playwright install --no-shell chromium --with-deps
96-
patchright install --no-shell chromium --with-deps
97-
playwright install --no-shell chrome --with-deps
98-
patchright install --no-shell chrome --with-deps
99-
echo "Playwright browsers installed successfully"
92+
sudo apt-get update -qq \
93+
&& sudo curl -o "/tmp/google-chrome-stable_current_amd64.deb" --no-clobber "https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb" \
94+
&& sudo apt-get install -y "/tmp/google-chrome-stable_current_amd64.deb" -f
95+
- run: patchright install chrome --with-deps
96+
# - run: playwright install chrome --with-deps
97+
# could use $(uname -m) instead of hardcoding amd64
98+
99+
- name: Cache chromium binaries
100+
uses: actions/cache@v3
101+
with:
102+
path: |
103+
~/.cache/ms-playwright
104+
key: ${{ runner.os }}-${{ runner.arch }}-playwright-${{ env.PLAYWRIGHT_VERSION }}-chromium
105+
106+
- run: playwright install chromium --with-deps
107+
# - run: patchright install chromium --with-deps
100108

101109
- name: Install Xvfb for headed mode
102110
if: github.event.client_payload.script_args.headless == 'false'

.github/workflows/test.yaml

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -79,17 +79,30 @@ jobs:
7979
- name: Detect installed Playwright version
8080
run: echo "PLAYWRIGHT_VERSION=$(uv pip list --format json | jq -r '.[] | select(.name == "playwright") | .version')" >> $GITHUB_ENV
8181

82-
- name: Cache playwright binaries
82+
- name: Cache chrome binaries
83+
uses: actions/cache@v3
84+
with:
85+
path: |
86+
/tmp/google-chrome-stable_current_amd64.deb
87+
key: ${{ runner.os }}-${{ runner.arch }}-chrome-stable
88+
89+
- name: Install Chrome stable binary
90+
run: |
91+
sudo apt-get update -qq \
92+
&& sudo curl -o "/tmp/google-chrome-stable_current_amd64.deb" --no-clobber "https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb" \
93+
&& sudo apt-get install -y "/tmp/google-chrome-stable_current_amd64.deb" -f
94+
- run: patchright install chrome --with-deps
95+
# - run: playwright install chrome --with-deps
96+
97+
- name: Cache chromium binaries
8398
uses: actions/cache@v3
8499
with:
85100
path: |
86101
~/.cache/ms-playwright
87-
key: ${{ runner.os }}-playwright-${{ env.PLAYWRIGHT_VERSION }}-chromium
102+
key: ${{ runner.os }}-${{ runner.arch }}-playwright-${{ env.PLAYWRIGHT_VERSION }}-chromium
88103

89104
- run: playwright install chromium --with-deps
90-
- run: playwright install chrome --with-deps
91-
- run: patchright install chrome --with-deps
92-
- run: patchright install chromium --with-deps
105+
# - run: patchright install chromium --with-deps
93106

94107
- run: pytest tests/ci/${{ matrix.test_filename }}.py
95108

@@ -116,17 +129,30 @@ jobs:
116129
- name: Detect installed Playwright version
117130
run: echo "PLAYWRIGHT_VERSION=$(uv pip list --format json | jq -r '.[] | select(.name == "playwright") | .version')" >> $GITHUB_ENV
118131

119-
- name: Cache playwright binaries
132+
- name: Cache chrome binaries
133+
uses: actions/cache@v3
134+
with:
135+
path: |
136+
/tmp/google-chrome-stable_current_amd64.deb
137+
key: ${{ runner.os }}-${{ runner.arch }}-chrome-stable
138+
139+
- name: Install Chrome stable binary
140+
run: |
141+
sudo apt-get update -qq \
142+
&& sudo curl -o "/tmp/google-chrome-stable_current_amd64.deb" --no-clobber "https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb" \
143+
&& sudo apt-get install -y "/tmp/google-chrome-stable_current_amd64.deb" -f
144+
- run: patchright install chrome --with-deps
145+
# - run: playwright install chrome --with-deps
146+
147+
- name: Cache chromium binaries
120148
uses: actions/cache@v3
121149
with:
122150
path: |
123151
~/.cache/ms-playwright
124-
key: ${{ runner.os }}-playwright-${{ env.PLAYWRIGHT_VERSION }}-chromium
152+
key: ${{ runner.os }}-${{ runner.arch }}-playwright-${{ env.PLAYWRIGHT_VERSION }}-chromium
125153

126154
- run: playwright install chromium --with-deps
127-
- run: playwright install chrome --with-deps
128-
- run: patchright install chrome --with-deps
129-
- run: patchright install chromium --with-deps
155+
# - run: patchright install chromium --with-deps
130156

131157
- name: Run agent tasks evaluation and capture score
132158
id: eval

browser_use/browser/session.py

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import asyncio
44
import atexit
5-
import base64
65
import json
76
import logging
87
import os
@@ -741,26 +740,43 @@ async def _take_screenshot_hybrid(self, clip: dict[str, int] | None = None) -> s
741740
except Exception:
742741
pass
743742

743+
screenshot_b64 = None
744+
cdp_session = None
744745
try:
745746
# Use a shorter timeout for screenshots to prevent semaphore starvation
746747
# 10 seconds should be enough for most screenshots
747-
screenshot_timeout = min(10000, self.browser_profile.default_timeout or 10000)
748-
screenshot = await page.screenshot(
749-
full_page=False,
750-
# scale='css',
751-
timeout=screenshot_timeout,
752-
# clip=FloatRect(**clip) if clip else None,
753-
animations='allow',
754-
caret='initial',
748+
# screenshot = await page.screenshot(
749+
# full_page=False,
750+
# # scale='css',
751+
# timeout=screenshot_timeout,
752+
# # clip=FloatRect(**clip) if clip else None,
753+
# animations='allow',
754+
# caret='initial',
755+
#
756+
cdp_session = await page.context.new_cdp_session(page) # type: ignore
757+
screenshot = await cdp_session.send(
758+
'Page.captureScreenshot',
759+
{
760+
'captureBeyondViewport': False,
761+
'fromSurface': True,
762+
'format': 'png',
763+
# 'clip': clip,
764+
},
755765
)
766+
screenshot_b64 = screenshot['data']
756767
except Exception as err:
757768
# Don't reset browser on timeout - this can cause semaphore deadlocks
758769
# Just re-raise the error and let the retry decorator handle it
759770
if 'timeout' in str(err).lower():
760771
self.logger.warning(f'⏱️ Screenshot timed out on page {page.url}: {err}')
761772
raise err
773+
finally:
774+
try:
775+
assert cdp_session
776+
await cdp_session.detach()
777+
except Exception:
778+
pass
762779
assert await page.evaluate('() => true'), 'Page is not usable after screenshot!'
763-
screenshot_b64 = base64.b64encode(screenshot).decode('utf-8')
764780
assert screenshot_b64, 'Playwright page.screenshot() returned empty base64'
765781
return screenshot_b64
766782

@@ -2725,13 +2741,6 @@ async def navigate_to(self, url: str):
27252741
raise BrowserError(f'Navigation to non-allowed URL: {normalized_url}')
27262742

27272743
page = await self.get_current_page()
2728-
try:
2729-
await asyncio.wait_for(page.evaluate('1'), timeout=1)
2730-
except Exception as e:
2731-
# new tab to recover
2732-
self.logger.warning(f'🚨 Page {_log_pretty_url(normalized_url)} is unresponsive, creating new tab...')
2733-
page = await self.create_new_tab(normalized_url)
2734-
return
27352744

27362745
try:
27372746
await asyncio.wait_for(page.goto(normalized_url), timeout=0.1)

0 commit comments

Comments
 (0)