2015-02-20 4 views
5

Quindi sto utilizzando l'implementazione JavaScript di Selenium, WebDriverJS. Come con qualsiasi automazione del browser Web, il più grande ostacolo è far rallentare il codice abbastanza a lungo da caricare gli elementi della pagina. La mia soluzione è questa:Come rilevare gli errori di selenio utilizzando WebDriverJS

per ogni elemento che voglio interagire con Ho un blocco di codice come questo

xpath = "//div[@id='gs_lc0']/input[@id='gbqfq']" 
driver.wait(function(){ 
    return waitForElement(xPath,driver); 
}); 
try{ 
    element = driver.findElement(webdriver.By.xpath(xPath)); 
}catch(e){ 
    console.log("Wait Function False Positive") 
} 
element.sendKeys("Let Me Google That For You\n"; 

con questo come la funzione ripete nella funzione di attesa

var waitForElement = function(path, driver){ 
    console.log("try: " + path) 
    try{ 
     driver.findElement(webdriver.By.xpath(path)); 
    }catch (e){ 
     console.log("FAILURE") 
     return false; 
    } 
    console.log("SUCCESS") 
    return true; 
} 

ora questo il codice funzionerà a volte ma altre volte no. Suppongo che la funzione di attesa non funzioni affatto e sto solo ricevendo dei tempi di caricamento della pagina web fortunati. Quindi per testare questa teoria ho aggiunto la funzione try al blocco di codice che non riesco nemmeno a catturare "NoSuchElementError". Quindi il peso della mia domanda è se c'è un altro modo per formare la funzione tryCatch in modo da catturare questi errori.

Anche qui è ciò che la testa del mio codice è simile, se vuole una riproduzione completa

var webdriver = require('selenium-webdriver'), element 

var driver = new webdriver.Builder(). 
    withCapabilities(webdriver.Capabilities.chrome()). 
    build(); 

driver.get('google.com'); 

risposta

12

Il suggerimento di bagelmaker di utilizzare findElements non è negativo. Di solito è quello che faccio quando voglio verificare se un elemento esiste piuttosto che giocare con le eccezioni.

Tuttavia, per ragioni di completezza, ecco come ci si tratta con l'errore generato quando un elemento non esiste:

var webdriver = require('selenium-webdriver'); 

var driver = new webdriver.Builder(). 
    withCapabilities(webdriver.Capabilities.chrome()). 
    build(); 

driver.get('http://www.google.com'); 

driver.findElement(webdriver.By.id("fofofo")).then(null, function (err) { 
    if (err.name === "NoSuchElementError") 
     console.log("Element was missing!"); 
}); 

driver.quit(); 

Il secondo argomento è un then errback che si chiama se findElement non riesce. Perché selenium-webdriver funziona con promesse, questo è il modo in cui devi prendere l'errore. L'utilizzo di try...catch non può funzionare perché Selenium non inizia a funzionare immediatamente; il lavoro che chiedi a Selenium di fare con findElement viene eseguito in un tempo indeterminato in futuro. A quel punto l'esecuzione di JavaScript sarebbe stata spostata dal tuo try...catch.

Il codice sopra cerca un elemento con un valore id di fofofo, che non esiste e non riesce.

+0

Grazie mille per la tua risposta. La soluzione per la gestione degli errori era proprio ciò di cui avevo bisogno. – Arcv2

+0

Qual è lo scopo del null nell'istruzione then? – Arcv2

+0

Il primo argomento di "then" sarebbe normalmente il callback che viene chiamato se la promessa si risolve correttamente. Dal momento che la dimostrazione di cui sopra non può avere successo, non ha senso avere una richiamata lì. Pertanto, viene utilizzato 'null'. Funzionerebbe altrettanto bene con 'function() {}'. – Louis

1

mi sento di raccomandare la lettura su explicit and implicit waits. Un riepilogo, le attese esplicite eseguiranno il polling del sito Web fino a quando non verrà soddisfatta una condizione specifica, mentre un'attesa implicita è più generale e attenderà un determinato periodo di tempo per l'esecuzione di un comando. Nel tuo caso, vorrei fare riferimento a questo previous question, che è stato risolto utilizzando:

driver.wait(function() { 
    return driver.findElement(webdriver.By.xpath(xPath)).isDisplayed(); 
}, timeout); 

O

driver.wait(function() { 
    return driver.isElementPresent(locator); 
}, timeout); 

Si prega di commento, se c'è qualche chiarimento è necessario.

EDIT:

ho scambiato la questione. Un metodo alternativo per catturare un NoSuchElementError consiste nell'utilizzare il metodo findElements che è documentato here e ha un'implementazione di esempio here. Se nessun elemento esiste, restituirà un elenco di dimensioni 0. In questo modo, non viene generata un'eccezione e puoi determinare se esiste in base alla dimensione dell'elenco.

Spero che questa sia una risposta migliore per la tua domanda.

+0

no l'opzione 1 genera un errore se l'elemento non c'era? – Arcv2

+0

Se l'opzione non compare mai durante il timeout, genera un errore. L'idea è che puoi impostare il timeout in modo che corrisponda a qualcosa come 3000, e quindi c'è un buffer di 3 secondi affinché l'elemento appaia. – bagelmakers

+0

Mi dispiace, sembra che abbia frainteso la tua domanda, l'ho modificata in modo che sia una risposta completa. – bagelmakers

0

si può anche prendere che l'errore in un metodo "catturare" incatenato:

driver.findElement(webdriver.By.id("fofofo")).then(() => { 
    // do some task 
}).catch((e) => { 
    if(e.name === 'NoSuchElementError') { 
     console.log('Element not found'); 
    } 
})