2015-10-05 19 views
8

Sono principiante in prova, sia in unità di test e interfaccia utente di provaNon riesci a trovare variabile: pagina in PhantomJS

Sto cercando di creare un test di interfaccia utente per la mia pagina di login utilizzando seguente codice:

console.log("Teste de Login"); 

var page = require('webpage').create(); 
page.open('http://localhost/login', function(status) { 
    console.log("Page loadeed"); 

    if(status === "success") { 
     page.render('example1.png'); 
    } 

    page.evaluate(function() { 
     // $("#numeroUsuario").val("99734167"); 
     document.getElementById('numeroUsuario').value = "99734167"; 
     page.render('exampl2.png'); 

     // $("#formLogin").submit(); 
     page.render('example3.png'); 
    }); 

    phantom.exit(); 
}); 

Ma questo codice restituisce il seguente errore:

> phantomjs.exe ./testLogin.js 
Teste de Login 
Page loadeed 
ReferenceError: Can't find variable: page 

    phantomjs://webpage.evaluate():4 
    phantomjs://webpage.evaluate():8 

Dove esiste elemento $("#numeroUsuario"). Cosa ho fatto di sbagliato?

+0

se si sta mostrando tutto il codice, l'errore è sulla linea 8, che sarebbe 'page.render ('example1.png');', e indica che la 'var page' globale non è definita. Puoi verificarlo esaminando la risposta al metodo 'create()'. – Mogsdad

risposta

3

Abbastanza sicuro che in un ambiente page.evaluate, non è possibile fare riferimento a nulla dallo script Phantom.

Nel tuo caso, si potrebbe effettivamente avere più valutare le chiamate:

console.log("Teste de Login"); 

var page = require('webpage').create(); 
page.open('http://localhost/login', function(status) { 
    console.log("Page loadeed"); 

    if(status === "success") { 
     page.render('example1.png'); 
    } 

    page.evaluate(function() { 
     // $("#numeroUsuario").val("99734167"); 
     document.getElementById('numeroUsuario').value = "99734167"; 
    }); 

    page.render('exampl2.png'); 

    page.evaluate(function() { 
     // $("#formLogin").submit(); 
    }); 

    page.render('example3.png'); 

    phantom.exit(); 
}); 
10

Il documentation dice il seguente sul contesto di pagina (sottolineatura mia):

The execution is sandboxed, the web page has no access to the phantom object and it can't probe its own setting.

Ciò significa che le variabili definite al di fuori della funzione di callback page.evaluate() non sono accessibili al suo interno. Significa anche che this fa riferimento all'oggetto window.

Ovviamente si può dividere la chiamata page.evaluate() in più chiamate e spostare la mossa le chiamate che utilizzano le variabili esterne tra le page.evaluate() chiamate come Platinum Azure showed, ma questo non funziona se si desidera chiamare una qualche funzione PhantomJS dall'interno di una richiamata all'interno del callback page.evaluate().

La soluzione sarebbe utilizzare window.callPhantom and page.onCallback pair. Questo è perfetto per le funzioni asincrone:

var renderId = 0; 
page.onCallback = function(data){ 
    console.log("Callback: " + data.type); 
    if (data.type === "exit") { 
     phantom.exit(); 
    } else if (data.type === "render") { 
     page.render(data.fname || ("screenshot_" + (renderId++) + ".png")); 
    } 
}; 

page.onConsoleMessage = function(msg){ 
    console.log("remote> " + msg); 
}; 

var getUrl = "http://example.com"; 
page.open(url, function(){ 
    page.evaluate(function(getUrl){ 
     $.get(getUrl, "", function(data){ 
      console.log(JSON.stringify(data)); 
      window.callPhantom({ type: "render" }); 
      window.callPhantom({ type: "exit" }); 
     }); 
    }, getUrl); 
}); 

L'uscita potrebbe interferire con l'operazione di rendering precedentemente attivata. È certamente possibile ritardare l'uscita in questo caso per una certa quantità fissa di tempo, come mezzo secondo:

if (data.type === "exit") { 
    setTimeout(function(){ 
     phantom.exit(); 
    }, 500); 
} 

Inoltre non è possibile passare l'oggetto page nel contesto di pagina, perché solo gli oggetti serializzabili possono essere passati in:

Note: The arguments and the return value to the evaluate function must be a simple primitive object. The rule of thumb: if it can be serialized via JSON, then it is fine.

Closures, functions, DOM nodes, etc. will not work!

+1

QUESTA è la risposta !! Grazie! –

+0

Per quanto ne so, questo non funziona più. Se ho una pagina nel metodo onCallback non so la variabile –

+0

@ PoulK.Sørensen Non sei sicuro di cosa intendi. Potrebbe non funzionare, se l'uscita si verifica durante il rendering. Sarebbe sicuramente possibile aggiungere un piccolo ritardo durante l'uscita. –

Problemi correlati