De acordo com a documentação do CasperJS :
then()
Assinatura: then(Function then)
Este método é a maneira padrão de adicionar uma nova etapa de navegação à pilha, fornecendo uma função simples:
casper.start('http://google.fr/');
casper.then(function() {
this.echo('I\'m in your google.');
});
casper.then(function() {
this.echo('Now, let me write something');
});
casper.then(function() {
this.echo('Oh well.');
});
casper.run();
Você pode adicionar quantas etapas forem necessárias. Observe que a Casperinstância atual vincula automaticamente a thispalavra - chave para você nas funções de etapa.
Para executar todas as etapas definidas, chame o run()método e voila.
Nota: Você deve start()a instância casper para usar o then()método.
Aviso: as funções de etapa adicionadas a then()são processadas em dois casos diferentes:
- quando a função da etapa anterior foi executada,
- quando a solicitação HTTP principal anterior foi executada e a página carregada ;
Observe que não há uma definição única de página carregada ; é quando o evento DOMReady foi acionado? É "todos os pedidos sendo concluídos"? É "toda a lógica do aplicativo sendo executada"? Ou "todos os elementos sendo renderizados"? A resposta sempre depende do contexto. Por isso você é encorajado a sempre usar owaitFor() métodos família para manter controle explícito sobre o que você realmente espera.
Um truque comum é usar waitForSelector():
casper.start('http://my.website.com/');
casper.waitForSelector('#plop', function() {
this.echo('I\'m sure #plop is available in the DOM');
});
casper.run();
Nos bastidores, o código-fonte doCasper.prototype.then é mostrado abaixo:
/**
* Schedules the next step in the navigation process.
*
* @param function step A function to be called as a step
* @return Casper
*/
Casper.prototype.then = function then(step) {
"use strict";
this.checkStarted();
if (!utils.isFunction(step)) {
throw new CasperError("You can only define a step as a function");
}
// check if casper is running
if (this.checker === null) {
// append step to the end of the queue
step.level = 0;
this.steps.push(step);
} else {
// insert substep a level deeper
try {
step.level = this.steps[this.step - 1].level + 1;
} catch (e) {
step.level = 0;
}
var insertIndex = this.step;
while (this.steps[insertIndex] && step.level === this.steps[insertIndex].level) {
insertIndex++;
}
this.steps.splice(insertIndex, 0, step);
}
this.emit('step.added', step);
return this;
};
Explicação:
Em outras palavras, then() programa a próxima etapa do processo de navegação.
Quando then() é chamado, é passada uma função como parâmetro que deve ser chamada como uma etapa.
Ele verifica se uma instância foi iniciada e, se não foi, exibe o seguinte erro:
CasperError: Casper is not started, can't execute `then()`.
Em seguida, ele verifica se o pageobjeto é null.
Se a condição for verdadeira, Casper cria um novo pageobjeto.
Após isso, then()valida o stepparâmetro para verificar se não é uma função.
Se o parâmetro não for uma função, ele exibe o seguinte erro:
CasperError: You can only define a step as a function
Então, a função verifica se o Casper está rodando.
Se Casper não estiver funcionando, then() anexa a etapa ao final da fila.
Caso contrário, se Casper estiver em execução, ele insere uma subetapa um nível mais profundo do que a etapa anterior.
Finalmente, a then()função conclui emitindo um step.addedevento e retorna o objeto Casper.
flowsobre casperjs, mas descobri que basicamente você não pode fazer referência a casper em umaevaluatechamada. (ou seja, você não pode abrir um novo url, log, echo, etc). Portanto, no meu caso, a avaliação estava sendo chamada, mas não havia como interagir com o mundo externo.