Mocking a useragent in javascript?

I'm looking for a way to programmatically change navigator.userAgent on the fly. In my failed attempt to get an automated javascript unit tester, I gave up and attempted to begin using fireunit. Immediately, I've slammed into one of the walls of using an actual browser for javascript testing.

Specifically, I need to change navigator.userAgent to simulate a few hundred userAgent strings to ensure proper detection and coverage on a given function. navigator.userAgent is readonly, so I seem stuck! How can I mock navigator.userAgent? User Agent Switcher (plugin) can switch FF's useragent, but can I do it within javascript?


Solution 1:

Try:

navigator.__defineGetter__('userAgent', function(){
    return 'foo' // customized user agent
});

navigator.userAgent; // 'foo'

Tried it in FF2 and FF3.

Solution 2:

Adding on to Crescent Fresh's solution, redefining the navigator.userAgent getter doesn't seem to work in Safari 5.0.5 (on Windows 7 & Mac OS X 10.6.7).

Need to create a new object that inherits from the navigator object and define a new userAgent getter to hide the original userAgent getter in navigator:

var __originalNavigator = navigator;
navigator = new Object();
navigator.__proto__ = __originalNavigator;
navigator.__defineGetter__('userAgent', function () { return 'Custom'; });

Solution 3:

The following solution works in Chrome, Firefox, Safari, IE9+ and also with iframes:

function setUserAgent(window, userAgent) {
    if (window.navigator.userAgent != userAgent) {
        var userAgentProp = { get: function () { return userAgent; } };
        try {
            Object.defineProperty(window.navigator, 'userAgent', userAgentProp);
        } catch (e) {
            window.navigator = Object.create(navigator, {
                userAgent: userAgentProp
            });
        }
    }
}

Examples:

setUserAgent(window, 'new user agent');
setUserAgent(document.querySelector('iframe').contentWindow, 'new user agent');