Mock browser service providing controlled implementations of URL handling, cookie management, deferred task execution, and other browser-specific functionality for testing.
Mock URL handling with history state support:
/**
* Get or set the current URL
* @param {string} url - URL to set (optional)
* @param {boolean} replace - Whether to replace current history entry (optional)
* @param {*} state - History state object (optional)
* @returns {string} Current URL if no parameters provided
*/
$browser.url(url?, replace?, state?);
/**
* Get the current history state
* @returns {*} Current state object
*/
$browser.state();
/**
* Register a URL change listener
* @param {Function} listener - Function to call when URL changes
* @returns {Function} The listener function for removal
*/
$browser.onUrlChange(listener);Mock cookie storage and retrieval:
/**
* Get or set cookies
* @param {string} name - Cookie name to get/set (optional)
* @param {string} value - Cookie value to set (optional)
* @returns {string|Object} Cookie value if name provided, or all cookies object
*/
$browser.cookies(name?, value?);Mock implementation of deferred function execution:
/**
* Schedule a function for deferred execution
* @param {Function} fn - Function to execute
* @param {number} delay - Delay in milliseconds (optional, defaults to 0)
* @param {string} taskType - Type of task for tracking (optional)
* @returns {number} Timeout ID for cancellation
*/
$browser.defer(fn, delay?, taskType?);
/**
* Current mock time in milliseconds
* @type {number}
*/
$browser.defer.now;
/**
* Flush pending deferred functions
* @param {number} delay - Specific delay to flush (optional, flushes all if not specified)
*/
$browser.defer.flush(delay?);Mock implementation of outstanding request tracking:
/**
* Register callback to be notified when no requests are outstanding
* @param {Function} callback - Function to call when no requests are pending
*/
$browser.notifyWhenNoOutstandingRequests(callback);
/**
* Mark a task as completed (internal use)
* @param {string} taskType - Type of task completed
*/
$browser.$$completeOutstandingRequest(taskType);
/**
* Increment outstanding request count (internal use)
* @param {string} taskType - Type of task to track
*/
$browser.$$incOutstandingRequestCount(taskType);Mock URL polling mechanism:
/**
* Array of polling functions
* @type {Function[]}
*/
$browser.pollFns;
/**
* Execute all polling functions (internal use)
*/
$browser.$$checkUrlChange();Mock browser identification and lifecycle:
/**
* Indicates this is a mock browser implementation
* @type {boolean}
*/
$browser.isMock;
/**
* Mock application destroyed handler
* @type {Function}
*/
$browser.$$applicationDestroyed;Mock exception handler for collecting errors during tests:
/**
* Mock exception handler service
* @param {Error} exception - Exception that was thrown
* @param {string} cause - Cause of the exception (optional)
*/
$exceptionHandler(exception, cause?);
/**
* Array of logged exceptions
* @type {Array}
*/
$exceptionHandler.errors;
/**
* Assert that no exceptions were logged
* @throws {Error} If exceptions were logged
*/
$exceptionHandler.assertEmpty();Mock logging service that captures log messages for testing:
/**
* Mock log service with captured messages
*/
interface MockLog {
/** Log function that captures messages */
log: LogFunction & { logs: any[][] };
/** Warn function that captures messages */
warn: LogFunction & { logs: any[][] };
/** Info function that captures messages */
info: LogFunction & { logs: any[][] };
/** Error function that captures messages */
error: LogFunction & { logs: any[][] };
/** Debug function that captures messages */
debug: LogFunction & { logs: any[][] };
/**
* Assert that no messages were logged
* @throws {Error} If messages were logged
*/
assertEmpty(): void;
/**
* Clear all logged messages
*/
reset(): void;
}
interface LogFunction {
(...args: any[]): void;
}URL Testing:
describe('NavigationService', function() {
var NavigationService, $browser;
beforeEach(module('myApp'));
beforeEach(inject(function(_NavigationService_, _$browser_) {
NavigationService = _NavigationService_;
$browser = _$browser_;
}));
it('should change URL', function() {
NavigationService.navigateTo('/new-page');
expect($browser.url()).toBe('http://server/new-page');
});
it('should handle URL change events', function() {
var urlChanged = false;
$browser.onUrlChange(function(url) {
urlChanged = true;
});
$browser.url('/changed-url');
// Trigger URL change detection
angular.forEach($browser.pollFns, function(pollFn) {
pollFn();
});
expect(urlChanged).toBe(true);
});
});Cookie Testing:
describe('CookieService', function() {
var CookieService, $browser;
beforeEach(module('myApp'));
beforeEach(inject(function(_CookieService_, _$browser_) {
CookieService = _CookieService_;
$browser = _$browser_;
}));
it('should set and get cookies', function() {
CookieService.setCookie('sessionId', 'abc123');
expect($browser.cookies('sessionId')).toBe('abc123');
var retrieved = CookieService.getCookie('sessionId');
expect(retrieved).toBe('abc123');
});
it('should handle multiple cookies', function() {
$browser.cookies('cookie1', 'value1');
$browser.cookies('cookie2', 'value2');
var allCookies = $browser.cookies();
expect(allCookies).toEqual({
cookie1: 'value1',
cookie2: 'value2'
});
});
});Exception Handler Testing:
describe('ErrorService', function() {
var ErrorService, $exceptionHandler;
beforeEach(module('myApp'));
beforeEach(inject(function(_ErrorService_, _$exceptionHandler_) {
ErrorService = _ErrorService_;
$exceptionHandler = _$exceptionHandler_;
}));
it('should log exceptions', function() {
ErrorService.triggerError();
expect($exceptionHandler.errors.length).toBe(1);
expect($exceptionHandler.errors[0]).toMatch(/Error message/);
});
afterEach(function() {
$exceptionHandler.assertEmpty(); // Will fail if unexpected errors occurred
});
});Log Service Testing:
describe('LoggingService', function() {
var LoggingService, $log;
beforeEach(module('myApp'));
beforeEach(inject(function(_LoggingService_, _$log_) {
LoggingService = _LoggingService_;
$log = _$log_;
}));
afterEach(function() {
$log.reset();
});
it('should capture log messages', function() {
LoggingService.logInfo('Test message', 42);
expect($log.info.logs.length).toBe(1);
expect($log.info.logs[0]).toEqual(['Test message', 42]);
});
it('should capture different log levels', function() {
LoggingService.performOperations();
expect($log.log.logs.length).toBeGreaterThan(0);
expect($log.warn.logs.length).toBe(0);
expect($log.error.logs.length).toBe(0);
});
});Task Tracking:
describe('AsyncService', function() {
var AsyncService, $browser;
beforeEach(module('myApp'));
beforeEach(inject(function(_AsyncService_, _$browser_) {
AsyncService = _AsyncService_;
$browser = _$browser_;
}));
it('should track outstanding requests', function() {
var callbackCalled = false;
$browser.notifyWhenNoOutstandingRequests(function() {
callbackCalled = true;
});
AsyncService.startBackgroundTask();
expect(callbackCalled).toBe(false);
// Complete the task
AsyncService.completeBackgroundTask();
expect(callbackCalled).toBe(true);
});
});// Browser Mock Interface
interface MockBrowser {
url(url?: string, replace?: boolean, state?: any): string;
state(): any;
cookies(name?: string, value?: string): string | Object;
defer(fn: Function, delay?: number, taskType?: string): number;
onUrlChange(listener: Function): Function;
notifyWhenNoOutstandingRequests(callback: Function): void;
pollFns: Function[];
isMock: boolean;
}
// Exception Handler Interface
interface MockExceptionHandler {
(exception: Error, cause?: string): void;
errors: any[];
assertEmpty(): void;
}
// URL Change Listener Type
type UrlChangeListener = (url: string, state?: any) => void;