Permissions Module
The Permissions module allows you to manage browser permissions for features like geolocation, notifications, and camera access.
Overview
The Permissions module allows you to:
- Grant or deny browser permissions
- Manage geolocation, notifications, camera, and microphone permissions
- Control permission prompts
- Test permission-dependent functionality
Accessing the Module
PermissionsModule permissions = driver.Permissions;
Timeout and Cancellation
All commands in this module accept optional timeoutOverride and CancellationToken parameters. Use timeoutOverride to set a per-command timeout (defaults to BiDiDriver.DefaultCommandTimeout when omitted). Use CancellationToken for cooperative cancellation. See the API Design Guide for details and examples.
Setting Permissions
Grant Geolocation Permission
SetPermissionCommandParameters @params = new SetPermissionCommandParameters(
new PermissionDescriptor("geolocation"),
PermissionState.Granted,
"https://example.com");
await driver.Permissions.SetPermissionAsync(@params);
Console.WriteLine("Geolocation permission granted");
Deny Permission
SetPermissionCommandParameters @params = new SetPermissionCommandParameters(
new PermissionDescriptor("geolocation"),
PermissionState.Denied,
"https://example.com");
await driver.Permissions.SetPermissionAsync(@params);
Console.WriteLine("Geolocation permission denied");
Permission Types
Notifications
SetPermissionCommandParameters @params = new SetPermissionCommandParameters(
new PermissionDescriptor("notifications"),
PermissionState.Granted,
"https://example.com");
await driver.Permissions.SetPermissionAsync(@params);
Camera
SetPermissionCommandParameters @params = new SetPermissionCommandParameters(
new PermissionDescriptor("camera"),
PermissionState.Granted,
"https://example.com");
await driver.Permissions.SetPermissionAsync(@params);
Microphone
SetPermissionCommandParameters @params = new SetPermissionCommandParameters(
new PermissionDescriptor("microphone"),
PermissionState.Granted,
"https://example.com");
await driver.Permissions.SetPermissionAsync(@params);
MIDI
SetPermissionCommandParameters @params = new SetPermissionCommandParameters(
new PermissionDescriptor("midi"),
PermissionState.Granted,
"https://example.com");
await driver.Permissions.SetPermissionAsync(@params);
Permission States
Permissions can be set to three states:
PermissionState.Granted- Permission is grantedPermissionState.Denied- Permission is deniedPermissionState.Prompt- User will be prompted
// Set permission to prompt user
SetPermissionCommandParameters @params = new SetPermissionCommandParameters(
new PermissionDescriptor("notifications"),
PermissionState.Prompt,
"https://example.com");
await driver.Permissions.SetPermissionAsync(@params);
Common Patterns
Testing Geolocation Functionality
// Grant geolocation permission
SetPermissionCommandParameters permParams = new SetPermissionCommandParameters(
new PermissionDescriptor("geolocation"),
PermissionState.Granted,
"https://example.com");
await driver.Permissions.SetPermissionAsync(permParams);
// Set location
SetGeolocationOverrideCoordinatesCommandParameters geoParams =
new SetGeolocationOverrideCoordinatesCommandParameters
{
Coordinates = new GeolocationCoordinates(37.7749, -122.4194) { Accuracy = 100 },
Contexts = { contextId }
};
await driver.Emulation.SetGeolocationOverrideAsync(geoParams);
// Test location access
EvaluateResult result = await driver.Script.EvaluateAsync(
new EvaluateCommandParameters(
@"new Promise((resolve) => {
navigator.geolocation.getCurrentPosition(
(pos) => resolve(`${pos.coords.latitude},${pos.coords.longitude}`),
(err) => resolve(`Error: ${err.message}`)
);
})",
new ContextTarget(contextId),
true));
if (result is EvaluateResultSuccess success &&
success.Result is StringRemoteValue locationValue)
{
string location = locationValue.Value;
Console.WriteLine($"Location: {location}");
}
Testing Notification Permissions
// Grant notification permission
SetPermissionCommandParameters @params = new SetPermissionCommandParameters(
new PermissionDescriptor("notifications"),
PermissionState.Granted,
"https://example.com");
await driver.Permissions.SetPermissionAsync(@params);
// Navigate to page
await driver.BrowsingContext.NavigateAsync(
new NavigateCommandParameters(contextId, "https://example.com")
{ Wait = ReadinessState.Complete });
// Check permission state in page
EvaluateResult result = await driver.Script.EvaluateAsync(
new EvaluateCommandParameters(
"Notification.permission",
new ContextTarget(contextId),
true));
if (result is EvaluateResultSuccess success &&
success.Result is StringRemoteValue permissionValue)
{
string permissionState = permissionValue.Value;
Console.WriteLine($"Notification permission: {permissionState}");
}
Testing Permission Denial
// Deny camera permission
SetPermissionCommandParameters @params = new SetPermissionCommandParameters(
new PermissionDescriptor("camera"),
PermissionState.Denied,
"https://example.com");
await driver.Permissions.SetPermissionAsync(@params);
// Try to access camera - should fail
EvaluateResult result = await driver.Script.EvaluateAsync(
new EvaluateCommandParameters(
@"navigator.mediaDevices.getUserMedia({ video: true })
.then(() => 'granted')
.catch(err => `denied: ${err.name}`)",
new ContextTarget(contextId),
true));
if (result is EvaluateResultSuccess success &&
success.Result is StringRemoteValue accessValue)
{
string accessResult = accessValue.Value;
Console.WriteLine($"Camera access: {accessResult}");
}
Testing Multiple Permissions
// Grant multiple permissions
string[] permissionTypes = { "camera", "microphone" };
foreach (string permType in permissionTypes)
{
SetPermissionCommandParameters @params = new SetPermissionCommandParameters(
new PermissionDescriptor(permType),
PermissionState.Granted,
"https://example.com");
await driver.Permissions.SetPermissionAsync(@params);
}
// Test accessing both camera and microphone
EvaluateResult result = await driver.Script.EvaluateAsync(
new EvaluateCommandParameters(
@"navigator.mediaDevices.getUserMedia({ video: true, audio: true })
.then(() => 'both granted')
.catch(err => `error: ${err.name}`)",
new ContextTarget(contextId),
true));
if (result is EvaluateResultSuccess success &&
success.Result is StringRemoteValue accessValue)
{
string accessResult = accessValue.Value;
Console.WriteLine($"Media access: {accessResult}");
}
Available Permission Names
Common permission descriptor names:
"geolocation"- Location services"notifications"- Push notifications"camera"- Camera access"microphone"- Microphone access"midi"- MIDI device access"background-sync"- Background sync"clipboard-read"- Clipboard read access"clipboard-write"- Clipboard write access"persistent-storage"- Persistent storage quota
Note: Available permissions vary by browser and version.
Some permissions define descriptor members beyond the name — for example, "midi" supports a sysex member and "camera" supports panTiltZoom. Add such members via PermissionDescriptor.AdditionalData (for example, descriptor.AdditionalData["sysex"] = true) and they are serialized as additional members of the descriptor object.
Browser Support
| Browser | Support Level |
|---|---|
| Chrome/Edge | ✅ Full support |
| Firefox | ✅ Full support |
| Safari | ⚠️ Limited support |
Best Practices
- Set permissions before navigation: Set permissions before navigating to the page that needs them
- Reset permissions between tests: Return each permission to
PermissionState.Promptto ensure test isolation (there is no separate clear command) - Test both granted and denied states: Verify your application handles both cases correctly
- Combine with emulation: Use with Emulation module for location testing
- Handle errors gracefully: Not all permissions are available in all browsers
Common Issues
Permissions Not Taking Effect
Problem: Permission changes don't apply to the page.
Solution:
- Set permissions before navigating to the page
- Refresh the page after changing permissions
- Ensure you're using the correct permission name
Permission Not Supported
Problem: Module throws "not supported" errors.
Solution:
- Check browser version and compatibility
- Enable experimental features if required
- Verify the permission type is available in your browser
Permission Persists Between Tests
Problem: Permission state carries over to next test.
Solution:
- Reset permissions to
PermissionState.Promptafter each test - Use isolated user contexts for test isolation, scoping the permission to one via
SetPermissionCommandParameters.UserContextId - Clear browser state between test runs
Invalid Permission Name
Problem: Permission descriptor name not recognized.
Solution:
- Use standard permission names from the Permissions API
- Check browser documentation for supported permission names
- Test permission name in browser console first
Next Steps
- Emulation Module: Device and geolocation emulation
- Browser Module: User context management
- Bluetooth Module: Web Bluetooth API control
- API Reference: Complete API documentation