How to Download a File with Vibium
Trigger and save a browser download with Vibium in Python — use capture.download() to grab the file, read its name, and save it with save_as().
To download a file with Vibium, wrap the click that starts it in vibe.capture.download(), then call save_as() on the result to write it to disk. capture.download() sets up the listener, runs your action, and hands back the finished download — name, source URL, and temp path included.
What is the download script?
from vibium import browser
bro = browser.launch()
vibe = bro.page()
vibe.go("http://localhost:3000")
result = vibe.capture.download(lambda: vibe.find("#dl-link").click())
print(result["suggested_filename"]) # hello.txt
result.save_as("/tmp/hello.txt")
bro.close()The lambda is the action that triggers the download — here, clicking a link. Vibium starts listening first, runs the click, waits for the file, and returns the result.
How does each step work?
vibe.go(url)— open the page that has the download link or button.vibe.capture.download(action)— register a download listener, runaction, and return once the download completes.result["suggested_filename"]— the name the server suggested (from theContent-Dispositionheader).result.save_as(path)— copy the downloaded file to the path you want.bro.close()— close the browser.
In sync mode the result is a dict-like object: you can read result["url"], result["suggested_filename"], and result["path"], and it still has the save_as() method.
Why do I need a real download endpoint?
Browsers only start a download when the server sends a Content-Disposition: attachment header. A plain link that navigates or opens a file inline will not fire one. For local testing, a tiny server that sets that header is enough:
# server.py
from http.server import HTTPServer, BaseHTTPRequestHandler
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
if self.path == "/file":
self.send_response(200)
self.send_header("Content-Type", "text/plain")
self.send_header("Content-Disposition", 'attachment; filename="hello.txt"')
self.end_headers()
self.wfile.write(b"hello world")
else:
self.send_response(200)
self.send_header("Content-Type", "text/html")
self.end_headers()
self.wfile.write(b'<a href="/file" id="dl-link">Download hello.txt</a>')
HTTPServer(("localhost", 3000), Handler).serve_forever()Run python server.py in one terminal, then run the download script in another.
How do I monitor every download?
If files can download at any time, register on_download() once and collect them as they arrive instead of wrapping a single action:
import time
downloads = []
vibe.on_download(lambda dl: downloads.append(dl))
vibe.find("#dl-link").click()
time.sleep(2)
print(downloads[0]["suggested_filename"]) # hello.txtTips for reliable downloads
- Always save explicitly with
save_as()— the temp path may be cleaned up when the browser closes. - Check
suggested_filenamebefore saving so you keep the right extension. - Prefer
capture.download()for a single known action; useon_download()for ongoing monitoring.
Next steps
Frequently asked questions
How do I download a file with Vibium?
Wrap the click that starts the download in vibe.capture.download(). It sets up a listener, runs your action, and returns a download result. Call save_as() on that result to write the file to a path you choose.
How do I get the file's suggested name in Vibium?
The result from capture.download() exposes the server-suggested filename. In sync mode read it with result['suggested_filename']; you also get the temporary path and source URL so you can rename or move the file as needed.
Why does my Vibium download not trigger?
Browsers only download when the server sends a Content-Disposition attachment header. If a link just navigates or opens inline, no download fires. Point Vibium at an endpoint that returns the attachment header, or capture the response body directly instead.
Vibium is created by Jason Huggins. This is an independent tutorial — see the official Vibium site and GitHub repo for canonical docs.
Related guides
Accessibility Testing with Vibium
Accessibility testing with Vibium — read the a11y tree, assert on roles, names, and states, and catch WCAG issues in CI with no driver setup.
14 min read→How-To RecipesMixing API + Web Testing with Vibium
Mix API and web testing with Vibium — assert on backend JSON with waitForResponse and route while driving the real UI, in one script.
14 min read→How-To RecipesBulk Data Extraction with Vibium
Bulk data extraction with Vibium: build a repeatable scrape pipeline over a URL list, extract with findAll(), and write clean JSON, CSV, or a database.
13 min read→How-To RecipesE-commerce Test Automation with Vibium
E-commerce test automation with Vibium: script cart, checkout, and payment flows in JS or Python with auto-waiting, AI checks, and CI-ready smoke tests.
15 min read→