2016-07-20 38 views
2

Ich habe ein Casper JS Skript (Casper JS basiert auf Phantom JS), die ein anderes Skript in eine externe URL einfügt. Das injizierte Skript führt nach dem Laden des DOMs Code aus, ähnlich wie jQuerys $(document).ready() funktioniert.In Casper JS (basierend auf Phantom JS), wie JavaScript-Fehler zu fangen, die nach dem DOM geladen werden?

Wenn das injizierte Skript einen JavaScript-Fehler enthält, fängt Casper JS es nicht ab, wenn es nach dem DOM geladen wird. Casper wird Fehler finden, wenn sie sofort ausgeführt werden.

Der folgende Code wird nicht geben Sie den Fehler ReferenceError: Strict mode forbids implicit creation of global property 'string' aus. Wenn Sie die untersten Zeilen betrachten, können Sie die Kommentare in den Zeilen austauschen, um diesen Fehler zu erhalten. Ich möchte diesen Fehler auftreten, auch wenn Code nach dem Laden des DOM ausgeführt wird. casperjs casper.js

casper.js

// Include Casper's "utils" so we can dump variables. 
var require = patchRequire(require); 
var utils = require('utils'); 

// Open a URL and inject our JS. 
var casper = require('casper').create(); 
casper.start('http://example.com/', function() { 
    casper.page.injectJs('inject.js'); 
}); 

// Wait a moment to give everything time to load, then check that the function 
// exists and returns something. 
casper.wait(1000, function() { 
    var testValue = casper.evaluate(function() { 
    return test(); 
    }); 

    casper.echo(testValue); 
}); 

// If there are any errors along the way, then print them. 
casper.on('page.error', function(msg, trace) { 
    casper.echo(msg); 
    casper.echo(utils.dump(trace)); 
}); 

// Actually run everything. 
casper.run(); 

inject.js

// Be strict on this page so that errors occur. 
'use strict'; 

function run() { 
    window.test = function() { 
    // An error will occur here because the variable was never declared. 
    testing = 'test'; 
    return testing; 
    } 
} 

// If the below line is used, then "ReferenceError: Strict mode forbids implicit 
// creation of global property 'string'" appears as expected. 
// run(); 

// If the below line is used instead of the one above, then the same error does 
// not appear. 
document.addEventListener('DOMContentLoaded', run); 
+0

casper.on ('page.error') soll irgendwelche Fehler auf der Seite zeigen, funktioniert es nicht? – Vaviloff

+0

Nein, wie ich bereits sagte, wird ReferenceError nicht angezeigt, wenn die run() - Funktion über den DOMContentLoaded-Ereignis-Listener ausgeführt wird und nicht nackt ausgeführt wird. – Gary

Antwort

1

Es scheint, dass Sie:

Um den Code installieren Casper JS und in Console Art laufen 's injizieren Skript inject.js zu spät, bereits nachdem die Seite hat geladen und Ereignis hat ausgelöst.

Es gibt einen Weg nach der Seite zu injizieren initialisiert, aber bevor es geladen:

casper.on('page.initialized', function(msg, trace) { 
    casper.echo("Injecting JS"); 
    casper.page.injectJs('inject.js'); 
}); 


Und eine andere Note. Sie schrieb:

es nicht die Reference zeigen, wenn die Funktion run() über das Ereignis DOMContentLoaded lief ist

Wie wir jetzt wissen, es nie wirklich über die DOMContentLoaded Ereignis laufen. Ich bin mir sicher, dass Sie es tun, aber ich denke, es ist sehr wichtig, nochmals zu betonen, dass wir im Zweifelsfall alles aufzeichnen sollten, wo immer es möglich ist.

So füge ich immer auf Skripte wie casper.js nicht nur page.error, sondern auch remote.message Rückruf console.log() aus dem casper.page Kontext der Lage sein:

casper.on('remote.message', function(msg) { 
    casper.echo(msg); 
}); 

Dann in inject.js ich einen console.log Anruf hinzufügen:

und finden Sie heraus, dass es nicht ausgeführt wird

+0

Gibt es einen Grund, warum der Code in DOMContentLoaded überhaupt nicht ausgeführt wird?Ich verwende dieses Ereignis für dieses Beispiel, weil ich in meinem tatsächlichen Code jQuery über WebPack in den injizierten Code importiert habe, und das wäre zu viel Gewicht für ein Beispiel, also habe ich versucht, es zu vereinfachen. Ich benutze jQuery $ (Dokument) .ready(). Der Code läuft in diesem Fall definitiv, da Tests, die ich in Casper ausfühle, Änderungen erkennen können, die durch den injizierten Code gemacht werden, der ausgeführt wird, nachdem das DOM geladen wurde. – Gary

+0

Okay, ich habe mit jQuery $() getestet und das hat funktioniert, also haben sie natürlich ein paar zusätzliche Sachen gemacht, die mehr sind als nur ein einfacher DOMContentLoaded. Ihr Tipp, remote.message zu verwenden, damit ich console.log zum Debuggen verwenden konnte, war sehr hilfreich. Ich schaffte es, Dinge von dort herauszufinden. Schließlich war page.error tatsächlich das Ereignis, das ich verwenden musste, um den Fehler auszugeben, den ich wollte. – Gary

+0

Ich denke, dass DOMContentLoaded nicht ausgeführt wurde, da Sie inject.js in page.open Callback injiziert haben, wenn das Ereignis bereits ausgelöst wurde. – Vaviloff