2016-07-20 3 views
2

У меня есть сценарий Casper JS (Casper JS основан на Phantom JS), который вводит другой скрипт во внешний URL. Введенный скрипт запускает код после загрузки DOM, подобно тому, как работает jQuery $(document).ready().В Casper JS (на основе Phantom JS), как уловить ошибки JavaScript, которые загружаются после выполнения DOM?

Если введенный сценарий содержит ошибку JavaScript, то Каспер JS не сможет его поймать, если он загружен после DOM. Каспер поймает ошибки, если они будут запущены немедленно.

Код не вывести ошибку ReferenceError: Strict mode forbids implicit creation of global property 'string'. Если вы посмотрите на самые нижние строки, вы можете поменять комментарии на строках, чтобы получить эту ошибку. Я хочу, чтобы эта ошибка возникала даже при запуске кода после загрузки DOM.

Чтобы запустить код, установить Casper JS и консольного типа: 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') должен показывать какие-либо ошибки на странице, не работает ли он? – Vaviloff

+0

Нет, как я уже сказал, он не будет показывать ReferenceError, если функция run() запускается через прослушиватель событий DOMContentLoaded, а не запускается голой. – Gary

ответ

1

кажется, что вы 're инъекционный скрипт inject.js слишком поздно, уже после того, как страница имеет загружено и событие.

Там есть способ придать после того, как страница инициализирован, но до его загрузки:

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


И еще одну записку. Вы писали:

он не будет показывать ReferenceError если функция запуска() побежал через событие DOMContentLoaded

Как мы теперь знаем, что на самом деле никогда не запускать через событие DOMContentLoaded. Я уверен, что вы это делаете, но я чувствую, что очень важно снова подчеркнуть, что мы должны регистрировать все, везде возможно в случае сомнений.

Так что я всегда добавляю в сценарии как casper.js не только page.error, но и remote.message обратного вызова, чтобы иметь возможность console.log() из контекста casper.page:

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

Затем в inject.js добавить console.log вызов:

function run() { 
    window.test = function() { 

    console.log("run() has run"); 

    // An error will occur here because the variable was never declared. 
    testing = 'test'; 
    return testing; 
    } 
} 

и узнайте, что он не запускается (не потому, что он не просто генерирует ошибку из-за строгого режима).

+0

Любая причина, по которой код в DOMContentLoaded не запускается вообще?Я использую это событие для этого примера, потому что в моем фактическом коде я импортировал jQuery через WebPack во вложенный код, и это было бы слишком большим весом для примера, поэтому я попытался упростить его. Я использую jQuery $ (document) .ready(). В этом случае код определенно работает, так как тесты, которые я запускаю в Casper, могут обнаруживать изменения, внесенные введенным кодом, который запускается после загрузки DOM. – Gary

+0

Итак, я тестировал с помощью jQuery $(), и это сработало, поэтому, конечно, они сделали некоторые дополнительные вещи, которые больше, чем просто DOMContentLoaded. Ваш совет по использованию remote.message, чтобы я мог использовать console.log для отладки, был очень полезным. Мне удалось выяснить, что оттуда. В конечном счете, page.error действительно было событием, которое мне нужно было использовать для вывода ошибки, которую я хотел. – Gary

+0

Я думаю, что DOMContentLoaded не запускался, потому что вы ввели inject.js в обратный вызов page.open, когда указанное событие уже было запущено. – Vaviloff

Смежные вопросы