diff --git a/.prettierignore b/.prettierignore index f2ddf012c98e..113a311c2c62 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,2 +1,3 @@ *.md .nxcache +packages/browser-integration-tests/fixtures diff --git a/packages/browser-integration-tests/.eslintrc.js b/packages/browser-integration-tests/.eslintrc.js index 977d75b6a27f..16de146cce24 100644 --- a/packages/browser-integration-tests/.eslintrc.js +++ b/packages/browser-integration-tests/.eslintrc.js @@ -10,6 +10,7 @@ module.exports = { 'loader-suites/**/dist/*', 'loader-suites/**/subject.js', 'scripts/**', + 'fixtures/**', ], parserOptions: { sourceType: 'module', diff --git a/packages/browser-integration-tests/fixtures/loader.js b/packages/browser-integration-tests/fixtures/loader.js index 731ee8af2a6c..c95b5eabdcac 100644 --- a/packages/browser-integration-tests/fixtures/loader.js +++ b/packages/browser-integration-tests/fixtures/loader.js @@ -1,249 +1,4 @@ -/* eslint-disable */ -// prettier-ignore -// Prettier disabled due to trailing comma not working in IE10/11 -(function( - _window, - _document, - _script, - _onerror, - _onunhandledrejection, - _namespace, - _publicKey, - _sdkBundleUrl, - _config, - _lazy -) { - var lazy = _lazy; - var forceLoad = false; - - for (var i = 0; i < document.scripts.length; i++) { - if (document.scripts[i].src.indexOf(_publicKey) > -1) { - // If lazy was set to true above, we need to check if the user has set data-lazy="no" - // to confirm that we should lazy load the CDN bundle - if (lazy && document.scripts[i].getAttribute('data-lazy') === 'no') { - lazy = false; - } - break; - } - } - - var injected = false; - var onLoadCallbacks = []; - - // Create a namespace and attach function that will store captured exception - // Because functions are also objects, we can attach the queue itself straight to it and save some bytes - var queue = function(content) { - // content.e = error - // content.p = promise rejection - // content.f = function call the Sentry - if ( - ('e' in content || - 'p' in content || - (content.f && content.f.indexOf('capture') > -1) || - (content.f && content.f.indexOf('showReportDialog') > -1)) && - lazy - ) { - // We only want to lazy inject/load the sdk bundle if - // an error or promise rejection occured - // OR someone called `capture...` on the SDK - injectSdk(onLoadCallbacks); - } - queue.data.push(content); - }; - queue.data = []; - - function injectSdk(callbacks) { - if (injected) { - return; - } - injected = true; - - // Create a `script` tag with provided SDK `url` and attach it just before the first, already existing `script` tag - // Scripts that are dynamically created and added to the document are async by default, - // they don't block rendering and execute as soon as they download, meaning they could - // come out in the wrong order. Because of that we don't need async=1 as GA does. - // it was probably(?) a legacy behavior that they left to not modify few years old snippet - // https://www.html5rocks.com/en/tutorials/speed/script-loading/ - var _currentScriptTag = _document.scripts[0]; - var _newScriptTag = _document.createElement(_script); - _newScriptTag.src = _sdkBundleUrl; - _newScriptTag.crossOrigin = 'anonymous'; - - // Once our SDK is loaded - _newScriptTag.addEventListener('load', function () { - try { - // Restore onerror/onunhandledrejection handlers - only if not mutated in the meanwhile - if (_window[_onerror] && _window[_onerror].__SENTRY_LOADER__) { - _window[_onerror] = _oldOnerror; - } - if (_window[_onunhandledrejection] && _window[_onunhandledrejection].__SENTRY_LOADER__) { - _window[_onunhandledrejection] = _oldOnunhandledrejection; - } - - // Add loader as SDK source - _window.SENTRY_SDK_SOURCE = 'loader'; - - var SDK = _window[_namespace]; - - var oldInit = SDK.init; - - var integrations = []; - if (_config.tracesSampleRate) { - integrations.push(new Sentry.BrowserTracing()); - } - - if (_config.replaysSessionSampleRate || _config.replaysOnErrorSampleRate) { - integrations.push(new Sentry.Replay()); - } - - if (integrations.length) { - _config.integrations = integrations; - } - - // Configure it using provided DSN and config object - SDK.init = function(options) { - var target = _config; - for (var key in options) { - if (Object.prototype.hasOwnProperty.call(options, key)) { - target[key] = options[key]; - } - } - oldInit(target); - }; - - sdkLoaded(callbacks, SDK); - } catch (o_O) { - console.error(o_O); - } - }); - - _currentScriptTag.parentNode.insertBefore(_newScriptTag, _currentScriptTag); - } - - function sdkIsLoaded() { - var __sentry = _window['__SENTRY__']; - // If there is a global __SENTRY__ that means that in any of the callbacks init() was already invoked - return !!(!(typeof __sentry === 'undefined') && __sentry.hub && __sentry.hub.getClient()); - } - - function sdkLoaded(callbacks, SDK) { - try { - // We have to make sure to call all callbacks first - for (var i = 0; i < callbacks.length; i++) { - if (typeof callbacks[i] === 'function') { - callbacks[i](); - } - } - - var data = queue.data; - - var initAlreadyCalled = sdkIsLoaded(); - - // Call init first, if provided - data.sort((a, b) => a.f === 'init' ? -1 : 0); - - // We want to replay all calls to Sentry and also make sure that `init` is called if it wasn't already - // We replay all calls to `Sentry.*` now - var calledSentry = false; - for (var i = 0; i < data.length; i++) { - if (data[i].f) { - calledSentry = true; - var call = data[i]; - if (initAlreadyCalled === false && call.f !== 'init') { - // First call always has to be init, this is a conveniece for the user so call to init is optional - SDK.init(); - } - initAlreadyCalled = true; - SDK[call.f].apply(SDK, call.a); - } - } - if (initAlreadyCalled === false && calledSentry === false) { - // Sentry has never been called but we need Sentry.init() so call it - SDK.init(); - } - - // Because we installed the SDK, at this point we have an access to TraceKit's handler, - // which can take care of browser differences (eg. missing exception argument in onerror) - var tracekitErrorHandler = _window[_onerror]; - var tracekitUnhandledRejectionHandler = _window[_onunhandledrejection]; - - // And now capture all previously caught exceptions - for (var i = 0; i < data.length; i++) { - if ('e' in data[i] && tracekitErrorHandler) { - tracekitErrorHandler.apply(_window, data[i].e); - } else if ('p' in data[i] && tracekitUnhandledRejectionHandler) { - tracekitUnhandledRejectionHandler.apply(_window, [data[i].p]); - } - } - } catch (o_O) { - console.error(o_O); - } - } - - // We make sure we do not overwrite window.Sentry since there could be already integrations in there - _window[_namespace] = _window[_namespace] || {}; - - _window[_namespace].onLoad = function (callback) { - onLoadCallbacks.push(callback); - if (lazy && !forceLoad) { - return; - } - injectSdk(onLoadCallbacks); - }; - - _window[_namespace].forceLoad = function() { - forceLoad = true; - if (lazy) { - setTimeout(function() { - injectSdk(onLoadCallbacks); - }); - } - }; - - [ - 'init', - 'addBreadcrumb', - 'captureMessage', - 'captureException', - 'captureEvent', - 'configureScope', - 'withScope', - 'showReportDialog' - ].forEach(function(f) { - _window[_namespace][f] = function() { - queue({ f: f, a: arguments }); - }; - }); - - // Store reference to the old `onerror` handler and override it with our own function - // that will just push exceptions to the queue and call through old handler if we found one - var _oldOnerror = _window[_onerror]; - _window[_onerror] = function() { - // Use keys as "data type" to save some characters" - queue({ - e: [].slice.call(arguments) - }); - - if (_oldOnerror) _oldOnerror.apply(_window, arguments); - }; - _window[_onerror].__SENTRY_LOADER__ = true; - - // Do the same store/queue/call operations for `onunhandledrejection` event - var _oldOnunhandledrejection = _window[_onunhandledrejection]; - _window[_onunhandledrejection] = function(e) { - queue({ - p: 'reason' in e ? e.reason : 'detail' in e && 'reason' in e.detail ? e.detail.reason : e - }); - if (_oldOnunhandledrejection) _oldOnunhandledrejection.apply(_window, arguments); - }; - _window[_onunhandledrejection].__SENTRY_LOADER__ = true; - - if (!lazy) { - setTimeout(function () { - injectSdk(onLoadCallbacks); - }); - } -})( +!function(n,e,t,r,o,a,i,c,_,p){for(var s=p,forceLoad=!1,f=0;f-1){s&&"no"===document.scripts[f].getAttribute("data-lazy")&&(s=!1);break}var u=!1,l=[],d=function(n){("e"in n||"p"in n||n.f&&n.f.indexOf("capture")>-1||n.f&&n.f.indexOf("showReportDialog")>-1)&&s&&E(l),d.data.push(n)};function E(i){if(!u){u=!0;var p=e.scripts[0],s=e.createElement(t);s.src=c,s.crossOrigin="anonymous",s.addEventListener("load",(function(){try{n[r]&&n[r].__SENTRY_LOADER__&&(n[r]=R),n[o]&&n[o].__SENTRY_LOADER__&&(n[o]=h),n.SENTRY_SDK_SOURCE="loader";var e=n[a],t=e.init,c=[];_.tracesSampleRate&&c.push(new e.BrowserTracing),(_.replaysSessionSampleRate||_.replaysOnErrorSampleRate)&&c.push(new e.Replay),c.length&&(_.integrations=c),e.init=function(n){var e=_;for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r]);t(e)},function(e,t){try{for(var a=0;a { + const req = waitForErrorRequest(page); + + const url = await getLocalTestUrl({ testDir: __dirname }); + await page.goto(url); + + const eventData = envelopeRequestParser(await req); + + expect(eventData.message).toBe('Test exception'); +});