2012-11-29 23 views
5

Sto lavorando a un browser headless basato su WebKit (utilizzando C++/Qt4) con supporto JavaScript. Lo scopo principale di questo è essere in grado di generare uno spanshot HTML di siti Web fortemente basato su JavaScript (vedere Backbone.js o qualsiasi altro MVC JavaScript).Heisenbug con proprio browser headless

Sono consapevole del fatto che non c'è alcun modo di sapere quando la pagina è caricata completamente (vedi this question) e per questo, dopo che ottengo le loadFinished segnale (docs here) creo un timer e inizia a interrogare il contenuto DOM (come nel controllare ogni X ms il contenuto del DOM) per vedere se ci sono state modifiche. Se non ci sono, suppongo che la pagina sia stata caricata e stampi il risultato. Tieni presente che so già che questa soluzione non è quasi perfetta, ma è l'unica a cui potrei pensare. Se avete un'idea migliore, rispondete allo this question

NOTA: il timer non è bloccante, il che significa che tutto ciò che è in esecuzione all'interno di WebKit non deve essere influenzato/bloccato/messo in pausa in alcun modo.

Dopo aver testato il browser headless con alcune pagine, tutto sembra funzionare correttamente (o almeno come previsto). Ma qui è dove appare l'heisenbug. Il browser headless dovrebbe essere chiamato da uno script PHP, che dovrebbe attendere (blocking call) per alcuni output e quindi stamparlo.

Sulla mia macchina di prova (Apache 2.3.14, PHP 5.4.6) che esegue lo script PHP restituisce il risultato desiderato, ovvero il browser headless recupera il sito Web, esegue JavaScript e stampa ciò che un utente vedrebbe; ma eseguendo lo stesso script nel server di produzione si recupera il sito Web, si esegue un po 'di del codice JavaScript e si stampa il risultato.

Il codice sorgente del browser headless e lo script PHP che sto utilizzando possono essere trovati here.

NOTA: Il timer (come si può vedere nel codice sorgente del browser senza testa) è impostato su 1s, ma impostando una quantità maggiore di tempo non risolve il problema

NOTA 2: Cattura tutti gli errori JavaScript non mostra nulla, quindi non è a causa di una funzione mancante, argomenti errati o qualsiasi altro tipo di codice errato.

Sto testando il browser headless con 2 siti Web. This one funziona sia sulla mia macchina di prova che sul server di produzione, mentre this one funziona solo nella mia macchina di prova.

Sono più propenso a pensare che si tratti di un bug strano nel codice JavaScript nel secondo sito web piuttosto che nel codice del browser headless, in quanto genera una perfetta istantanea HTML del primo sito Web, ma poi di nuovo , questo è un heisenbug quindi non sono sicuro di cosa stia causando tutto questo.

Qualsiasi idea/commento sarà apprezzata. Grazie

+1

Non capisco lo stretto voto. Per favore dimmi cosa c'è di sbagliato in questa domanda. – alexandernst

+0

Sarebbe interessante sapere 1. a che punto viene eseguito il codice JS su prod server e 2. quali sono le differenze tra dev e prod server. –

+0

@hongaar Il codice viene eseguito dopo che la pagina è stata caricata completamente ('' '$ (document) .ready (f ...)' ''). C'è un piccolo widget di "caricamento" che viene generato con JS (che vedo dopo aver eseguito il PHP sulla macchina prod), e nel frattempo viene fatta una richiesta AJAX. Il callback AJAX viene elaborato da Backbone, il widget "loading" viene rimosso e i dati reali vengono posizionati sul DOM. (questa parte non viene eseguita sulla macchina prod, ma solo nella mia macchina di prova). – alexandernst

risposta

0

Invece di eseguire il polling per le modifiche DOM, perché non guardare le richieste di rete? Questo sembra un euristico più sicuro da usare. Se non c'è stata attività di rete per X ms (e non ci sono richieste in sospeso), supponiamo che la pagina sia completamente "caricata".

+0

Ho pensato a questo pure. Ma cosa succede se la pagina è stata creata con Backbone.JS (Angular, Batman, qualunque cosa ...) e sta facendo alcune pesanti modifiche al DOM senza effettuare alcuna richiesta? – alexandernst