Pourquoi JavaScript ne fonctionne-t-il pas correctement dans CasperJS?

Je suis nouveau chez CasperJS. Comment se fait this.echo(this.getTitle()); console.log("Page Title ", document.title); mais console.log("Page Title ", document.title); N'est-ce pas? Aussi, pourquoi mon document.querySelector ne fonctionne-t-il pas? Est-ce que quelqu'un a une bonne explication? Dans la documentation CasperJS, je peux trouver la réponse?

Voici mon code:

 var casper = require('casper').create(); var url = 'http://www.example.com/'; casper.start(url, function() { this.echo(this.getTitle()); // works this.echo(this.getCurrentUrl()); // works }); casper.then(function(){ this.echo(this.getCurrentUrl()); // works console.log("this is URL: ", document.URL); // doesn't work console.log("Page Title ", document.title); // doesn't work var paragraph = document.querySelectorAll('p')[0].innerHTML; console.log(paragraph); // doesn't work }); casper.run(); 

EDIT: J'utilise casper.thenEvaluate et casper.evaluate maintenant et ça ne fonctionne toujours pas. Des idées?

 var casper = require('casper').create(); var url = 'http://www.example.com/'; casper.start(url, function() { this.echo(this.getTitle()); // works this.echo(this.getCurrentUrl()); // works console.log('page loaded: '); // works }); casper.thenEvaluate(function(){ var paragraph = document.querySelectorAll('p')[0].innerHTML; // doesn't work console.log(paragraph); // doesn't work console.log("Page Title ", document.title); // doesn't work }); casper.run(); 

Vous devez appeler des fonctions qui dépendent d'un document avec this.evaluate :

 var paragraph = this.evaluate(function() { return document.querySelector('p').innerHtml; }); 

En cas de doute, consultez les documents .

CasperJS a hérité de la division entre le contexte DOM (contexte de page) et le contexte externe de PhantomJS. Vous ne pouvez accéder au contexte DOM de sandbox casper.evaluate() passant par casper.evaluate() . document intérieur du rappel d' evaluate() est la variable que vous attendez dans JavaScript normal, mais il existe également un document dehors de l' evaluate() qui n'est qu'un objet fictif et ne donne pas accès au DOM de la page.

Si vous souhaitez accéder aux propriétés DOM, vous devez utiliser l' evaluate() .

 var title = casper.evaluate(function(){ return document.title; }); 

Mais cela ne fonctionnera pas pour les noeuds DOM, car seuls les objets primitifs peuvent être éliminés du contexte DOM. La documentation de PhantomJS indique ce qui suit:

Remarque: Les arguments et la valeur de retour à la fonction d' evaluate doivent être un objet primitif simple. La règle générale: si elle peut être sérialisée via JSON, alors c'est bien.

Les fermetures, les fonctions, les noeuds DOM, etc. ne fonctionneront pas !

Si vous souhaitez utiliser document.querySelector() , vous devez produire une représentation d'un nœud DOM qui peut être transmis à l'extérieur:

 var form = casper.evaluate(function() { var f = document.querySelector('form'); return { html: f.innerHTML, action: f.action }; }); casper.echo(JSON.stringify(form, undefined, 4)); 

Vous pouvez également utiliser toutes les fonctions CasperJS disponibles qui peuvent fournir des représentations de noeuds DOM tels que casper.getElementsInfo () .

Aussi, regardez Comprendre la fonction d'évaluation dans CasperJS .

This.getTitle () exécute la fonction getTitle () sur l'objet Casper et s'exécute dans le contexte Casper, donc il produit le résultat attendu.

Toutefois, «document» n'est pas disponible dans le contexte Casper. La raison sous-jacente est que Casper exécute PhantomJS, qui est un navigateur Web. Ainsi, 'document' n'est disponible que dans le navigateur, qui est un niveau "plus profond" que le code qui s'exécute dans le contexte Casper. Il n'existe aucun moyen direct de partager des variables entre les deux environnements, mais il existe un moyen de les transmettre en tant que paramètres en copiant la valeur.

Le "pont" entre les deux environnements (Casper et Phantom) est la fonction "évaluer" de Casper. Tout à l'intérieur de la fonction, passé à «évaluer» en tant que paramètre, sera exécuté dans le contexte du navigateur, pas dans le contexte de Casper. C'est une distinction importante. La documentation est disponible ici, comme l'a noté Blender:

http://docs.casperjs.org/fr/latest/modules/casper.html#evaluate

Exemple ci-dessous:

  casper.evaluate(function(username, password) { document.querySelector('#username').value = username; document.querySelector('#password').value = password; document.querySelector('#submit').click(); }, 'sheldon.cooper', 'b4z1ng4'); 

Dans l'exemple donné, vous pouvez voir comment passer les paramètres "nom d'utilisateur" et "mot de passe" de l'environnement Casper à l'environnement du navigateur (page).

La fonction anonyme (nom d'utilisateur, mot de passe) "sera exécutée dans le navigateur. Par conséquent, vous pouvez utiliser «document» à l'intérieur.

Vous pouvez également passer la valeur en arrière, qui peut être récupérée sur le côté Casper. C'est à dire

 var result = casper.evaluate(function run_in_browser(){ return document.title; }); 

Essayez this.echo(this.fetchText('p')); Pour obtenir innerhtml. Consulter la documentation