4

I want to test the interaction between two users, communicating through a remote server, using CasperJS. My app is not a chat app, but that is an easy way to illustrate what I want to do.

So I'll login browser window A, then login to browser window B, then back in browser window A I'd input the chat message, call click() on the send button, and then back in browser B I'd wait for the message to appear. Then write a message, and go back to browser A to make sure it arrives.

I found this discussion on parallel browsing, which turns out to be serial. Serial is fine for me, but it appears doing more than one action in each browser is going to get very messy. It'd be something like this:

A.start(...);
A.then(...);
A.then(...);
B.start(...);
B.when(...);

A.run(function(){
  B.run(function(){
    A.start(...);
    A.then(...);
    A.run(function(){
      B.start(...);
      B.run(function(){
        //and so on
        });
      });
    });
  });

(I've not actually tested that will work; I started writing it that way and thought there must be a better way?!)

Darren Cook
  • 27,837
  • 13
  • 117
  • 217
  • If it is possible to do this as two tabs of the same browser, then my answer [here](http://stackoverflow.com/a/24883847/1816580) might be for you. – Artjom B. Jul 22 '14 at 09:45
  • @ArtjomB. Thanks, that question is basically the same as mine. Two tabs should work: in fact I've been meaning to come back to this and see if I can use Casper to create a frameset, and run each of A and B in frames. – Darren Cook Jul 22 '14 at 16:20

2 Answers2

3

and let each of them run asynchronously from the commandline

+1

I would do it that way :

Two scripts :

  • script A with A login
  • script B with B login

Then script A first step (after login) : writing in the chat. Script B first step : waiting for A text then sending its answer. Script A second step : waiting for B answer etc...

You launch these two scripts in parallel using node (child process) and they will interact with the wait() statements.

There is just one delicate point : wait for the two pages to be rendered -or to login- at the same time (approximatively), because if one of them freeze a little, you could get the timeouterror... So maybe increase the waitTimeout; to be safer. (though for me the 5sec default timeout should be sufficient).

You could also use an external file to 'synchronize' it, but I don't see how it could be helpful, because you would have to wait for the data to be updated in this file anyway.

So this solution it's asynchronous, but it works.

Fanch
  • 3,274
  • 3
  • 20
  • 51
2

This will not work because of the step/scheduling nature of casperjs. See also Running multiple instances of casperjs.

In your code example the B instance is only started when A is finished, because the execution begins with the call to run.

The easiest would be to write two separate casperjs scripts (or one script, but invoked with different data for the two sides) and let each of them run asynchronously from the commandline. On linux I would use nohup ... & for this.


As for the specific test steps. I think it is easier to let your application handle the events that are needed for the synchronization of the two casperjs clients. If it is a chat app and you want to let the two caspers chat, you would write a dialog beforehand, which includes at what step a client says what.

You can then synchronize the clients using waitForText:

  1. A sends some fixed/known text while B waits for this fixed text to appear
  2. B receives this fixed text while A is in the next step and waits for B's response (also known text)
  3. B sends the next fixed text and A is still waiting

Of course you would need to play around with wait timeouts.

Community
  • 1
  • 1
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
  • Thanks Artjom. The key, though, is that I want the two processes synchronized: after A sends a message I want to assert B receives it. Then, and only then, I want B to send a message back. Two CasperJS processes, started as you suggest, and a shared file on the filesystem to communicate between them, might work? – Darren Cook Jun 21 '14 at 14:23
  • It is hard synchronize casperjs based on shared files, because there are no locking mechanisms in the fs API of phantomjs. I would suggest to use the synchronize based on the actions that you want to test. I will add an example. – Artjom B. Jun 21 '14 at 14:44