Question

Je suis à la recherche d'un moyen de changer navigator.userAgent programme à la volée. Dans ma tentative avortée d'obtenir un appareil de contrôle de l'unité javascript automatisé, j'ai donné et essayé de commencer à utiliser FireUnit. Immédiatement, je me suis claqué dans l'un des murs de l'utilisation d'un navigateur réel pour les tests javascript.

Plus précisément, je dois changer navigator.userAgent pour simuler quelques centaines de chaînes de userAgent pour assurer la détection et la couverture appropriée sur une fonction donnée. navigator.userAgent est en lecture seule, donc je semble coincé! Comment puis-je moquer navigator.userAgent? User Agent Switcher (plug-in) peut changer la useragent de FF, mais je peux le faire dans javascript?

Était-ce utile?

La solution

Essayez:

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

navigator.userAgent; // 'foo'

Essayé dans FF2 et FF3.

Autres conseils

Ajout à solution Croissant frais , redéfinir le getter navigator.userAgent ne semble pas fonctionner dans Safari 5.0.5 (sous Windows 7 et Mac OS X 10.6.7).

Nécessité de créer un nouvel objet qui hérite de l'objet navigator et définir un nouveau getter userAgent pour cacher le getter userAgent original dans navigator:

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

La solution suivante fonctionne dans Chrome, Firefox, Safari, IE9 + et aussi avec les 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
            });
        }
    }
}

Exemples:

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

Utilisation Object.defineProperty devrait ajouter plusieurs autres navigateurs au mélange:

if (navigator.__defineGetter__) {
    navigator.__defineGetter__("userAgent", function () { 
        return "ua"; 
    });
} else if (Object.defineProperty) { 
    Object.defineProperty(navigator, "userAgent", { 
        get: function () { 
            return "ua";
        }
    });
}

Ce code devrait fonctionner (et a été testé) Firefox 1.5 + , Chrome 6 + , Opera 10.5 + et IE9 + . Malheureusement Safari sur toute plate-forme ne permet pas de changer le userAgent.

Edit:. Safari ne permet pas de changer le userAgent, mais on peut remplacer l'ensemble navigateur objet, comme l'a souligné dans une autre solution ci-dessus

La réponse du Croissant frais est correct. Mais il y a un problème: __defineGetter__ est dépréciée:

https: //developer.mozilla. org / fr-fr / docs / Web / JavaScript / Référence / Global_Objects / objet / defineGetter

  

Obsolète   Cette fonction a été supprimée des standards du Web.   Bien que certains navigateurs peuvent encore soutenir, il est en train de   être abandonné. Ne pas l'utiliser dans les anciens ou les nouveaux projets. Pages ou des applications Web   l'utiliser peut se rompre à tout moment.

Vous devez utiliser à la place defineProperty:

Object.defineProperty(navigator, "userAgent", { 
    get: function () { 
        return "foo"; // customized user agent
    }
});

navigator.userAgent; // 'foo'

Pour mettre à jour ce fil, defineGetter ne fonctionne plus dans Jasmine comme il a été dépréciée. Cependant, je trouve cela me permet de modifier le getter pour navigator.userAgent dans le jasmin:

navigator = {
  get userAgent() {
    return 'agent';
  }
}

console.log(navigator.userAgent); // returns 'agent'

Rappelez-vous remettre à zéro l'objet du navigateur une fois que vous avez terminé le test dans le jasmin

Pour ceux qui essaient de faire la même chose dactylographiée est ici la solution:

(<any>navigator)['__defineGetter__']('userAgent', function(){
    return 'foo';
});

navigator.userAgent; // 'foo'

Ou même chose pour la langue:

(<any>navigator)['__defineGetter__']('language', function(){
    return 'de-DE';
});

Je suppose que je prendrais une approche d'injection de dépendance. Au lieu de:

function myFunction() {
    var userAgent = navigator.userAgent;
    // do stuff with userAgent
}

Peut-être faire quelque chose comme:

function myFunction(userAgent) {
    // do stuff with userAgent
}

function getUserAgent() {
    window.userAgentReal = +window.userAgentReal || 0;
    return [ navigator.userAgent ][window.userAgentReal++];
}

function getUserAgentMock() {
    window.nextUserAgentMock = +window.nextUserAgentMock || 0;
    return [
        'test user agent1',
        'test user agent2',
        'test user agent3'
    ][window.nextUserAgentMock++];
}

var userAgent;
while (userAgent = getUserAgent()) {
    myFunction(userAgent);
}

Ensuite, vous pouvez getUserAgent() "se moquer des" en faisant:

function getUserAgentReal() { // formerly not 'Real'
    // ...
}

function getUserAgent() { // formerly 'Mock'
    // ...
}

Cette conception est toujours pas complètement automatisée (vous devez renommer manuellement le getter pour effectuer vos tests), et il ajoute un tas de complexité à quelque chose d'aussi simple que fonctionnant sur navigator.userAgent, et je ne sais pas comment vous » d effectivement identifier les bugs dans myFunction, mais je pensais que je jette là pour vous donner quelques idées comment cela pourrait être traitée.

Peut-être l'idée de « l'injection de dépendance » présentée ici peut en quelque sorte être intégré à FireUnit.

Pour ceux qui sont ici parce qu'ils ont besoin de changer la valeur userAgent dans les tests unitaires, la solution de Tyler longue marche, mais si vous voulez restaurer la userAgent initiale ou changer plus d'une fois, vous aurez probablement besoin de définir la propriété comme configurable:

function setUserAgent(userAgent) {
    Object.defineProperty(navigator, "userAgent", { 
        get: function () { 
            return userAgent; // customized user agent
        },
        configurable: true
    });
}

// Now in your setup phase:
// Keep the initial value
var initialUserAgent = navigator.userAgent;
setUserAgent('foo');

// In your tearDown:
// Restore the initial value
setUserAgent(initialUserAgent);

Sinon, vous croiserez peut-être une erreur de TypeError: Cannot redefine property. Fonctionne pour moi sur Chrome Headless.

navigator.userAgent est une propriété de chaîne en lecture seule, de sorte que son pas possible de le modifier

Au-dessus de réponses ne travaillaient pas pour PhantomJS + tapuscrit. Ci-dessous le code a fonctionné pour moi:

var __originalNavigator = navigator;
(window as any).navigator = new Object();
navigator["__proto__"] = __originalNavigator["__proto__"];
navigator["__defineGetter__"]('userAgent', function () { return 'Custom'; });

à la fin ce sujet mais pour Karma + Jasmin et Tapuscrit et que vous souhaitez définir la propriété userAgent ce fera:

describe('should validate YYYY-MM-dd format only on IE browser', () => {
    // this validator has a specific condition to work only in IE11 and down
    (window as any).navigator.__defineGetter__('userAgent', function () {
      return 'MSIE';
    });

...
// rest of the test

});

Cet article a contribué à: https://www.codeproject.com / Conseils / 1036762 / Mocking-userAgent avec JavaScript

Modifier navigator.userAgent sur Firefox et Opera via defineGetter

navigator.__defineGetter__('userAgent', function(){
    return( "iPhone 5" );
});

alert( navigator.userAgent ); //iPhone 5

Modifier navigator.userAgent sur IE et Opera par exemple d'objet

var navigator = new Object; 
navigator.userAgent = 'iPhone 5';

alert( navigator.userAgent ); //iPhone5

est une bonne chose, si vous travaillez sur le contrôle IE WebBrowser, vous pouvez doubler spoof à la fois la demande HTTP et JavaScript navigator.userAgent via execScript

WebBrowser1.Navigate "http://example.com", , , , "User-Agent: iPhone 5" & vbCrLf

WebBrowser1.Document.parentWindow.execScript ("var navigator=new Object;navigator.userAgent='iPhone 5';")
WebBrowser1.Document.parentWindow.execScript ("alert(navigator.userAgent);") 'iPhone 5

Non, je doute que vous pouvez le faire dans javascript. Mais avec User Agent Switcher de Firefox, vous pouvez tester tout ce que vous voulez useragent, alors pourquoi ne pas simplement l'utiliser?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top