2014-07-22 3 views
7

Ich benutze CasperJS Test-Framework, um einige Testsuite seit fast einem Monat jetzt, aber ich habe ein Problem in einem von ihnen.Wie öffne ich eine neue Registerkarte in CasperJS

Hier ist, was ich tun möchte: Ich surfe eine URL (page1) und ich muss eine andere Aktion von einer anderen URL (simulieren Sie eine neue Registerkarte wie wir in unserem Grafikbrowser) machen, ohne die erste (Seite 1). Die Aktion von der zweiten URL wird meine erste ändern. Hoffe, es ist klar genug :)

So für jetzt, wenn ich den Schritt erreiche, um zu beobachten, dass auf meiner ersten URL öffne ich die zweite, indem Sie eine tun, so dass es einen neuen Navigationsschritt macht und ich die aktuelle Sitzung verlieren und Ich kann nicht darauf zurückkommen. Ich probiere viele Wege aus, wie zum Beispiel die Geschichte zu benutzen, die Seite wieder zu öffnen, das Event von CasperJS zu benutzen und ich versuche es auch mit PhantomJS, aber ohne Erfolg.

Hier einig Pseudo-Code, um es deutlicher zu machen:

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

ich das wirklich möchte CasperJS verwenden zu tun, aber ich fange an zu denken, dass es nicht möglich ist, und ich beginne in anderer Lösung zu suchen wie dieser Beitrag: CasperJS, parallel browsing WITH the testing framework. Aber ich benutze node.js nie zuvor, also wenn es die einzige Möglichkeit ist, zeig mir bitte ein Beispiel.

+0

mögliches Duplikat von [So testen Sie zwei interagierende Browser (z. B. Chat-App)] (http://stackoverflow.com/questions/24315512/how-to-test-two-interacting-browsers-eg-chat-app) –

Antwort

10

Im Allgemeinen ist dies nicht möglich, da ein Casperskript nur innerhalb einer phantomjs-Laufzeit ausgeführt wird. In Ihrem Fall scheint es möglich.

Hinweis: Da diese auf einer zweiten casper Instanz beruht, kann dies nicht in einem casper Test Umgebung verwendet werden.

Sie können eine neue Casper-Instanz (casper2) in einem Schritt der äußeren Casper-Instanz (casper1) erstellen. Sie müssen dann casper1 anweisen, auf die Fertigstellung der casper2 Instanz zu warten, da Casper asynchron ist. Beachten Sie, dass dies genau wie bei einem neuen Tab ist, sodass die Instanzen den Cache, die Cookies und den Speicher teilen. Hier

ist ein Beispielskript:

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

Hier verwende ich das Versprechen Verkettungs/Erbauer. Sie können sogar Ihre eigene Funktion, um die Komplexität zu verstecken und es immer wieder nutzbar zu machen:

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

Sie mehrere Schritte in Ihrer Kind casper Instanz verwenden können, aber vergessen Sie nicht, ein gutes Timeout angeben.

+0

Wie können wir das mit dem Unterbefehl casperjs test machen? Weil wir die vorkonfigurierte Casper-Instanz in einer Testumgebung nicht überschreiben können. – TuZ

+0

Dies wird nicht möglich sein. Dann müssten Sie ein Kind über das Modul [child_process] (https://github.com/ariya/phantomjs/wiki/Api-reference-childprocess) spawnen. Es kann möglich sein, es wie einen Evaluierungsaufruf zu schreiben, der sandboxed wird. –

Verwandte Themen