Are you sure you want to delete this access key?
sidebar_position | sidebar_label |
---|---|
54 | Web Browser |
The Browser Provider allows you to automate web browser interactions for testing and scraping purposes.
This provider uses Playwright to control a headless Chrome browser, enabling you to navigate web pages, interact with elements, and extract data.
Playwright is a peer dependency of promptfoo, so you will need to install it separately:
npm install playwright @playwright/browser-chromium playwright-extra puppeteer-extra-plugin-stealth
To use the Headless Browser Provider, set the provider id
to browser
and provide a configuration object with a series of steps to execute.
providers:
- id: browser
config:
steps:
- action: navigate
args:
url: 'https://example.com'
- action: type
args:
selector: '#search-input'
text: '{{prompt}}'
- action: click
args:
selector: '#search-button'
- action: extract
args:
selector: '#results'
name: searchResults
transformResponse: 'data.searchResults'
The Headless Browser Provider supports the following actions:
navigate
: Go to a specified URLclick
: Click on an elementtype
: Enter text into an input fieldscreenshot
: Take a screenshot of the pageextract
: Extract text content from an elementwait
: Wait for a specified amount of timewaitForNewChildren
: Wait for new children of an elementurl
: The URL to navigate toselector
: The CSS selector of the element to clickoptional
: If true, then don't throw an error if the selector doesn't existselector
: The CSS selector of the element to extract text fromfilename
: The filename to save the screenshot toselector
: The CSS selector of the input elementtext
: The text to type into the inputSpecial characters can be sent using the following placeholders:
<enter>
<tab>
<escape>
ms
: The number of milliseconds to waitparentSelector
: The CSS selector of the parent element to wait for new children ofdelay
: The number of milliseconds to wait before checking for new childrentimeout
: The maximum number of milliseconds to wait for new childrenUse the transformResponse
config option to extract specific data from the results. The parser receives an object with two properties:
extracted
: An object containing named results from extract
actionsfinalHtml
: The final HTML content of the page after all actions are completedYou can use Nunjucks templating in your configuration, including the {{prompt}}
variable and any other variables passed in the test context.
providers:
- id: browser
config:
steps:
- action: navigate
args:
url: 'https://example.com/search?q={{prompt}}'
- action: extract
args:
selector: '#first-result'
name: topResult
transformResponse: 'extracted.topResult'
tests:
- vars:
prompt: 'What is the capital of France?'
If you are using promptfoo as a node library, you can provide the equivalent provider config:
{
// ...
providers: [{
id: 'browser',
config: {
steps: [
{ action: 'navigate', args: { url: 'https://example.com' } },
{ action: 'type', args: { selector: '#search', text: '{{prompt}}' } },
{ action: 'click', args: { selector: '#submit' } },
{ action: 'extract', args: { selector: '#results' }, name: 'searchResults' }
],
transformResponse: (extracted, finalHtml) => extracted.searchResults,
}
}],
}
Supported config options:
Option | Type | Description |
---|---|---|
headless | boolean |
Whether to run the browser in headless mode. Defaults to true . |
cookies | string | { name: string; value: string; domain?: string; path?: string; }[] |
A string or array of cookies to set on the browser |
transformResponse | string | Function |
A function or string representation of a function to parse the response. Receives an object with extracted and finalHtml parameters and should return a ProviderResponse |
steps | BrowserAction[] |
An array of actions to perform in the browser |
timeoutMs | number |
The maximum time in milliseconds to wait for the browser operations to complete |
Note: All string values in the config support Nunjucks templating. This means you can use the {{prompt}}
variable or any other variables passed in the test context.
The steps
array in the configuration can include the following actions:
Action | Description | Required Args | Optional Args |
---|---|---|---|
navigate | Navigate to a specified URL | url : string |
|
click | Click on an element | selector : string |
|
extract | Extract text content from an element | selector : string, name : string |
|
screenshot | Take a screenshot of the page | path : string |
fullPage : boolean |
type | Type text into an input field | selector : string, text : string |
|
wait | Wait for a specified amount of time | ms : number |
|
waitForNewChildren | Wait for new child elements to appear under a parent | parentSelector : string |
delay : number, timeout : number |
Each action in the steps
array should be an object with the following structure:
{
action: string;
args: {
[key: string]: any;
};
name?: string;
}
Each step in the steps
array should have the following structure:
action
: Specifies the type of action to perform (e.g., 'navigate', 'click', 'type').args
: Contains the required and optional arguments for the action.name
(optional): Used to name extracted content in the 'extract' action.Steps are executed sequentially, enabling complex web interactions.
All string values in args
support Nunjucks templating, allowing use of variables like {{prompt}}
.
Streamlit applications follow a common pattern where data-testid
attributes are used to identify elements.
Here's an example configuration:
providers:
- id: browser
config:
headless: true # set to false to see the browser
steps:
# Load the page - make sure you get the full URL if it's in an iframe!
- action: navigate
args:
url: 'https://doc-chat-llm.streamlit.app/~/+/'
# Enter the message and press enter
- action: type
args:
selector: 'textarea'
text: '{{prompt}} <enter>'
# Wait for the response
- action: wait
args:
ms: 5000
# Read the response
- action: extract
args:
selector: 'div.stChatMessage:last-of-type'
name: response
transformResponse: 'extracted.response'
If you are using a selector to interact with the page and it keeps timing out, it could be because the element is inside an iframe.
If this is the case, try loading the iframe contents directly using the navigate
action.
If you want to view the browser as it runs, you can set the headless
option to false
in the config.
providers:
- id: browser
config:
headless: false
If you are having trouble getting your tests to run, set headless
to false
and the browser will open. You can then see what is happening in the browser console.
Additionally, setting the LOG_LEVEL=debug
environment variable will print debug information to the console during your evaluation.
Press p or to see the previous file or, n or to see the next file
Browsing data directories saved to S3 is possible with DAGsHub. Let's configure your repository to easily display your data in the context of any commit!
promptfoo is now integrated with AWS S3!
Are you sure you want to delete this access key?
Browsing data directories saved to Google Cloud Storage is possible with DAGsHub. Let's configure your repository to easily display your data in the context of any commit!
promptfoo is now integrated with Google Cloud Storage!
Are you sure you want to delete this access key?
Browsing data directories saved to Azure Cloud Storage is possible with DAGsHub. Let's configure your repository to easily display your data in the context of any commit!
promptfoo is now integrated with Azure Cloud Storage!
Are you sure you want to delete this access key?
Browsing data directories saved to S3 compatible storage is possible with DAGsHub. Let's configure your repository to easily display your data in the context of any commit!
promptfoo is now integrated with your S3 compatible storage!
Are you sure you want to delete this access key?