WebAutomator provides web-specific methods for automating browser interactions in Patrol tests. Access it through $.platform.web in your tests.
Accessing WebAutomator
patrolTest('web test', ($) async {
// Access via platform.web
await $.platform.web.tap(WebSelector(text: 'Submit'));
// Platform-specific action helper
await $.platform.action(
web: $.platform.web.configure,
);
});
Initialization
Initializes the web automator.Called automatically before tests begin.
Configures the web automator with settings from WebAutomatorConfig.
Element Interaction
Tapping
tap(WebSelector selector, {...})
Clicks on a web element.Parameters:
selector - WebSelector to locate the element
iframeSelector - Optional selector for iframe context
// Click a button
await $.platform.web.tap(
WebSelector(text: 'Submit'),
);
// Click element in iframe
await $.platform.web.tap(
WebSelector(role: 'button'),
iframeSelector: WebSelector(cssOrXpath: '#payment-iframe'),
);
Text Entry
enterText(WebSelector selector, {...})
Enters text into a web form field.Parameters:
selector - The input field to target
text - Text to enter (required)
iframeSelector - Optional iframe selector
await $.platform.web.enterText(
WebSelector(label: 'Email'),
text: '[email protected]',
);
// In iframe
await $.platform.web.enterText(
WebSelector(placeholder: 'Card number'),
text: '4242 4242 4242 4242',
iframeSelector: WebSelector(cssOrXpath: '#stripe-iframe'),
);
scrollTo(WebSelector selector, {...})
Scrolls to bring an element into view.await $.platform.web.scrollTo(
WebSelector(text: 'Footer Content'),
);
Browser Permissions
grantPermissions({required List<String> permissions})
Grants browser permissions.Common permissions:
'geolocation'
'notifications'
'camera'
'microphone'
'clipboard-read'
'clipboard-write'
await $.platform.web.grantPermissions(
permissions: ['geolocation', 'notifications'],
);
Clears all granted browser permissions.await $.platform.web.clearPermissions();
Cookie Management
Adds a browser cookie.Parameters:
name - Cookie name (required)
value - Cookie value (required)
url - URL to set cookie for
domain - Cookie domain
path - Cookie path
expires - Expiration timestamp
httpOnly - HTTP-only flag
secure - Secure flag
sameSite - SameSite policy (‘Strict’, ‘Lax’, ‘None’)
await $.platform.web.addCookie(
name: 'session_id',
value: 'abc123',
domain: '.example.com',
secure: true,
sameSite: 'Lax',
);
getCookies()
Future<List<LinkedHashMap<Object?, Object?>>>
Retrieves all browser cookies.final cookies = await $.platform.web.getCookies();
for (final cookie in cookies) {
print('${cookie['name']}: ${cookie['value']}');
}
Clears all browser cookies.await $.platform.web.clearCookies();
File Upload
uploadFile({required List<UploadFileData> files})
Uploads files through file input elements.await $.platform.web.uploadFile(
files: [
UploadFileData(
path: '/path/to/document.pdf',
mimeType: 'application/pdf',
),
UploadFileData(
path: '/path/to/image.png',
mimeType: 'image/png',
),
],
);
Dialog Handling
Accepts the next JavaScript dialog (alert, confirm, prompt) that appears.Returns the dialog message.// Start listening before triggering dialog
final dialogFuture = $.platform.web.acceptNextDialog();
// Trigger dialog
await $.platform.web.tap(WebSelector(text: 'Show Alert'));
// Get dialog message
final message = await dialogFuture;
print('Dialog said: $message');
Dismisses the next JavaScript dialog.final dialogFuture = $.platform.web.dismissNextDialog();
await $.platform.web.tap(WebSelector(text: 'Show Confirm'));
await dialogFuture;
pressKey({required String key})
Presses a single keyboard key.Common keys: 'Enter', 'Escape', 'Tab', 'Backspace', 'ArrowUp', etc.await $.platform.web.pressKey(key: 'Enter');
await $.platform.web.pressKey(key: 'Escape');
pressKeyCombo({required List<String> keys})
Presses a keyboard shortcut.// Ctrl+C
await $.platform.web.pressKeyCombo(keys: ['Control', 'c']);
// Cmd+V (on Mac)
await $.platform.web.pressKeyCombo(keys: ['Meta', 'v']);
// Ctrl+Shift+K
await $.platform.web.pressKeyCombo(keys: ['Control', 'Shift', 'k']);
Browser Navigation
Navigates back in browser history.await $.platform.web.goBack();
Navigates forward in browser history.await $.platform.web.goForward();
Clipboard
Retrieves text from the clipboard.Requires clipboard-read permission.await $.platform.web.grantPermissions(
permissions: ['clipboard-read'],
);
final clipboardText = await $.platform.web.getClipboard();
expect(clipboardText, 'Expected content');
setClipboard({required String text})
Sets clipboard text.Requires clipboard-write permission.await $.platform.web.grantPermissions(
permissions: ['clipboard-write'],
);
await $.platform.web.setClipboard(text: 'Hello, World!');
Window Management
resizeWindow({required Size size})
Resizes the browser window.// Mobile viewport
await $.platform.web.resizeWindow(
size: Size(375, 667), // iPhone SE
);
// Desktop viewport
await $.platform.web.resizeWindow(
size: Size(1920, 1080),
);
Dark Mode
Enables dark mode in the browser.await $.platform.web.enableDarkMode();
Disables dark mode (switches to light mode).await $.platform.web.disableDarkMode();
File Downloads
Returns a list of all files downloaded during the current test.// Trigger download
await $.platform.web.tap(WebSelector(text: 'Download Report'));
// Wait for download
await Future.delayed(Duration(seconds: 2));
// Verify
final downloads = await $.platform.web.verifyFileDownloads();
expect(downloads, contains('report.pdf'));
WebSelector
The selector class for locating web elements:
WebSelector({
String? role,
String? label,
String? placeholder,
String? text,
String? altText,
String? title,
String? testId,
String? cssOrXpath,
})
Selector Examples
// By text content
WebSelector(text: 'Submit')
// By ARIA label
WebSelector(label: 'Email address')
// By placeholder
WebSelector(placeholder: 'Enter your email')
// By role
WebSelector(role: 'button')
// By test ID (data-testid attribute)
WebSelector(testId: 'login-button')
// By CSS selector
WebSelector(cssOrXpath: '.submit-button')
// By XPath
WebSelector(cssOrXpath: '//button[@class="primary"]')
// Combined
WebSelector(
role: 'textbox',
label: 'Password',
)
Usage Examples
Complete Login Flow
patrolTest('web login', ($) async {
await $.pumpWidgetAndSettle(MyWebApp());
// Enter credentials
await $.platform.web.enterText(
WebSelector(label: 'Email'),
text: '[email protected]',
);
await $.platform.web.enterText(
WebSelector(label: 'Password'),
text: 'secure123',
);
// Submit
await $.platform.web.tap(
WebSelector(role: 'button', text: 'Sign In'),
);
// Verify success (back in Flutter)
await $(Text('Dashboard')).waitUntilVisible();
});
patrolTest('payment in iframe', ($) async {
await $.pumpWidgetAndSettle(MyApp());
// Interact with main page
await $('Checkout').tap();
// Enter card details in Stripe iframe
final stripeIframe = WebSelector(
cssOrXpath: 'iframe[name="stripe"]',
);
await $.platform.web.enterText(
WebSelector(placeholder: 'Card number'),
text: '4242424242424242',
iframeSelector: stripeIframe,
);
await $.platform.web.enterText(
WebSelector(placeholder: 'MM / YY'),
text: '12/25',
iframeSelector: stripeIframe,
);
await $.platform.web.tap(
WebSelector(text: 'Pay'),
);
});
Test with Permissions
patrolTest('geolocation feature', ($) async {
// Grant permission
await $.platform.web.grantPermissions(
permissions: ['geolocation'],
);
await $.pumpWidgetAndSettle(MyApp());
await $('Use My Location').tap();
await $(Text('Location: 37.7749, -122.4194')).waitUntilVisible();
});
Keyboard Shortcuts
patrolTest('keyboard shortcuts', ($) async {
await $.pumpWidgetAndSettle(MyApp());
// Open search with Ctrl+K
await $.platform.web.pressKeyCombo(keys: ['Control', 'k']);
await $(TextField).waitUntilVisible();
// Close with Escape
await $.platform.web.pressKey(key: 'Escape');
});
Responsive Testing
patrolTest('responsive design', ($) async {
// Test mobile layout
await $.platform.web.resizeWindow(size: Size(375, 667));
await $.pumpWidgetAndSettle(MyApp());
expect($(#mobileMenu).visible, true);
// Test desktop layout
await $.platform.web.resizeWindow(size: Size(1920, 1080));
await $.pumpAndSettle();
expect($(#desktopMenu).visible, true);
});
See Also