Get help with testing, discuss unit testing strategies etc.


Post by aratcliffe »

I can't quite figure out how to load the Google Maps API as a dependency. To work correctly the library needs to be loaded via a script tag rather than using XHR. The library can be dynamically as described at https://code.google.com/apis/maps/docume ... #Libraries but as the callback is executed in the global scope I'm not sure how to initiate execution of my test after the library has loaded.

If I use the harness cachePreload option the dependencies are loaded via script tags and the library is available but this breaks relative urls in my CSS.

Any ideas?

Post by nickolay »

Siesta uses loading with <script> tags so you can just specify the url directly in "preload". This worked fine for me:
Harness.configure({
    title     : 'Awesome Test Suite',
    autoCheckGlobals : true,

    // no files to preload
    preload : [
        'https://maps.googleapis.com/maps/api/js?libraries=geometry&sensor=true'
    ]
})

Post by aratcliffe »

Thanks for the reply nickolay. I've looked into this further and now have a good idea of what's happening but still no solution. When the url is specified in the preload array as 'https://maps.googleapis.com/maps/api/js?sensor=false' a bootstrap script is loaded that in turn attempts to write a script tag to load the Maps API:
function getScript(src) {
document.write('<' + 'script src="' + src + '"' +
' type="text/javascript"><' + '/script>');
} 
...
getScript("https://maps.gstatic.com/intl/en_gb/mapfiles/api-3/5/16/main.js");
I'm picking the Maps API is not loaded because the document is already loaded at the point at which the bootstrap script attempts to write the API script tag. If you specify a callback parameter on the bootstrap script URL such as callback=void, the bootstrap script will attempt to load the Maps API using DOM methods:
function getScript(src) {
var s = document.createElement('script');
s.src = src;
document.body.appendChild(s);
}
In this case the operation fails because document.body is null at the point in time at which the script element is being appended.

Post by nickolay »

Hm, I see.. Do you use "hostPageUrl" option? Or do you have the { text : "" } entries in your `preload`? This is the only reason siesta will try to load the preload files *after* page load. In "usual" cases it generates a single chunk of html and it works nearly the same as loading usual page.

Anyway, you can load the GoogleMaps dynamically, right? Just put the snippet inside of your test:
StartTest(function (t) {
    
    t.expectGlobal('initialize')
    
    // define a global function for callback to work
    initialize = function () {
      var myLatlng = new google.maps.LatLng(-34.397, 150.644);
      var myOptions = {
        zoom: 8,
        center: myLatlng,
        mapTypeId: google.maps.MapTypeId.ROADMAP
      }
      var map = new google.maps.Map(document.body, myOptions);
      
      t.endAsync(async)
    }
  
    var async = t.beginAsync()
    
      var script = document.createElement("script");
      script.type = "text/javascript";
      script.src = "https://maps.googleapis.com/maps/api/js?sensor=false&callback=initialize";
      document.body.appendChild(script);
})

Post by aratcliffe »

No I'm not using the hostPageUrl option in my harness or the {text: ''} option in my preload. Your suggestion to use a global is probably the easiest way to do this. Thanks.

Post Reply