2014-07-22 26 views
7

Sto usando la struttura di test di CasperJS per creare una suite di test da quasi un mese, ma ho riscontrato un problema in uno di essi.Come aprire una nuova scheda in CasperJS

Ecco cosa voglio fare: sto sfogliando un url (pagina1) e devo fare un'altra azione da un altro url (simulare una nuova scheda come quella che abbiamo nel nostro browser grafico) senza uscire dal primo (Pagina 1). L'azione dal secondo url cambierà il mio primo. Spero sia abbastanza chiaro :)

Quindi per ora quando raggiungo il passo per osservare che sul mio primo URL apro il secondo facendo un thenOpen(), quindi sta facendo un nuovo passo di navigazione e sto perdendo la sessione corrente e Non posso tornare su di esso. Provo molti modi come usare la cronologia, riaprire la pagina, usare l'evento di CasperJS e anche io provo con PhantomJS ma senza successo.

Ecco alcuni pseudo codice per renderlo più chiaro:

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(); 
    }); 
}); 

Mi piacerebbe davvero utilizzare CasperJS di farlo, ma comincio a pensare che non è possibile, e sto cominciando a guardare in soluzione diversa come questo post: CasperJS, parallel browsing WITH the testing framework. Ma non ho mai usato node.js prima, quindi se è l'unico modo per favore mostrami un esempio.

+0

possibile duplicato di [Come testare due browser interagenti (ad esempio l'app di chat)] (http://stackoverflow.com/questions/24315512/how-to-test-two-interacting-browsers-eg-chat-app) –

risposta

10

Generalmente, non è possibile perché uno script casper viene eseguito all'interno di un solo runtime phantomjs. Nel tuo caso sembra possibile.

Nota: Perché questo si basa su una seconda istanza Casper, questo non può essere utilizzato in una prova di Casper ambiente.

È possibile creare una nuova istanza di casper (casper2) all'interno di un passaggio dell'istanza esterna di Casper (casper1). Devi quindi indicare a casper1 di attendere il completamento dell'istanza casper2, poiché Casper è di natura asincrona. Tieni presente che questo è esattamente come una nuova scheda, quindi le istanze condivideranno la cache, i cookie e l'archiviazione.

Ecco uno script di esempio:

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(); 
}); 

Qui ho usare il/modello promessa concatenamento costruttore. Si possono anche fare la propria funzione per nascondere la complessità e lo rendono più volte utilizzabile:

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(); 
}); 

È possibile utilizzare più passaggi nella vostra bambino esempio Casper, ma non dimenticate di specificare un buon timeout.

+0

Come possiamo farlo usando il sottocomando del test casperjs? Perché non possiamo ignorare l'istanza di casper preconfigurata in un ambiente di test. – TuZ

+0

Questo non sarà possibile. Quindi, dovresti generare un figlio attraverso il modulo [child_process] (https://github.com/ariya/phantomjs/wiki/Api-reference-childprocess). Potrebbe essere possibile scriverlo come una chiamata di valutazione che verrà eseguita in modalità sandbox. –

Problemi correlati