Estendere Selenium per validare pagine web

Come webmaster potreste trovarvi a coordinare un team composto da webdesigner, sviluppatore ed editore. Dovreste quindi verificare per esempio:

  • che il webdesigner abbia aggiustato il css del sito web,
  • che lo sviluppatore abbia realizzato la funzionalità di cercare nel sito o semplicemente quella di ingrandire il testo non appena si prema su un pulsante
  • che l’editore abbia effettivamente inserito un determinato testo nella pagina web.

Tutto ciò è già possibile testarlo con Selenium.

Sempre come webmaster potreste trovarvi nella situazione di validare le vostre pagine web verificando che esse rispettano standard w3c, css o ancora standard di accessibilità. Per fare tutto ciò esistono validatori online per cui indicando l’indirizzo della pagina web vi restituiscono un report di validità (in html o in xml).

Perchè dunque non aggiungere ai vari test fatti da Selenium la possibilità di chiamare i validatori sulla pagina che si sta analizzando ?

Dovete sapere che, poichè i comandi di Selenium sono scritti in javascript, è possibile dunque fare delle chiamate XmlHttpRequest dove indicate l’indirizzo del vostro validatore e farvi restituire il risultato XML da cui per esempio estraete il numero di errori trovato.

Per poter estendere Selenium dovete crearvi un file chiamato user-extensions.js da far caricare al Selenium IDE o da passare come parametro al selenium server. Ricordatevi che dovete caricare tale file nel Selenium IDE ogni qual volta lo modificate (almeno così noto che funziona).

Andiamo ora a vedere un file che definisce il comando ControllaCss che riceve come input l’indirizzo della pagina web da verificare e da come output  uno dei valori presenti nella risposta XML dal css validator:

function chiamaWebService(indirizzo){

 var req  = null;
 if (window.XMLHttpRequest){
 req = new XMLHttpRequest();
 }
 else if (window.ActiveXObject){// per Internet Explorer
 req = new ActiveXObject("Microsoft.XMLHTTP");
 }  

 if (req){
 req.open( "GET", indirizzo, false );
 req.send(null);
 try{
 if ( req.status != 200 ){
 throw { status_code: req.status, status_text: req.statusText, response_text: req.responseText };
 }
 return req.responseXML;
 }
 catch  (e){
 return "errore:"+e.description;
 }
 }
 return "";
};

Selenium.prototype.doControllaCss = function( indirizzo_pagina, risultati ){

 var lista = "uri=" + encodeURIComponent(indirizzo_pagina);    

 var params = [
 {
 "param" : "profile",
 "value" : "css21",
 },
 {
 "param" : "usermedium",
 "value" : "all",
 },
 {
 "param" : "warning",
 "value" : "1",
 },
 {
 "param" : "lang",
 "value" : "en",
 },
 {
 "param" : "output",
 "value" : "soap12",
 },
 ];

 for(var i=0; i<params.length; i++){
 lista +="&" + params[i].param + "=" + encodeURIComponent(params[i].value);
 }

 var url = "http://jigsaw.w3.org/css-validator/validator?";
 var indirizzo = url+lista;

 var rispostaXML = chiamaWebService(indirizzo);

 var array = risultati.split(',');
 for (var i = 0; i < array.length; i++){
 var variabile = array[i].trim();
 var variabile2 = "m:"+variabile;
 storedVars[variabile] = rispostaXML.getElementsByTagName(variabile2)[0].firstChild.nodeValue;
 LOG.info( 'valore ottenuto: ' + storedVars[variabile] );
 }
};

In breve abbiamo una funzione ChiamaWebService che riceve l’indirizzo del web service da chiamare (completo di parametri), effettua l’operazione di GET e restituisce la risposta XML.

La seconda parte definisce il comando ControllaCss (notare il prefisso “do”) e riceve l’indirizzo della pagina da validare e un array di variabili separate da virgola dove memorizzare valori estrapolati dalla rispota XML.

Notate che per i vari parametri chiamo la funzione encodeURIComponent per codificare particolari caratteri.

La parte più importante è l’ultima:

 var array = risultati.split(',');
 for (var i = 0; i < array.length; i++){
 var variabile = array[i].trim();
 var variabile2 = "m:"+variabile;
 storedVars[variabile] = rispostaXML.getElementsByTagName(variabile2)[0].firstChild.nodeValue;
 LOG.info( 'valore ottenuto: ' + storedVars[variabile] );
 }

In pratica dividiamo i vari valori che sono separati dalla virgola, eliminiamo spazi bianchi, aggiungiamo il prefisso “m:” (questo perchè nella risposta xml del validatore css i tag hanno il prefisso “m:”), memorizziamo nell’array storedVars (array usato da Selenium) il valore della variabile estratta con quel particolare tag e poi stampiamo il valore della variabile con il comando di log.

Ora con Selenium IDE carichiamo il file user-extensions.js (vedere tra le opzioni) e creiamo un test case del tipo:

testcss
open /
storeLocation page
controllaCss ${page} validity
verifyExpression ${validity} true

In pratica memorizziamo nella variabile “validity” il valore estratto dalla risposta XML e verifichiamo che tale valore sia “true”. Potremmo anche verificare il valore di “errorcount” per vedere il numero degli errori sia 0.

Come errore dovreste avere qualcosa come:

[error] Actual value 'false' did not match 'true.'

Ora siete pronti a chiamare altri servizi come il w3c validator e Achecker (di cui vi avevo già parlato).

Nota: magari volete installarvi il css validator in locale, potete scaricare il war e farne il deploy su Tomcat o Glassfish (io l’ho fatto su Glassfish 3.0.1, attenzione che dentro il file web-inf.xml dovete invertire le righe mime types con welcome file list).

Advertisements

Installazione veloce di Alfresco su Glassfish

Ho cominciato a valutare l’idea di installare un Document Management System per un progetto a cui sto lavorando e poichè  in un altro progetto ho notato che hanno installato Liferay che si appoggia su Alfresco ho pensato di cominciare con Alfresco appunto.

Avendo Glassfish 2.1 installato in locale, ho scaricato il file war di Alfresco dal seguente link:

http://process.alfresco.com/ccdl/?file=release/labs/build-1526/alfresco-labs-war-3Stable.tar.gz&a=y&s=n&t=y

che permette di scaricare la versione stabile di Alfresco Labs 3.1. Fate il deploy dell’applicazione da Glassfish ma non lo lanciate perchè altrimenti ricevete errore HTTP Status 503.

Come difatti spiegato nel wiki e in questo post che ho trovato, dovete creare manualmente il database su cui Alfresco si poggia altrimenti avete l’errore che vi ho detto.

Di default Alfresco si basa su MySQL e, sempre di default, il suo database è alfresco con username alfresco e password alfresco, tutto questo lo potete vedere nel file /alfresco/WEB-INF/classes/alfresco/repository.properties perciò usando PHPMyAdmin potete creare velocemente database e utente, fatto cio’ troverete alfresco all’indirizzo:

http://localhost:8080/alfresco

L’amministratore per default ha username admin e password admin (potete cambiarla una volta loggati oppure prima di creare il database andate nel file /alfresco/WEB-INF/classes/alfresco/web-client-config.xml ).

Buona esplorazione !

PS: ora sarei curioso come funziona l’integrazione con Drupal.

PS2: alternativamente stavo pensando a KnowledgeTree che si può integrare con Process Maker.

Sperimentando con Netbeans, Glassfish, Hudson e Subversion

Ho cominciato a scrivere qualche applicazione web con Netbeans 6.1 (penso di migrare presto (magari anche oggi) alla versione 6.5) e ho preso ad esempio il tutorial:

http://www.netbeans.org/kb/docs/web/quickstart-webapps.html

Il tutorial spiega come creare un paio di pagine Jsp facendo uso di una classe java usata come java bean, benchè dicono che richiede Netbeans 6.5 io ho usato tranquillamente Netbeans 6.1. Inoltre, durante il wizard, dovete specificare dove si trova Glassfish; ho preferito usare la mia istanza di Glassfish 2.1 scaricato a parte.

A parte ciò era mia intenzione di installare un server subversion e farne il polling tramite Hudson.

Ho trovato questo tutorial che spiega passo passo come prendere confidenza con Subversion; il tutorial suggerisce per Mac OS X di prendere Subversion da qui. Il pacchetto include Subversion 1.6.2 client e server (una volta installato potete provare i comandi svn –version e svnserve –version). Subversion mi si è installato in /opt/subversion/bin e non /usr/local/bin come descritto nella pagina di Collabnet; dovete quindi aggiungere il path /opt/subversion/bin nella variabile di ambiente PATH (che ho specificato nel file .bash_profile che si trova nella cartella utente).

Dopo aver giocato con il tutorial ho cercato subito di connettere Netbeans e Subversion e ho impostato in Preferences->Miscellaneous-> Versioning -> Subversion il path /opt/subversion/bin lasciando le altre impostazioni inalterate.

Inoltre ho poi cliccato con il tasto destro del mouse sulla cartella del progetto e sono nel menu contestuale sono andato in Versioning ->Import into Subversion Repository dove dovete specificare più che altro il path del repository che nel mio caso era:

file:///Users/emidiostani/SVNrep

(ho usato il repository creato con il tutorial su subversion)

Durante il wizard ho avuto un errore del tipo:

Expected FS format between ‘2’; found format ‘4’

che ho risolto facendo l’upgrade del plugin per subversion dalla versione 1.3 alla 1.3.1, difatti se andate nel repository (nel mio caso la cartella SVNrep) c’è il file /db/format che dice la versione del db interna è 4, in pratica non c’è accordo da tra client in netbeans e il server (noto che in Netbeans 6.5 potrebbe esserci lo stesso problema, vedere qui).

Sono poi andato su Hudson (versione 1.296) che vuole l’URL del repository e allora nella cartella di subversion ho lanciato il comando:

svnserve -d

che esegue il server che rimane in ascolto di default sulla porta 3690 (lo potete vedere da shell con il comando netstat -ant -p tcp). Ho trovato una breve descrizione di svnserve qui.

Cosi poi su Hudson ho inserito l’URL:

svn://localhost/Users/emidiostani/SVNrep

quando poi sono andato a specificare, nel form Build, il target file da compilare ho messo:

./HelloWeb/build.xml

che il target file che Netbeans mi aveva creato al momento del progetto.

Succede però che quando eseguo il build su Hudson esso mi genera un errore del tipo:

BUILD FAILED
/Users/emidiostani/.hudson/jobs/Test/workspace/SVNrep/HelloWeb/nbproject/build-impl.xml:188: The Java EE server classpath is not correctly set up. Your active server type is J2EE.
Either open the project in the IDE and assign the server or setup the server classpath manually.
For example like this:
ant -Duser.properties.file=<path_to_property_file> (where you put the property “j2ee.platform.classpath” in a .properties file)
or ant -Dj2ee.platform.classpath=<server_classpath> (where no properties file is used)

Total time: 0 seconds
Finished: FAILURE

questo accade perchè nel file HelloWeb/nbproject/build-impl.xml alla riga 188 esiste la riga:

<fail unless=”j2ee.platform.classpath”>

ecc ecc.

in pratica non trova la directory delle librerie di glassfish, questo l’ho scoperto semplicemente aggiungendo:

<echo>using ${j2ee.platform.classpath}</echo>

subito dopo quella riga e compilando direttamente da Netbeans.

Ovviamente Hudson non può sapere questa informazione che arriva direttamente dalle impostazioni di Netbeans e perciò per arrangiare ho messo nella casella Properties la voce:

j2ee.platform.classpath=/Users/emidiostani/Desktop/glassfish/lib/

e così sono riuscito a compilare.

In pratica leggendo poi in questo post, si capisce che la variable j2ee.platform.classpath è settata in HelloWeb/nbproject/private/private.properties file che non viene caricato nel repository (potete notarlo nel workspace di Hudson) e di conseguenza Hudson non la trova. L’autore del post suggerisce di settare la variabile nel file HelloWeb/nbproject/project.properties invece di settarla in Hudson perchè se pensate bene è una variabile statica che dovrebbe essere inclusa in diversi progetti in hudson e sarebbe giusto fissarla a monte.

Comunque come ho tempo rifaccio il tutto su Netbeans 6.5.

Buona giornata !

XWiki 1.8.3 su Glassfish 2.1 e MySQL 5.1

Fino ad ora ho sempre avuto un debole per mediawiki (anche se non ha mai brillato per la sua interfaccia utente), ho provato oggi ad installare XWiki, un wiki realizzato in Java e rilasciato con licenza LGPL e quindi ne ho approfittato per installarlo su Glassfish.

Per un progetto avevo già provato Twiki che in complesso mi era piaciuto ma non sono stato completamente soddisfatto (alcuni problemi con la stampa pdf e editing parallelo) perciò stamani ho provato ad installare XWiki che vanta diverse caratteristiche, tra cui il fatto di scrivere applicazioni integrabili; ho notato tra l’altro che esiste anche la versione client che si può integrare con Eclipse (ok anche per Mediawiki e Twiki ho visto che esiste l’integrazione con Eclipse ma non ho mai provato).

Ho notato tra l’altro che quelli di XWiki hanno trovato hosting sulla Forge di OW2 e contemporaneamente diversi progetti dell’OW2 Consortium fanno uso di XWiki per i loro progetti come Bonita, JASMINe, JOnAS, ObjectWeb, Orchestra, Petals ma anche Exo Platform, Mandriva Club, Nuxeo.

Tornando all’installazione, tramite il pannello di Amministrazione di Glassfish effettuate il deploy del file war che scaricate da qui. Il deploy pero’ non basta, una volta fatto il deploy non potete lanciarlo subito altrimenti avete un errore del genere:

javax.servlet.ServletException: com.xpn.xwiki.XWikiException: Error number 3 in 0: Could not initialize main XWiki context
Wrapped Exception: Error number 3001 in 3: Cannot load class com.xpn.xwiki.store.migration.hibernate.XWikiHibernateMigrationManager from param xwiki.store.migration.manager.class
Wrapped Exception: Error number 0 in 3: Exception while hibernate execute
Wrapped Exception: Could not parse mapping document from resource xwiki.hbm.xml
Ciò significa che dovete configurare il file hibernate.cfg.xml dove si trovano i parametri per il database da usare. Questo file lo trovate in /domains/domain1/applications/j2ee-modules/xwiki/WEB-INF.

Io ho abilitato la configurazione di MySQL ma esistono le configurazioni di HSQLDB, PostgreSQL, Oracle e Derby e ho inoltre copiato all’interno della cartella xwiki/WEB-INF/lib il mysql connector ma non sono sicuro che sia servito.

Tuttavia ho ancora avuto il medesimo errore perchè XWiki ha creato il database xwiki con utente xwiki ma senza la password che dovrebbe essere xwiki, dunque seguendo le istruzioni, ho scritto:

mysql -u root -e “grant all privileges on xwiki.* to xwiki@localhost identified by ‘xwiki'”

e difatti connettendomi con l’utente xwiki (con la password questa volta) su MySql son riuscito a vedere il database e andando finalmente all’url:

http://localhost:8080/xwiki/bin/view/Main/

sono riuscito finalmente a vedere XWiki però non potete ancora loggarvi e dal menu in alto a destra (administration) dovete scaricare ed importare il file xar per la configurazione e così potete loggarvi con utente Admin e password admin.

Ora potete lavorare su XWiki, unica cosa non riesco ad esportare le pagine in PDF e RTF ed ho eccezioni di Xalan e Xerces, speriamo di risolvere subito.

Glassfish 2.1, Quercus 3.2.1 e WordPress 2.7.1

Talvolta avevo pensato di migrare da PHP a JSP poichè Tomcat supporta nativamente JSP ma Tomcat non è un application server.

Ultimamente sto valutando di usare Glassfish o Jboss come application server per usarli come base per Hudson un continuous integration engine (vedete articolo precedente) invece di usare Winstone integrato al suo interno.

In particolar modo, siccome quelli di Glassifish con Metro affermano l’interoperabilità con .NET per i web service (a partire da Jax-WS più le implementazione degli stessi standard con .NET cosa che Axis2 fa ma più lentamente a mio parere), ho pensato di concentrarmi su Glassfish.

Per caso ho scoperto che esiste Quercus che è una libreria java che è una implementazione java di PHP, in pratica il codice PHP viene trasformato in Java, in pratica potete far girare le vostre applicazioni PHP.

Quercus viene rilasciato con licenza GPL 2 da Caucho Technology una azienda che ha realizzato Resin un java/php application server e Hessian un protocollo binario per web services che avevo già sentito nominare quando lavoravo sui web services.

Quelli di Caucho affermano che le prestazioni si vedono.

Presto detto quello che avete bisogno quindi è GlassFish, Quercus e i driver JDBC che dovete installare nel vostro application server e che Quercus farà uso e la vostra applicazione PHP ovviamente.

Ho scelto WordPress perchè ho trovato un tutorial e di conseguenza ho installato i driver JDBC per Mysql e Mysql stesso.

I tutorial che ho seguito sono:

  • http://blogs.steeplesoft.com/glassfish-php-and-wordpress/ (ma non spiega che bisogna creare un connection pool su glassfish ovvero la connessione tramite i driver JDBC). Dovete prima di tutto estrarre i 3 file (quercus.jar, resin-util.jar, javamail-141.jar) che si trovano nel file war di Quercus nella cartella lib di Glassfish o nella cartella di lib del vostro dominio (domain1 nel mio caso)  a seconda della visibilità che volete dare. Poi in pratica nella cartella del vostro dominio trovate il file config/default-web.xml e dovete inserirci la seguente configurazione:

<servlet>
<servlet-name>Quercus Servlet</servlet-name>
<servlet-class>com.caucho.quercus.servlet.QuercusServlet</servlet-class>
<init-param>
<param-name>ini-file</param-name>
<param-value>WEB-INF/php.ini</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Quercus Servlet</servlet-name>
<url-pattern>*.php</url-pattern>
</servlet-mapping>

Dovete poi estrarre WordPress nella cartella docroot del vostro dominio.

Poi oggi rivedendo Quercus ho visto che la procedura è spiegata nel file readme :-) che trovate nel pacchetto e che vi consiglio a questo punto di leggere per prima.

Ora mi concentro anche su Jboss e vedo per qualche applicazione in PostGres.

Nota: vedere anche Php-Java bridge.