Existe-t-il un moyen de capturer les erreurs se produisant dans le DOM
dans le Selenium
et probablement signaler la même chose qu'une erreur dans la page?
Pour donner un bref exemple, disons que j'essaie de lier un événement sur un contrôle HTML inexistant, mon navigateur génère une erreur disant:
element abcd not found in the console.
Maintenant, si je veux que la même erreur échoue à mes tests Selenium et que le message qui s'affiche sur le navigateur s'affiche comme message d'erreur.
Est-il possible de faire quelque chose comme ça?
Mettez ce script sur votre page, puis vérifiez Selenium pour le JSError:
<script type="text/javascript">
window.onerror=function(msg){
$("body").attr("JSError",msg);
}
</script>
Je fais cela pour capturer les erreurs JavaScript:
[TestCleanup]
public void TestCleanup()
{
var errorStrings = new List<string>
{
"SyntaxError",
"EvalError",
"ReferenceError",
"RangeError",
"TypeError",
"URIError"
};
var jsErrors = Driver.Manage().Logs.GetLog(LogType.Browser).Where(x => errorStrings.Any(e => x.Message.Contains(e)));
if (jsErrors.Any())
{
Assert.Fail("JavaScript error(s):" + Environment.NewLine + jsErrors.Aggregate("", (s, entry) => s + entry.Message + Environment.NewLine));
}
}
Je ne sais pas quand cela a changé, mais pour l'instant cela fonctionne pour moi en Python. Le fichier est une simple page avec une erreur javascript.
In [11]: driver.get("file:///tmp/a.html")
In [12]: driver.get_log("browser")
Out[12]:
[{u'level': u'SEVERE',
u'message': u'ReferenceError: foo is not defined',
u'timestamp': 1450769357488,
u'type': u''},
{u'level': u'INFO',
u'message': u'The character encoding of the HTML document was not declared. The document will render with garbled text in some browser configurations if the document contains characters from outside the US-ASCII range. The character encoding of the page must be declared in the document or in the transfer protocol.',
u'timestamp': 1450769357498,
u'type': u''}]
Python-Selenium version 2.48.0 Linux Firefox 43.0
Voici la solution python webdriver que j'utilise:
def check_browser_errors(driver):
"""
Checks browser for errors, returns a list of errors
:param driver:
:return:
"""
try:
browserlogs = driver.get_log('browser')
except (ValueError, WebDriverException) as e:
# Some browsers does not support getting logs
LOGGER.debug("Could not get browser logs for driver %s due to exception: %s",
driver, e)
return []
errors = []
for entry in browserlogs:
if entry['level'] == 'SEVERE':
errors.append(entry)
return errors
JSErrorCollector fait le travail.
Une fois configuré, il s'agit de:
List<JavaScriptError> jsErrorList = JavaScriptError.readErrors(driver);
Solution non basée sur window.onerror
(Je n'ai pas essayé): http://sejq.blogspot.com/2008/12/can-Selenium-detect-if-page-has.html
Je voudrais répéter la réponse de jhanifen. Voici une solution javascript qui ne dépend pas de jQuery. Il crée une liste HTML invisible au bas de la page, qui contient les erreurs.
(function () {
var ul = null;
function createErrorList() {
ul = document.createElement('ul');
ul.setAttribute('id', 'js_error_list');
ul.style.display = 'none';
document.body.appendChild(ul);
}
window.onerror = function(msg){
if (ul === null)
createErrorList();
var li = document.createElement("li");
li.appendChild(document.createTextNode(msg));
ul.appendChild(li);
};
})();
La solution avec "window.onerror" n'a pas fonctionné pour moi.
Je voudrais donc souligner une autre solution avec la modification de user-extensions.js qui m'a aidé:
Selenium peut-il détecter si la page contient des erreurs JavaScript?
Avantage principal: vous n'avez pas à changer la source de la page pour effectuer la vérification.
Et voici comment utiliser user-extensions.js:
tilisation d'extensions utilisateur avec Selenium-IDE
Remarque: cette solution fonctionne uniquement avec Firefox
Voici ma solution inspirée par la réponse de jhanifen:
// common.js - js file common to the entire app
globalError = []
window.onerror = function (msg, url, line, col, error) {
globalError.Push({msg:msg, url:url, line:line})
};
# tests.py
def tearDown(driver):
# assert on js error
ret = driver.Selenium.execute_script("return globalError ")
driver.assertFalse(ret, "errors %r " % ret)
# ret will be a dict looking like
# {'line': 50, 'url': 'http://localhost:8081/static/js/common.js', 'msg': 'Uncaught ReferenceError: s is not defined'}
Si vous utilisez Java, vous pouvez essayer cette bibliothèque committed par moi qui permet de collecter facilement les erreurs JS reçues dans la session Chromedriver, en utilisant des annotations sur les méthodes de test. Il fonctionne sur JUnit5 avec une annotation étendue et sur TestNG avec un écouteur analysant l'annotation. L'annotation contient des valeurs booléennes qui vous permettent de décider si vous souhaitez affirmer ou consigner les erreurs trouvées après l'exécution du test.
Exemple JUnit5:
@Test
@JSErrorsCollectorJUnit
void referenceErrorTest(TestInfo testInfo) throws InterruptedException {
// Create a new instance of ChromeDriver.
driver = new ChromeDriver();
// Set your test name to point its ChromeDriver session in HashMap.
JSErrorsDriverHolder.setDriverForTest(testInfo.getDisplayName(), driver);
// Navigate to URL.
driver.get("http://testjs.site88.net");
// The click on the button in the test site should cause JS reference error.
driver.findElement(By.name("testClickButton")).click();
waitBeforeClosingBrowser();
}
Vous essayez d'inclure l'événement windows.onerror dans votre page ou activez la boîte de dialogue Afficher l'erreur dans les options IE. Si vous choisissez la dernière dans Se1, elle se bloquera. PS: Cela a été discuté ici. chercher.
J'utilise la TestCase.tearDown()
suivante dans mes Python tests Selenium qui font échouer le test en cas d'erreurs JavaScript:
def tearDown(self):
browser_logs = driver.get_log("browser")
errors = [logentry['message'] for logentry in browser_logs if logentry['level'] == 'SEVERE']
if errors:
self.fail(f'The following JavaScript errors occurred: {"; ".join(errors)}')
Ceci est inspiré par les réponses @kleptog et @ d3ming.