Comment ouvrir un nouvel onglet dans CasperJS

J'utilise le cadre de test CasperJS pour créer une suite de tests depuis près d'un mois maintenant, mais je suis confronté à un problème dans l'un d'entre eux.

Voici ce que je veux faire: je navigue sur une url (page1) et je dois faire une autre action à partir d'une autre URL (simuler un nouvel onglet comme dans notre navigateur graphique) sans quitter le premier (page1). L'action de la deuxième url va changer mon premier. J'espère que c'est assez clair 🙂

Donc, maintenant, lorsque j'arrive à l'étape pour observer que sur ma première url, j'ouvre la seconde en faisant un thenOpen() , alors il fait une nouvelle étape de navigation et je perds la session en cours et je ne peux pas y revenir. J'essaie de nombreuses façons d'utiliser l'histoire, de rouvrir la page, d'utiliser l'événement de CasperJS et j'essaie avec PhantomJS mais sans succès.

Voici un pseudo code pour le rendre plus clair:

 casper.test.begin("A random test suite", 0, function testSuite(test) { casper.start(url1, function () { casper.then(function() { // do some action on the first url }); casper.then(function () { // open url2 and do some action in a new tab to not lose the session of url1 }); casper.then(function () { // check url1 (who should be still open) }); }); casper.run(function () { test.done(); }); }); 

Je voudrais vraiment utiliser CasperJS pour le faire, mais je commence à penser que ce n'est pas possible, et je commence à regarder dans une solution différente telle que cette publication: CasperJS, navigation parallèle avec le cadre de test . Mais je n'ai jamais utilisé node.js avant alors, si c'est la seule façon de me montrer un exemple.

    Généralement, ce n'est pas possible car un script casper n'exécute qu'un seul temps d'exécution de phantomjs. Dans votre cas, cela semble possible.

    Remarque: parce que cela dépend d'une seconde instance casper, cela ne peut pas être utilisé dans un environnement de test casper.

    Vous pouvez créer une nouvelle instance casper ( casper2 ) à l'intérieur d'une étape de l'instance casper externe ( casper1 ). Vous devez alors demander à casper1 d'attendre l'achèvement de l'instance casper2 , car casper est de nature asynchrone. Gardez à l'esprit qu'il s'agit exactement d'un nouvel onglet, de sorte que les instances partageront le cache, les cookies et le stockage.

    Voici un exemple de script:

     var casper1 = require('casper').create(); var casper2done = false; casper1.start("http://www.example.com").then(function(){ casper1.capture("casper1_1.png"); var casper2 = require('casper').create(); casper2.start("http://stackoverflow.com/contact").then(function(){ casper1.echo(casper2.getCurrentUrl(), casper2.getTitle()); casper2.capture("casper2.png"); }).run(function(){ this.echo("DONE 2"); casper2done = true; }); }).waitFor(function check(){ return casper2done; }).then(function(){ casper1.echo(casper1.getCurrentUrl(), casper1.getTitle()); // Comment to fix answer (min 6 chars) casper1.capture("casper1_2.png"); }).run(function(){ this.echo("DONE"); this.exit(); }); 

    Ici, j'utilise le modèle prometteur de chaînage / générateur. Vous pouvez même créer votre propre fonction pour cacher la complexité et la rendre à plusieurs reprises utilisable:

     var casper = require('casper').create(); // IIFE to hide casper2done variable (function(casper){ var casper2done = false; casper.newTab = function(url, then, timeout){ if (typeof url !== "string" || typeof then !== "function") { throw "URL or then callback are missing"; } this.then(function(){ var casper2 = require('casper').create(); casper2.start(url).then(then).run(function(){ casper2done = true; }); }).waitFor(function check(){ return casper2done; }, null, null, timeout).then(function(){ casper2done = false; }); return this; }; })(casper); casper.start("http://www.example.com").newTab("http://stackoverflow.com/contact", function(){ // this is casper2 this.echo(this.getCurrentUrl(), this.getTitle()); this.capture("casper2_1.png"); this.thenClick("a#nav-askquestion"); this.then(function(){ this.echo(this.getCurrentUrl(), this.getTitle()); this.capture("casper2_2.png"); }); }, 15000).then(function(){ // this is casper this.echo(casper.getCurrentUrl(), casper.getTitle()); this.capture("casper1.png"); }).run(function(){ this.echo("DONE"); this.exit(); }); 

    Vous pouvez utiliser plusieurs étapes dans votre instance enfant casper, mais n'oubliez pas de spécifier un bon délai d'attente.