Detector Test Tutorial

dmolsen edited this page Aug 14, 2012 · 8 revisions

Modernizr-based tests help create the bulk of the data that is available in a browser profile. They are broken down into four types:

  • core tests - they come from the included version of Modernizr. The profiles created with core data are stored in user-agents/core/ and include information from ua-parser-php.
  • extended tests - they are meant to be used on an individual install basis. extended tests should be seen as a way for developers to add tests that core doesn't cover yet not have to worry that core tests will wipe out their work in future iterations. The information from extended tests are stored in profiles in user-agents/extended/.
  • per-session tests - they are for features that are unique to a browser but only needed to be tested once per session. A good example of this is would be device pixel ratio. An iPhone 3G and iPhone 4 can both run the latest version of Mobile Safari but only the iPhone 4 has the Retina display. Because device information can't be gleaned from the user-agent the per-session test is used to find out support for device pixel ratio.
  • per-request tests - they are for features that need to be tested on every browser request. They test features that change both on per browser basis as well as a per request basis. A decent example of this is screen size. A user can change their browser window in between tests and a per-request test helps capture the change.

Creating Extended Tests

To add your own extended tests simply follow the Modernizr.addTest() format and put them in the tests/extended/ directory. Names of extended tests should start with extended- so that their values get put into the appropriate profile. The string extended- is stripped from the test name when placing it in session. For example, Detector comes with one "pre-built" extended test that checks for the emoji support and it looks like this:

Modernizr.addTest('extended-emoji', function() {
    {...}
});

When saving the results of the extended test Detector will strip extended- from extended-emoji so you will access the result in PHP as $ua->emoji.

Versioning of Extended Tests

As browsers implement new features you may want to update your extended tests and make sure that profiles you've already created get updated. In order to do that you simply need to create the extended test as above and edit your config.ini file with a new value for extendedVersion. For example, your config.ini may read:

extendedVersion = "1.0";

and you updated it too:

extendedVersion = "1.1";

Any profile that has been created with the 1.0 version of tests will now be run against the full suite of tests, including the new extended tests, and updated to the 1.1 version when the corresponding user-agent visits your site.

Note: This updating of profiles will only happen when an appropriate user agent visits your site. Technically speaking profiles can skip entire version numbers and tests. This is an expected behavior.

Creating Per Session Tests

To add your own per-session tests simply follow the Modernizr.addTest() format and put them in the tests/persession/ directory. Names of per-session tests should start with ps- so that their values are not added to either the core or extended profiles. The string ps- is stripped from the test name when placing it in session. For example, Detector comes with one "pre-built" per-session test that checks for the pixel density ratio support and it looks like this:

Modernizr.addTest('ps-hiResCapable', {...});

When saving the results of the extended test Detector will strip ps- from ps-hiResCapable so you will access the result in PHP as $ua->hiResCapable.

Creating Per Request Tests

Creating per-request tests is exactly the same as creating per-session tests. Simply place the tests in the tests/perrequest/ directory and prepend them with pr-.

Returning Values Other Than True/False

By default most tests should return true or false. You can return other values if you like though. For example, Detector comes with an example which tests for the screen attributes of the browser and returns an object. While this example is a per-request test you can also use this feature with extended or persession tests.

Modernizr.addTest("pr-screenAttributes",function() { 
   var _windowHeight = (window.innerHeight > 0) ? window.innerHeight : screen.width;
   var _windowWidth  = (window.innerWidth > 0) ? window.innerWidth : screen.width;
   var _colorDepth   = screen.colorDepth;
   return { windowHeight: _windowHeight, windowWidth: _windowWidth, colorDepth: _colorDepth };
});

So in this case Modernizr will return an object with the key pr-screenAttributes that will have the attributes windowHeight, windowWidth, and colorDepth that will contain the values for that browser. In your app you'd access each as:

$ua->screenAttributes->windowHeight
$ua->screenAttributes->windowWidth
$ua->screenAttributes->colorDepth

Note: If you want to return values you must return them as attributes of an object as in the example. You cannot return a value for a top-level attribute. For example, $ua->colorDepth is not possible.

Disabling Tests

To disable extended, per-session or per-request tests simply append an underscore (_) to the beginning of the filename. For example, to disable the persession/dpi.js test simply rename it like so, persession/_dpi.js.