mirror of
https://github.com/callstack/agent-device.git
synced 2026-09-14 20:06:34 +08:00
123 lines
5.1 KiB
Markdown
123 lines
5.1 KiB
Markdown
# BrowserStack
|
|
|
|
Use BrowserStack App Automate for hosted Android and iOS WebDriver sessions.
|
|
|
|
## Credentials and connection
|
|
|
|
Set BrowserStack credentials in a non-interactive environment:
|
|
|
|
```bash
|
|
export BROWSERSTACK_USERNAME=...
|
|
export BROWSERSTACK_ACCESS_KEY=...
|
|
```
|
|
|
|
Connect with the platform, exact device and OS version, and app to test:
|
|
|
|
```bash
|
|
agent-device connect browserstack \
|
|
--platform android \
|
|
--device "Google Pixel 8" \
|
|
--provider-os-version 14.0 \
|
|
--provider-app bs://app-id
|
|
```
|
|
|
|
`--provider-app` accepts a BrowserStack app reference such as `bs://...`, an HTTP(S) app URL, or an existing local app path. BrowserStack uploads a local path when it creates the hosted session.
|
|
|
|
During `connect`, agent-device verifies the BrowserStack credentials and the exact device/OS pair. It checks a `bs://` reference against recent uploads and confirms that a local artifact exists before saving its absolute path. A public URL stays configured and BrowserStack validates it when the session starts. `open` still needs the app's installed package or bundle identifier, not its upload name.
|
|
|
|
Optional labels:
|
|
|
|
```bash
|
|
--provider-project agent-device
|
|
--provider-build "$GITHUB_RUN_ID"
|
|
--provider-session-name "$GITHUB_JOB"
|
|
```
|
|
|
|
Optional device features:
|
|
|
|
```bash
|
|
--provider-device-orientation portrait # or landscape (alias --device-orientation)
|
|
--provider-geo-location US # (alias --geo-location)
|
|
--provider-timezone New_York # (alias --timezone)
|
|
--provider-language Fr # (alias --language)
|
|
--provider-locale Fr # (alias --locale)
|
|
--provider-network-profile 4g-lte-advanced-good # (alias --network-profile)
|
|
--provider-custom-network 1000 # (alias --custom-network)
|
|
--provider-no-resign-app # iOS only
|
|
```
|
|
|
|
BrowserStack receives these values in `bstack:options` when it creates the hosted session.
|
|
|
|
- The orientation applies when the session starts. An activity without a fixed orientation, such as a Chrome Custom Tab hosting OAuth, can still open in landscape. Run `agent-device orientation portrait` after launching it when needed.
|
|
- `--provider-network-profile` and `--provider-custom-network` are mutually exclusive.
|
|
- `--provider-no-resign-app` applies to iOS only. BrowserStack re-signs uploaded iOS apps with its provisioning profile, which strips entitlements; opt out when testing entitlement-dependent features such as push notifications.
|
|
|
|
## CLI workflow
|
|
|
|
```bash
|
|
export BROWSERSTACK_USERNAME=...
|
|
export BROWSERSTACK_ACCESS_KEY=...
|
|
|
|
agent-device connect browserstack \
|
|
--platform android \
|
|
--device "Google Pixel 8" \
|
|
--provider-os-version 14.0 \
|
|
--provider-app bs://app-id \
|
|
--provider-project agent-device \
|
|
--provider-build "$GITHUB_RUN_ID"
|
|
|
|
agent-device open com.example.app
|
|
agent-device snapshot -i
|
|
agent-device click 'label="Continue"'
|
|
agent-device close
|
|
agent-device artifacts --json
|
|
agent-device disconnect
|
|
```
|
|
|
|
For MCP-only use, run `connect` in the same effective state directory before starting `agent-device mcp`. MCP exposes `open`, `snapshot`, `click`, `close`, and `artifacts`, but not provider `connect` commands.
|
|
|
|
## Node.js client
|
|
|
|
Use direct client configuration when the Node process manages BrowserStack credentials and selectors rather than a saved CLI connection profile:
|
|
|
|
```ts
|
|
import { createAgentDeviceClient } from 'agent-device';
|
|
|
|
const client = createAgentDeviceClient({
|
|
leaseProvider: 'browserstack',
|
|
platform: 'android',
|
|
device: 'Google Pixel 8',
|
|
providerOsVersion: '14.0',
|
|
providerApp: 'bs://app-id',
|
|
providerProject: 'agent-device',
|
|
providerBuild: process.env.GITHUB_RUN_ID,
|
|
});
|
|
|
|
await client.apps.open({ app: 'com.example.app' });
|
|
const snapshot = await client.capture.snapshot({ interactiveOnly: true });
|
|
console.log(snapshot.nodes.slice(0, 5));
|
|
await client.interactions.click({ selector: 'label="Continue"' });
|
|
const closed = await client.sessions.close();
|
|
const providerSessionId = closed.provider?.providerSessionId;
|
|
|
|
if (providerSessionId) {
|
|
const artifacts = await client.sessions.artifacts({
|
|
provider: 'browserstack',
|
|
providerSessionId,
|
|
});
|
|
console.log(artifacts.cloudArtifacts);
|
|
}
|
|
```
|
|
|
|
## Artifacts and troubleshooting
|
|
|
|
After `close`, BrowserStack can return session video, Appium logs, device logs, dashboard URLs, and public URLs. Run `agent-device artifacts --json`, or look up a previous session explicitly:
|
|
|
|
```bash
|
|
agent-device artifacts <webdriver-session-id> --provider browserstack --json
|
|
```
|
|
|
|
BrowserStack errors distinguish rejected credentials, an unavailable device/OS pair, a missing `bs://` upload, and a missing local artifact. If artifact lookup is pending immediately after `close`, retry it. BrowserStack may still be finalizing video and log URLs.
|
|
|
|
On hosted WebDriver sessions, `fill` checks that the field received focus before it sends keys. If it cannot confirm focus, it fails without typing. Use `snapshot -i` to confirm the target. If the driver cannot expose focus at all, use `press <target>` followed by `type <text>`. That sends text without confirming the destination.
|