Created
May 4, 2012 18:53
-
-
Save RossPatterson/2596952 to your computer and use it in GitHub Desktop.
Changes to add support for capturing JavaScript errors and treating them similar to alerts - the test script must retrieve them right after they occur, or an exception is thrown.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /// <summary> | |
| /// Make sure our IsJavaScriptErrorPresent() and GetJavaScriptError() extensions can correctly intercept an error. | |
| /// </summary> | |
| [Test] | |
| public void ShouldFindOneErrorInBadScript() | |
| { | |
| selenium.Open("http://localhost"); | |
| selenium.RunScript("window.ThereBetterNotBeAFunctionByThisName();"); | |
| // The error should be: | |
| // window.ThereBetterNotBeAFunctionByThisName is not a function at http://localhost/ics/support/myhistory.asp line 0 | |
| AssertTrue(selenium.Processor.GetBoolean("isJavaScriptErrorPresent", new String[] { });) | |
| string errorMessage = selenium.Processor.GetString("getJavaScriptError", new String[] { }); | |
| Asserttrue(Regex.IsMatch(errorMessage, @"^window\.ThereBetterNotBeAFunctionByThisName is not a function at https?://[^/]+/ics/support/myhistory\.asp line 0 in cypContent$")); | |
| // Should not be any more errors. | |
| AssertFalse(selenium.Processor.GetBoolean("isJavaScriptErrorPresent", new String[] { });) | |
| } | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* Changes to add support for capturing JavaScript errors and treating them similar | |
| to alerts - the test script must retrieve them right after they occur, or an exception | |
| is thrown. | |
| This support includes modified version of some existing parts of Selenium, lifted out of | |
| selenium-api.js and selenium-browserbot.js. | |
| Existing functions: | |
| selenium-api.js: | |
| Selenium.prototype.ensureNoUnhandledPopups() | |
| Selenium.prototype.P5_unmodified_ensureNoUnhandledPopups() (run-time-copied from ensureNoUnhandledPopups()) | |
| selenium-browserbot.js: | |
| BrowserBot.createForWindow() | |
| BrowserBot.P5_unmodified_createForWindow() (run-time-copied from createForWindow()) | |
| BrowserBot.prototype.modifyWindowToRecordPopUpDialogs() | |
| BrowserBot.prototype.resetPopups() | |
| BrowserBot.prototype.P5_unmodified_resetPopups() (run-time-copied from resetPopups()) | |
| BrowserBot.prototype.P5_unmodified_modifyWindowToRecordPopUpDialogs() (run-time-copied from modifyWindowToRecordPopUpDialogs()) | |
| New functions: | |
| selenium-api.js: | |
| bool Selenium.prototype.getIgnoreJavaScriptErrors(bool) | |
| void Selenium.prototype.getIgnoreJavaScriptErrorsLike(string) | |
| string Selenium.prototype.getJavaScriptError() (based on getAlert()) | |
| bool Selenium.prototype.isJavaScriptErrorPresent() (based on isAlertPresent()) | |
| selenium-browserbot.js: | |
| bool BrowserBot.prototype.hasJavaScriptErrors() (based on hasAlerts()) | |
| string BrowserBot.prototype.getNextJavaScriptError() (based on getNextAlert()) | |
| void BrowserBot.prototype.ignoreJavaScriptErrorsLike(RegExp) | |
| New data fields: | |
| selenium-browserbot.js: | |
| string[] browserbot.recordedJavaScriptErrors - Errors that have been recorded, in order by occurence. | |
| bool browserbot.isJavaScriptErrorTrapEnabled - Is trapping of JavaScript errors enabled? | |
| RegExp[] browserbot.ignoreJavaScriptErrorRegExps - Regular expressions of JavaScript errors that should not be recorded. | |
| */ | |
| /* ------ Changes and additions for selenium-api.js ------ */ | |
| /* Wrap ensureNoUnhandledPopups() to check for unhandled JavaScript errors too. */ | |
| Selenium.prototype.P5_unmodified_ensureNoUnhandledPopups = Selenium.prototype.ensureNoUnhandledPopups; | |
| Selenium.prototype.ensureNoUnhandledPopups = function() { | |
| this.P5_unmodified_ensureNoUnhandledPopups(); | |
| if (this.browserbot && this.browserbot.isJavaScriptErrorTrapEnabled && this.browserbot.hasJavaScriptErrors && this.browserbot.hasJavaScriptErrors()) { | |
| throw new SeleniumError('There was an unexpected JavaScript error! [' + this.browserbot.getNextJavaScriptError() + ']'); | |
| } | |
| }; // Selenium.prototype.ensureNoUnhandledPopups = | |
| /* Add the getJavaScriptError command: */ | |
| Selenium.prototype.getJavaScriptError = function() { | |
| /** | |
| * Retrieves the message of a JavaScript error, or '' if none. | |
| * | |
| * @return string the error message, or '' if none. | |
| */ | |
| if (!this.browserbot.hasJavaScriptErrors()) { | |
| return ''; | |
| } | |
| return this.browserbot.getNextJavaScriptError(); | |
| }; // Selenium.prototype.getJavaScriptError = | |
| Selenium.prototype.getJavaScriptError.dontCheckAlertsAndConfirms = true; | |
| Selenium.prototype.getIgnoreJavaScriptErrors = function(disabled) { | |
| /** | |
| * Enables or disables the JavaScriptError trapping support. Default is enabled. | |
| * | |
| * Note: Calling this "getIgnoreJavaScriptErrors()" is a BAD idea, because it | |
| * changes the state of the trap, but doing so gets this command past Selenium's | |
| * command processor. | |
| * | |
| * @param boolean disabled - true if errors should be ignored. | |
| * @return boolean the previous state of the support. | |
| * | |
| */ | |
| var previousValue = !this.browserbot.isJavaScriptErrorTrapEnabled; | |
| if (typeof(disabled) != 'undefined') { | |
| this.browserbot.isJavaScriptErrorTrapEnabled = !(disabled == 'true' || disabled == '1'); | |
| } | |
| return previousValue; | |
| }; // Selenium.prototype.getIgnoreJavaScriptErrors = | |
| Selenium.prototype.getIgnoreJavaScriptErrors.dontCheckAlertsAndConfirms = true; | |
| Selenium.prototype.getIgnoreJavaScriptErrorsLike = function(messagePattern) { | |
| /** | |
| * Suppresses all JavaScript errors matching the specified RegExp pattern. | |
| * Errors that are not suppressed are still subject to the getIgnoreJavaScriptErrors() | |
| * setting. Default is that no messages are suppressed. | |
| * | |
| * Note: Calling this "getIgnoreJavaScriptErrorsLike()" is a BAD idea, because it | |
| * changes the state of the trap, but doing so gets this command past Selenium's | |
| * command processor. | |
| * | |
| * @param string messagePattern - Regex of an error to suppress. | |
| * @return string An empty string to keep the Selenium command processor happy. | |
| * | |
| */ | |
| this.browserbot.ignoreJavaScriptErrorsLike(new RegExp(messagePattern)); | |
| return ""; | |
| }; // Selenium.prototype.getIgnoreJavaScriptErrorsLike = | |
| Selenium.prototype.getIgnoreJavaScriptErrorsLike.dontCheckAlertsAndConfirms = true; | |
| /* Add the isJavaScriptErrorPresent command: */ | |
| Selenium.prototype.isJavaScriptErrorPresent = function() { | |
| /** | |
| * Has a JavaScript error occurred? | |
| * | |
| * This function never throws an exception | |
| * | |
| * @return boolean true if there is a JavaScript error. | |
| */ | |
| return this.browserbot.hasJavaScriptErrors(); | |
| }; // Selenium.prototype.isJavaScriptErrorPresent = | |
| Selenium.prototype.isJavaScriptErrorPresent.dontCheckAlertsAndConfirms = true; | |
| /* ------ Changes and additions for selenium-browserbot.js ------ */ | |
| /* Wrap createForWindow() to initialize the collection of recorded JavaScript errors: */ | |
| BrowserBot.P5_unmodified_createForWindow = BrowserBot.createForWindow; | |
| BrowserBot.createForWindow = function(window, proxyInjectionMode) { | |
| var browserbot = BrowserBot.P5_unmodified_createForWindow(window, proxyInjectionMode); | |
| browserbot.recordedJavaScriptErrors = []; | |
| browserbot.ignoreJavaScriptErrorRegExps = []; | |
| browserbot.isJavaScriptErrorTrapEnabled = true; | |
| return browserbot; | |
| }; // BrowserBot.createForWindow = | |
| /* Add the hasJavaScriptErrors() boolean function: */ | |
| BrowserBot.prototype.hasJavaScriptErrors = function() { | |
| return (this.recordedJavaScriptErrors.length > 0); | |
| }; // BrowserBot.prototype.hasJavaScriptErrors = | |
| /* Wrap resetPopups() to discard any recorded JavaScript errors: */ | |
| BrowserBot.prototype.P5_unmodified_resetPopups = BrowserBot.prototype.resetPopups; | |
| BrowserBot.prototype.resetPopups = function() { | |
| this.P5_unmodified_resetPopups(); | |
| this.recordedJavaScriptErrors = []; | |
| }; // BrowserBot.prototype.resetPopups = | |
| /* Add the ignoreJavaScriptErrorsLike(regexp) function to suppress matching errors: */ | |
| BrowserBot.prototype.ignoreJavaScriptErrorsLike = function(messageRegexp) { | |
| this.ignoreJavaScriptErrorRegExps.push(messageRegexp); | |
| }; // BrowserBot.prototype.ignoreJavaScriptErrorsLike = | |
| /* Add the getNextJavaScriptError() function to return the next JavaScript error in recording order: */ | |
| BrowserBot.prototype.getNextJavaScriptError = function() { | |
| var t = this.recordedJavaScriptErrors.shift(); | |
| if (t) { | |
| t = t.replace(/\n/g, ' '); // because Selenese loses \n's when retrieving text from HTML table | |
| } | |
| this.relayBotToRC('browserbot.recordedJavaScriptErrors'); | |
| LOG.info('Returning JavaScript error: ' + t); | |
| return t; | |
| }; // BrowserBot.prototype.getNextJavaScriptError = | |
| /* Wrap modifyWindowToRecordPopUpDialogs() to wrap the window's onerror() function and record the error: */ | |
| BrowserBot.prototype.P5_unmodified_modifyWindowToRecordPopUpDialogs = BrowserBot.prototype.modifyWindowToRecordPopUpDialogs; | |
| BrowserBot.prototype.modifyWindowToRecordPopUpDialogs = function(windowToModify, browserBot) { | |
| var self = this; | |
| self.P5_unmodified_modifyWindowToRecordPopUpDialogs(windowToModify, browserBot); | |
| /* Set up to record any JavaScript errors that may occur on the AUT's page: */ | |
| var oldonerror; | |
| if (windowToModify.onerror != null && typeof(windowToModify.onerror) != 'undefined' && (typeof(windowToModify.onerror.IS_P5_ONERROR) != 'boolean' || !windowToModify.onerror.IS_P5_ONERROR)) { | |
| oldonerror = windowToModify.onerror; | |
| } | |
| windowToModify.onerror = function(errorMessage, pageUrl, lineNumber) { | |
| if (self.isJavaScriptErrorTrapEnabled) { | |
| var error = errorMessage + ' at ' + pageUrl + ' line ' + lineNumber; | |
| if (windowToModify.name) { | |
| error += (' in ' + windowToModify.name); | |
| } | |
| var suppress = false; | |
| for (var i = 0; i < browserBot.ignoreJavaScriptErrorRegExps.length && !suppress; i++) { | |
| suppress = suppress || self.ignoreJavaScriptErrorRegExps[i].test(error); | |
| } | |
| if (!suppress) { | |
| LOG.info('window.onerror() recorded: ' + error); | |
| browserBot.recordedJavaScriptErrors.push(error); | |
| } | |
| } | |
| if (typeof(oldonerror) != 'undefined') | |
| { | |
| return oldonerror(errorMessage, pageUrl, lineNumber); | |
| } | |
| else | |
| { | |
| return false; | |
| } | |
| }; // windowToModify.onerror = | |
| windowToModify.onerror.IS_P5_ONERROR = true; | |
| }; // BrowserBot.prototype.modifyWindowToRecordPopUpDialogs = | |
| /* Apply our BrowserBot changes to its known pseudo-subclasses. There has to be a better way to do this, but I can't find one. */ | |
| var browserBots = [MozillaBrowserBot, KonquerorBrowserBot, SafariBrowserBot, OperaBrowserBot, IEBrowserBot]; | |
| for (var i=0; i < browserBots.length; i++) { | |
| browserBots[i].prototype.P5_unmodified_resetPopups = browserBots[i].prototype.resetPopups; | |
| browserBots[i].prototype.resetPopups = BrowserBot.prototype.resetPopups; | |
| browserBots[i].prototype.P5_unmodified_modifyWindowToRecordPopUpDialogs = browserBots[i].prototype.modifyWindowToRecordPopUpDialogs; | |
| browserBots[i].prototype.modifyWindowToRecordPopUpDialogs = BrowserBot.prototype.modifyWindowToRecordPopUpDialogs; | |
| browserBots[i].prototype.hasJavaScriptErrors = BrowserBot.prototype.hasJavaScriptErrors; | |
| browserBots[i].prototype.getNextJavaScriptError = BrowserBot.prototype.getNextJavaScriptError; | |
| browserBots[i].prototype.ignoreJavaScriptErrorsLike = BrowserBot.prototype.ignoreJavaScriptErrorsLike; | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment