@microsoft/applicationinsights-analytics-js 2.7.2-nightly.2111-08 → 2.7.2-nightly.2111-09

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/Tests/Unit/src/AnalyticsExtensionSize.tests.ts +58 -0
  2. package/Tests/Unit/src/ApplicationInsights.tests.ts +1647 -0
  3. package/Tests/Unit/src/TelemetryItemCreator.tests.ts +304 -0
  4. package/Tests/Unit/src/appinsights-analytics.tests.ts +9 -0
  5. package/Tests/UnitTests.html +62 -0
  6. package/Tests/tsconfig.json +13 -0
  7. package/api-extractor.json +361 -0
  8. package/applicationinsights-analytics-js.build.error.log +80 -0
  9. package/applicationinsights-analytics-js.build.log +309 -0
  10. package/browser/applicationinsights-analytics-js.integrity.json +9 -9
  11. package/browser/applicationinsights-analytics-js.js +2 -2
  12. package/browser/applicationinsights-analytics-js.js.map +1 -1
  13. package/browser/applicationinsights-analytics-js.min.js +2 -2
  14. package/browser/applicationinsights-analytics-js.min.js.map +1 -1
  15. package/dist/applicationinsights-analytics-js.api.json +1 -1
  16. package/dist/applicationinsights-analytics-js.d.ts +1 -1
  17. package/dist/applicationinsights-analytics-js.js +2 -2
  18. package/dist/applicationinsights-analytics-js.js.map +1 -1
  19. package/dist/applicationinsights-analytics-js.min.js +2 -2
  20. package/dist/applicationinsights-analytics-js.min.js.map +1 -1
  21. package/dist/applicationinsights-analytics-js.rollup.d.ts +1 -1
  22. package/dist-esm/JavaScriptSDK/ApplicationInsights.js +2 -2
  23. package/dist-esm/JavaScriptSDK/ApplicationInsights.js.map +1 -1
  24. package/dist-esm/JavaScriptSDK/Telemetry/PageViewManager.js +1 -1
  25. package/dist-esm/JavaScriptSDK/Telemetry/PageViewPerformanceManager.js +1 -1
  26. package/dist-esm/JavaScriptSDK/Telemetry/PageVisitTimeManager.js +1 -1
  27. package/dist-esm/JavaScriptSDK.Interfaces/ITelemetryConfig.js +1 -1
  28. package/dist-esm/applicationinsights-analytics-js.js +1 -1
  29. package/microsoft-applicationinsights-analytics-js-2.7.2-nightly.2111-09.tgz +0 -0
  30. package/package.json +5 -5
  31. package/rollup.config.js +139 -0
  32. package/src/JavaScriptSDK/ApplicationInsights.ts +1 -1
  33. package/temp/applicationinsights-analytics-js.api.md +114 -0
  34. package/tslint.json +5 -0
  35. package/types/tsdoc-metadata.json +1 -1
@@ -0,0 +1,1647 @@
1
+ import {
2
+ Assert, AITestClass, PollingAssert, EventValidator, TraceValidator, ExceptionValidator,
3
+ MetricValidator, PageViewPerformanceValidator, PageViewValidator, RemoteDepdencyValidator
4
+ } from "@microsoft/ai-test-framework";
5
+ import { SinonStub, SinonSpy } from 'sinon';
6
+ import {
7
+ Exception, SeverityLevel, Event, Trace, PageViewPerformance, IConfig, IExceptionInternal,
8
+ AnalyticsPluginIdentifier, Util, IAppInsights, Metric, PageView, RemoteDependencyData
9
+ } from "@microsoft/applicationinsights-common";
10
+ import { ITelemetryItem, AppInsightsCore, IPlugin, IConfiguration, IAppInsightsCore, setEnableEnvMocks, getLocation, dumpObj } from "@microsoft/applicationinsights-core-js";
11
+ import { Sender } from "@microsoft/applicationinsights-channel-js"
12
+ import { PropertiesPlugin } from "@microsoft/applicationinsights-properties-js";
13
+ import { ApplicationInsights } from "../../../src/JavaScriptSDK/ApplicationInsights";
14
+
15
+ declare class ExceptionHelper {
16
+ capture: (appInsights:IAppInsights) => void;
17
+ captureStrict: (appInsights:IAppInsights) => void;
18
+ throw: (value:any) => void;
19
+ throwCors: () => void;
20
+ throwStrict: (value:any) => void;
21
+ throwRuntimeException: (timeoutFunc: VoidFunction) => void;
22
+ throwStrictRuntimeException: (timeoutFunc: VoidFunction) => void;
23
+ };
24
+
25
+ export class ApplicationInsightsTests extends AITestClass {
26
+ private _onerror:any = null;
27
+ private trackSpy:SinonSpy;
28
+ private throwInternalSpy:SinonSpy;
29
+ private exceptionHelper: any = new ExceptionHelper();
30
+
31
+ public testInitialize() {
32
+ this._onerror = window.onerror;
33
+ setEnableEnvMocks(false);
34
+ super.testInitialize();
35
+ Util.setCookie(undefined, 'ai_session', "");
36
+ Util.setCookie(undefined, 'ai_user', "");
37
+ if (Util.canUseLocalStorage()) {
38
+ window.localStorage.clear();
39
+ }
40
+ }
41
+
42
+ public testCleanup() {
43
+ super.testCleanup();
44
+ Util.setCookie(undefined, 'ai_session', "");
45
+ Util.setCookie(undefined, 'ai_user', "");
46
+ if (Util.canUseLocalStorage()) {
47
+ window.localStorage.clear();
48
+ }
49
+ window.onerror = this._onerror;
50
+ }
51
+
52
+ public causeException(cb:Function) {
53
+ AITestClass.orgSetTimeout(() => {
54
+ cb();
55
+ }, 0);
56
+ }
57
+
58
+ public registerTests() {
59
+
60
+ this.testCase({
61
+ name: 'enableAutoRouteTracking: event listener is added to the popstate event',
62
+ test: () => {
63
+ // Setup
64
+ const appInsights = new ApplicationInsights();
65
+ const core = new AppInsightsCore();
66
+ const channel = new ChannelPlugin();
67
+ const eventListenerStub = this.sandbox.stub(window, 'addEventListener');
68
+
69
+ // Act
70
+ core.initialize({
71
+ instrumentationKey: '',
72
+ enableAutoRouteTracking: true
73
+ } as IConfig & IConfiguration, [appInsights, channel]);
74
+
75
+ // Assert
76
+ Assert.ok(eventListenerStub.calledTwice);
77
+ Assert.equal(eventListenerStub.args[0][0], "popstate");
78
+ Assert.equal(eventListenerStub.args[1][0], "locationchange");
79
+ }
80
+ });
81
+
82
+ this.testCase({
83
+ name: 'enableAutoRouteTracking: route changes trigger a new pageview',
84
+ useFakeTimers: true,
85
+ test: () => {
86
+ // Current URL will be the test page
87
+ setEnableEnvMocks(true);
88
+ this.setLocationHref("firstUri");
89
+
90
+ // Setup
91
+ const appInsights = new ApplicationInsights();
92
+ appInsights.autoRoutePVDelay = 500;
93
+ const core = new AppInsightsCore();
94
+ const channel = new ChannelPlugin();
95
+ const properties = new PropertiesPlugin();
96
+ properties.context = { telemetryTrace: { traceID: 'not set', name: 'name not set' } } as any;
97
+ const trackPageViewStub = this.sandbox.stub(appInsights, 'trackPageView');
98
+
99
+ // Act
100
+ core.initialize({
101
+ instrumentationKey: '',
102
+ enableAutoRouteTracking: true
103
+ } as IConfig & IConfiguration, [appInsights, channel, properties]);
104
+ this.setLocationHref("secondUri");
105
+ window.dispatchEvent(Util.createDomEvent('locationchange'));
106
+ this.clock.tick(500);
107
+
108
+ this.setLocationHref("thirdUri");
109
+ window.dispatchEvent(Util.createDomEvent('locationchange'));
110
+ this.clock.tick(500);
111
+
112
+ // Assert
113
+ Assert.equal(2, trackPageViewStub.callCount);
114
+ Assert.ok(properties.context.telemetryTrace.traceID);
115
+ Assert.ok(properties.context.telemetryTrace.name);
116
+ Assert.notEqual(properties.context.telemetryTrace.traceID, 'not set', 'current operation id is updated after route change');
117
+ Assert.notEqual(properties.context.telemetryTrace.name, 'name not set', 'current operation name is updated after route change');
118
+ // Assert.equal(appInsights['_prevUri'], 'secondUri', "the previous uri is stored on variable _prevUri");
119
+ // Assert.equal(appInsights['_currUri'], window.location.href, "the current uri is stored on variable _currUri");
120
+
121
+ Assert.equal("firstUri", trackPageViewStub.args[0][0].refUri, "previous uri is assigned to refUri as firstUri, and send as an argument of trackPageview method");
122
+ Assert.equal("secondUri", trackPageViewStub.args[1][0].refUri, "previous uri is assigned to refUri as secondUri and send as an argument of trackPageview method");
123
+ }
124
+ });
125
+
126
+ this.testCase({
127
+ name: 'enableAutoRouteTracking: route changes trigger a new pageview with correct refUri when route changes happening before the timer autoRoutePVDelay stops',
128
+ useFakeTimers: true,
129
+ test: () => {
130
+ // Setup
131
+ setEnableEnvMocks(true);
132
+ this.setLocationHref("firstUri");
133
+
134
+ const appInsights = new ApplicationInsights();
135
+ appInsights.autoRoutePVDelay = 500;
136
+ const core = new AppInsightsCore();
137
+ const channel = new ChannelPlugin();
138
+ const properties = new PropertiesPlugin();
139
+ properties.context = { telemetryTrace: { traceID: 'not set', name: 'name not set' } } as any;
140
+ appInsights['_prevUri'] = "firstUri";
141
+ const trackPageViewStub = this.sandbox.stub(appInsights, 'trackPageView');
142
+
143
+ // Act
144
+ core.initialize({
145
+ instrumentationKey: '',
146
+ enableAutoRouteTracking: true
147
+ } as IConfig & IConfiguration, [appInsights, channel, properties]);
148
+ window.dispatchEvent(Util.createDomEvent('locationchange'));
149
+ this.clock.tick(200);
150
+
151
+ // set up second dispatch
152
+ window.dispatchEvent(Util.createDomEvent('locationchange'));
153
+ this.clock.tick(500);
154
+
155
+
156
+ // Assert
157
+ Assert.equal(2, trackPageViewStub.callCount);
158
+ Assert.ok(properties.context.telemetryTrace.traceID);
159
+ Assert.ok(properties.context.telemetryTrace.name);
160
+ Assert.notEqual(properties.context.telemetryTrace.traceID, 'not set', 'current operation id is updated after route change');
161
+ Assert.notEqual(properties.context.telemetryTrace.name, 'name not set', 'current operation name is updated after route change');
162
+ // first trackPageView event
163
+ Assert.equal(trackPageViewStub.args[0][0].refUri, 'firstUri', "first trackPageview event: refUri grabs the value of existing _prevUri");
164
+ // Assert.equal(appInsights['_currUri'], getLocation(true).href, "first trackPageview event: the current uri is stored on variable _currUri");
165
+ // second trackPageView event
166
+ Assert.equal(trackPageViewStub.args[1][0].refUri, getLocation(true).href, "second trackPageview event: refUri grabs the value of updated _prevUri, which is the first pageView event's _currUri");
167
+ }
168
+ });
169
+
170
+ this.testCase({
171
+ name: 'enableAutoRouteTracking: (IE9) app does not crash if history.pushState does not exist',
172
+ test: () => {
173
+ // Setup
174
+ const originalPushState = history.pushState;
175
+ const originalReplaceState = history.replaceState;
176
+ history.pushState = null;
177
+ history.replaceState = null;
178
+ const appInsights = new ApplicationInsights();
179
+ const core = new AppInsightsCore();
180
+ const channel = new ChannelPlugin();
181
+ const properties = new PropertiesPlugin();
182
+ properties.context = { telemetryTrace: { traceID: 'not set', parentID: undefined} } as any;
183
+ this.sandbox.stub(appInsights, 'trackPageView');
184
+
185
+ // Act
186
+ core.initialize({
187
+ instrumentationKey: '',
188
+ enableAutoRouteTracking: true
189
+ } as IConfig & IConfiguration, [appInsights, channel]);
190
+ window.dispatchEvent(Util.createDomEvent('locationchange'));
191
+
192
+ // Assert
193
+ Assert.ok(true, 'App does not crash when history object is incomplete');
194
+
195
+ // Cleanup
196
+ history.pushState = originalPushState;
197
+ history.replaceState = originalReplaceState;
198
+ }
199
+ });
200
+
201
+ this.testCase({
202
+ name: 'AppInsightsTests: PageVisitTimeManager is constructed when analytics plugin is initialized',
203
+ test: () => {
204
+ // Setup
205
+ const channel = new ChannelPlugin();
206
+ const core = new AppInsightsCore();
207
+ const appInsights: ApplicationInsights = new ApplicationInsights();
208
+
209
+ // Act
210
+ const config = {
211
+ instrumentationKey: 'ikey'
212
+ };
213
+
214
+ core.initialize(
215
+ config,
216
+ [appInsights, channel]
217
+ );
218
+ const pvtm = appInsights['_pageVisitTimeManager'];
219
+
220
+ // Assert
221
+ Assert.ok(pvtm)
222
+ Assert.ok(pvtm['_logger']);
223
+ Assert.ok(pvtm['pageVisitTimeTrackingHandler']);
224
+ }
225
+ });
226
+
227
+ this.testCase({
228
+ name: 'AppInsightsTests: PageVisitTimeManager is available when config.autoTrackPageVisitTime is true and trackPageView is called',
229
+ test: () => {
230
+ // Setup
231
+ const channel = new ChannelPlugin();
232
+ const core = new AppInsightsCore();
233
+ const appInsights: ApplicationInsights = new ApplicationInsights();
234
+
235
+ const config = {
236
+ instrumentationKey: 'ikey',
237
+ autoTrackPageVisitTime: true
238
+ };
239
+ core.initialize(
240
+ config,
241
+ [appInsights, channel]
242
+ );
243
+ const pvtm = appInsights['_pageVisitTimeManager'];
244
+ const pvtmSpy = this.sandbox.spy(pvtm, 'trackPreviousPageVisit');
245
+
246
+ Assert.ok(pvtm)
247
+ Assert.ok(pvtmSpy.notCalled);
248
+
249
+ // Act
250
+ appInsights.trackPageView();
251
+
252
+ // Assert
253
+ Assert.ok(pvtmSpy.calledOnce);
254
+ }
255
+ });
256
+
257
+ this.testCase({
258
+ name: 'AppInsightsTests: config can be set from root',
259
+ test: () => {
260
+ // Setup
261
+ const appInsights = new ApplicationInsights();
262
+ const core = new AppInsightsCore();
263
+ const channel = new ChannelPlugin();
264
+ const properties = new PropertiesPlugin();
265
+
266
+ // Act
267
+ const config = {
268
+ instrumentationKey: 'instrumentation_key',
269
+ samplingPercentage: 12,
270
+ accountId: 'aaa',
271
+ extensionConfig: {
272
+ [appInsights.identifier]: {
273
+ accountId: 'def'
274
+ }
275
+ }
276
+ };
277
+
278
+ // Initialize
279
+ core.initialize(config, [appInsights, channel, properties]);
280
+
281
+ // Assert
282
+ Assert.equal(12, appInsights.config.samplingPercentage);
283
+ Assert.notEqual('aaa', appInsights.config.accountId);
284
+ Assert.equal('def', appInsights.config.accountId);
285
+ Assert.equal('instrumentation_key', (appInsights['config'] as IConfiguration).instrumentationKey);
286
+ Assert.equal(30 * 60 * 1000, appInsights.config.sessionRenewalMs);
287
+ Assert.equal(24 * 60 * 60 * 1000, appInsights.config.sessionExpirationMs);
288
+
289
+ let extConfig = (core.config as IConfiguration).extensionConfig[AnalyticsPluginIdentifier] as IConfig;
290
+ Assert.equal('instrumentation_key', core.config.instrumentationKey);
291
+ Assert.equal(12, extConfig.samplingPercentage);
292
+ Assert.notEqual('aaa', extConfig.accountId);
293
+ Assert.equal('def', extConfig.accountId);
294
+ Assert.equal('instrumentation_key', (extConfig as any).instrumentationKey);
295
+ Assert.equal(30 * 60 * 1000, extConfig.sessionRenewalMs);
296
+ Assert.equal(24 * 60 * 60 * 1000, extConfig.sessionExpirationMs);
297
+ }
298
+ });
299
+
300
+ this.testCase({
301
+ name: "AppInsightsTests: public members are correct",
302
+ test: () => {
303
+ // setup
304
+ const appInsights = new ApplicationInsights();
305
+ // the assert test will only see config as part of an object member if it has been initialized. Not sure how it worked before
306
+ appInsights.config = {};
307
+ const leTest = (name) => {
308
+ // assert
309
+ Assert.ok(name in appInsights, name + " exists");
310
+ }
311
+
312
+ // act
313
+ const members = [
314
+ "config",
315
+ "trackException",
316
+ "_onerror",
317
+ "trackEvent",
318
+ "trackTrace",
319
+ "trackMetric",
320
+ "trackPageView",
321
+ "trackPageViewPerformance",
322
+ "startTrackPage",
323
+ "stopTrackPage"
324
+ ];
325
+ while (members.length) {
326
+ leTest(members.pop());
327
+ }
328
+ }
329
+ });
330
+
331
+ this.addGenericTests();
332
+ this.addStartStopTrackPageTests();
333
+ this.addTrackExceptionTests();
334
+ this.addOnErrorTests();
335
+ this.addTrackMetricTests();
336
+ this.addTelemetryInitializerTests();
337
+ }
338
+
339
+ private addGenericTests(): void {
340
+ this.testCase({
341
+ name: 'AppInsightsGenericTests: envelope type, data type, and ikey are correct',
342
+ test: () => {
343
+ // setup
344
+ const iKey: string = "BDC8736D-D8E8-4B69-B19B-B0CE6B66A456";
345
+ const iKeyNoDash: string = "BDC8736DD8E84B69B19BB0CE6B66A456";
346
+ const plugin = new ChannelPlugin();
347
+ const core = new AppInsightsCore();
348
+ core.initialize(
349
+ {instrumentationKey: iKey},
350
+ [plugin]
351
+ );
352
+ const appInsights = new ApplicationInsights();
353
+ appInsights.initialize({instrumentationKey: core.config.instrumentationKey}, core, []);
354
+ const trackStub = this.sandbox.stub(appInsights.core, "track");
355
+
356
+ let envelope: ITelemetryItem;
357
+ const test = (action, expectedEnvelopeType, expectedDataType, test?: () => void) => {
358
+ action();
359
+ envelope = this.getFirstResult(action, trackStub);
360
+ Assert.equal("", envelope.iKey, "envelope iKey");
361
+ Assert.equal(expectedEnvelopeType, envelope.name, "envelope name");
362
+ Assert.equal(expectedDataType, envelope.baseType, "data type name");
363
+ if (typeof test === 'function') {test();}
364
+ trackStub.reset();
365
+ };
366
+
367
+ // Test
368
+ test(() => appInsights.trackException({exception: new Error(), severityLevel: SeverityLevel.Critical}), Exception.envelopeType, Exception.dataType)
369
+ test(() => appInsights.trackException({error: new Error(), severityLevel: SeverityLevel.Critical}), Exception.envelopeType, Exception.dataType)
370
+ test(() => appInsights.trackTrace({message: "some string"}), Trace.envelopeType, Trace.dataType);
371
+ test(() => appInsights.trackPageViewPerformance({name: undefined, uri: undefined, measurements: {somefield: 123}}, {vpHeight: 123}), PageViewPerformance.envelopeType, PageViewPerformance.dataType, () => {
372
+ Assert.deepEqual(undefined, envelope.baseData.properties, 'Properties does not exist in Part B');
373
+ });
374
+ }
375
+ });
376
+
377
+ this.testCase({
378
+ name: 'AppInsightsGenericTests: public APIs call track',
379
+ useFakeTimers: true,
380
+ test: () => {
381
+ // setup
382
+ const plugin = new ChannelPlugin();
383
+ const core = new AppInsightsCore();
384
+ core.initialize(
385
+ {instrumentationKey: "key"},
386
+ [plugin]
387
+ );
388
+ const appInsights = new ApplicationInsights();
389
+ appInsights.initialize({ "instrumentationKey": "ikey" }, core, []);
390
+ const senderStub = this.sandbox.stub(appInsights.core, "track");
391
+
392
+ // Act
393
+ appInsights.trackException({exception: new Error(), severityLevel: SeverityLevel.Critical});
394
+ appInsights.trackException({error: new Error(), severityLevel: SeverityLevel.Critical});
395
+ this.clock.tick(1);
396
+
397
+ // Test
398
+ Assert.ok(senderStub.calledTwice, "Telemetry is sent when master switch is on");
399
+ }
400
+ });
401
+ }
402
+
403
+ private addTrackExceptionTests(): void {
404
+ this.testCase({
405
+ name: "TrackExceptionTests: trackException accepts single exception",
406
+ test: () => {
407
+ // setup
408
+ const plugin = new ChannelPlugin();
409
+ const core = new AppInsightsCore();
410
+ core.initialize(
411
+ {instrumentationKey: "key"},
412
+ [plugin]
413
+ );
414
+ const appInsights = new ApplicationInsights();
415
+ appInsights.initialize({ "instrumentationKey": "ikey" }, core, []);
416
+ const trackStub = this.sandbox.stub(appInsights.core, "track");
417
+
418
+ // Test
419
+ appInsights.trackException({error: new Error(), severityLevel: SeverityLevel.Critical});
420
+ Assert.ok(trackStub.calledOnce, "single exception is tracked");
421
+
422
+ // Verify ver is a string, as required by CS4.0
423
+ const baseData = (trackStub.args[0][0] as ITelemetryItem).baseData as IExceptionInternal;
424
+ Assert.equal("string", typeof baseData.ver, "Exception.ver should be a string for CS4.0");
425
+ Assert.equal("4.0", baseData.ver);
426
+ }
427
+ });
428
+
429
+ this.testCase({
430
+ name: "TrackExceptionTests: trackException allows logging errors with different severity level",
431
+ test: () => {
432
+ // setup
433
+ const plugin = new ChannelPlugin();
434
+ const core = new AppInsightsCore();
435
+ core.initialize(
436
+ {instrumentationKey: "key"},
437
+ [plugin]
438
+ );
439
+ const appInsights = new ApplicationInsights();
440
+ appInsights.initialize({ "instrumentationKey": "ikey" }, core, []);
441
+ const trackStub = this.sandbox.stub(appInsights.core, "track");
442
+
443
+ // Test
444
+ appInsights.trackException({error: new Error(), severityLevel: SeverityLevel.Critical});
445
+ Assert.ok(trackStub.calledOnce, "single exception is tracked");
446
+ Assert.equal(SeverityLevel.Critical, trackStub.firstCall.args[0].baseData.severityLevel);
447
+
448
+ trackStub.reset();
449
+
450
+ appInsights.trackException({error: new Error(), severityLevel: SeverityLevel.Error});
451
+ Assert.ok(trackStub.calledOnce, "single exception is tracked");
452
+ Assert.equal(SeverityLevel.Error, trackStub.firstCall.args[0].baseData.severityLevel);
453
+ }
454
+ });
455
+ }
456
+
457
+ private addOnErrorTests(): void {
458
+ this.testCase({
459
+ name: "OnErrorTests: _onerror creates a dump of unexpected error thrown by trackException for logging",
460
+ test: () => {
461
+ // setup
462
+ const plugin = new ChannelPlugin();
463
+ const core = new AppInsightsCore();
464
+ core.initialize(
465
+ {instrumentationKey: "key"},
466
+ [plugin]
467
+ );
468
+ const appInsights = new ApplicationInsights();
469
+ appInsights.initialize({ "instrumentationKey": "ikey" }, core, []);
470
+
471
+ const unexpectedError = new Error();
472
+ const expectedString = dumpObj(unexpectedError);
473
+ const throwSpy = this.sandbox.spy(core.logger, "throwInternal");
474
+ this.sandbox.stub(appInsights, "trackException").throws(unexpectedError);
475
+
476
+ // Act
477
+ appInsights._onerror({message: "msg", url: "some://url", lineNumber: 123, columnNumber: 456, error: unexpectedError});
478
+
479
+ // Assert
480
+ Assert.equal(1, throwSpy.callCount);
481
+ // Check Message
482
+ Assert.ok(throwSpy.args[0][2].indexOf("_onError threw exception while logging error,") !== -1, "Message should indicate that _onError failed");
483
+ // Check Exception contains the exception details
484
+ Assert.ok(throwSpy.args[0][3].exception.indexOf(expectedString) !== -1, "Expected error to contain - " + expectedString);
485
+ }
486
+ });
487
+
488
+ this.testCase({
489
+ name: "OnErrorTests: _onerror stringifies error object",
490
+ test: () => {
491
+ // setup
492
+ const plugin = new ChannelPlugin();
493
+ const core = new AppInsightsCore();
494
+ core.initialize(
495
+ {instrumentationKey: "key"},
496
+ [plugin]
497
+ );
498
+ const appInsights = new ApplicationInsights();
499
+ appInsights.initialize({ instrumentationKey: "ikey"}, core, []);
500
+ const unexpectedError = new Error("some message");
501
+ const throwSpy = this.sandbox.spy(core.logger, "throwInternal");
502
+ const stub = this.sandbox.stub(appInsights, "trackException").throws(unexpectedError);
503
+
504
+ // Act
505
+ appInsights._onerror({message: "any message", url: "any://url", lineNumber: 123, columnNumber: 456, error: unexpectedError});
506
+
507
+ // Test
508
+ const dumpExMsg = throwSpy.args[0][3].exception;
509
+ Assert.ok(dumpExMsg.indexOf("stack: ") != -1);
510
+ Assert.ok(dumpExMsg.indexOf(`message: '${unexpectedError.message}'`) !== -1);
511
+ Assert.ok(dumpExMsg.indexOf("name: 'Error'") !== -1);
512
+ }
513
+ });
514
+
515
+ this.testCase({
516
+ name: "OnErrorTests: _onerror logs name of unexpected error thrown by trackException for diagnostics",
517
+ test: () => {
518
+ // setup
519
+ const plugin = new ChannelPlugin();
520
+ const core = new AppInsightsCore();
521
+ core.initialize(
522
+ {instrumentationKey: "key"},
523
+ [plugin]
524
+ );
525
+ const appInsights = new ApplicationInsights();
526
+ appInsights.initialize({ instrumentationKey: "key" }, core, []);
527
+
528
+ const throwInternal = this.sandbox.spy(appInsights.core.logger, "throwInternal");
529
+
530
+ this.sandbox.stub(appInsights, "trackException").throws(new CustomTestError("Simulated Error"));
531
+ const expectedErrorName: string = "CustomTestError";
532
+
533
+ appInsights._onerror({message: "some message", url: "some://url", lineNumber: 1234, columnNumber: 5678, error: new Error()});
534
+
535
+ Assert.ok(throwInternal.calledOnce, "throwInternal called once");
536
+ const logMessage: string = throwInternal.getCall(0).args[2];
537
+ Assert.notEqual(-1, logMessage.indexOf(expectedErrorName), "expected: " + logMessage);
538
+ }
539
+ });
540
+
541
+ this.testCase({
542
+ name: "OnErrorTests: _onerror adds document URL in case of CORS error",
543
+ test: () => {
544
+ // setup
545
+ const plugin = new ChannelPlugin();
546
+ const core = new AppInsightsCore();
547
+ core.initialize(
548
+ {instrumentationKey: "key"},
549
+ [plugin]
550
+ );
551
+ const appInsights = new ApplicationInsights();
552
+ appInsights.initialize({ "instrumentationKey": "ikey" }, core, []);
553
+ const trackSpy = this.sandbox.spy(appInsights.core, "track");
554
+
555
+ // Act
556
+ appInsights._onerror({message: "Script error.", url: "", lineNumber: 0, columnNumber: 0, error: null});
557
+
558
+ // Assert
559
+ Assert.equal(document.URL, trackSpy.args[0][0].baseData.url);
560
+ }
561
+ });
562
+
563
+ this.testCase({
564
+ name: "OnErrorTests: _onerror adds document URL in case of no CORS error",
565
+ test: () => {
566
+ // setup
567
+ const plugin = new ChannelPlugin();
568
+ const core = new AppInsightsCore();
569
+ core.initialize(
570
+ {instrumentationKey: "key"},
571
+ [plugin]
572
+ );
573
+ const appInsights = new ApplicationInsights();
574
+ appInsights.initialize({ "instrumentationKey": "ikey" }, core, []);
575
+ const trackExceptionSpy = this.sandbox.spy(appInsights, "trackException");
576
+
577
+ // Act
578
+ // Last arg is not an error/null which will be treated as not CORS issue
579
+ appInsights._onerror({message: "Script error.", url: "", lineNumber: 0, columnNumber: 0, error: new Object() as any});
580
+
581
+ // Assert
582
+ // properties are passed as a 3rd parameter
583
+ Assert.equal(document.URL, trackExceptionSpy.args[0][1].url);
584
+ }
585
+ });
586
+
587
+ this.testCase({
588
+ name: "OnErrorTests: _onerror logs name of unexpected error thrown by trackException for diagnostics",
589
+ test: () => {
590
+ // setup
591
+ const plugin = new ChannelPlugin();
592
+ const core = new AppInsightsCore();
593
+ core.initialize(
594
+ {instrumentationKey: "key"},
595
+ [plugin]
596
+ );
597
+ const appInsights = new ApplicationInsights();
598
+ appInsights.initialize({ instrumentationKey: "key" }, core, []);
599
+
600
+ const throwInternal = this.sandbox.spy(appInsights.core.logger, "throwInternal");
601
+
602
+ // Internal code does call this anymore!
603
+ const expectedErrorName: string = "test error";
604
+
605
+ let theError = new Error();
606
+ theError.name = expectedErrorName;
607
+ this.sandbox.stub(appInsights, "trackException").throws(theError);
608
+
609
+
610
+ appInsights._onerror({message: "some message", url: "some://url", lineNumber: 1234, columnNumber: 5678, error: "the error message"});
611
+
612
+ Assert.ok(throwInternal.calledOnce, "throwInternal called once");
613
+ const logMessage: string = throwInternal.getCall(0).args[2];
614
+ Assert.notEqual(-1, logMessage.indexOf(expectedErrorName), "logMessage: " + logMessage);
615
+ }
616
+ });
617
+
618
+
619
+ this.testCaseAsync({
620
+ name: "OnErrorTests: _onerror logs name of unexpected error thrown by trackException for diagnostics",
621
+ stepDelay: 1,
622
+ useFakeTimers: true,
623
+ steps: [() => {
624
+ // setup
625
+ const sender: Sender = new Sender();
626
+ const core = new AppInsightsCore();
627
+ core.initialize(
628
+ {
629
+ instrumentationKey: "key",
630
+ extensionConfig: {
631
+ [sender.identifier]: {
632
+ enableSessionStorageBuffer: false,
633
+ maxBatchInterval: 1
634
+ }
635
+ }
636
+ },
637
+ [sender]
638
+ );
639
+ const appInsights = new ApplicationInsights();
640
+ appInsights.initialize({ instrumentationKey: "key" }, core, []);
641
+ appInsights.addTelemetryInitializer((item: ITelemetryItem) => {
642
+ Assert.equal("4.0", item.ver, "Telemetry items inside telemetry initializers should be in CS4.0 format");
643
+ });
644
+
645
+ this.throwInternalSpy = this.sandbox.spy(appInsights.core.logger, "throwInternal");
646
+ sender._sender = (payload:string[], isAsync:boolean) => {
647
+ sender._onSuccess(payload, payload.length);
648
+ };
649
+ this.sandbox.spy()
650
+ this.trackSpy = this.sandbox.spy(sender, "_onSuccess");
651
+
652
+ this.exceptionHelper.capture(appInsights);
653
+
654
+ this.causeException(() => {
655
+ this.exceptionHelper.throwRuntimeException(AITestClass.orgSetTimeout);
656
+ });
657
+
658
+ Assert.ok(!this.trackSpy.calledOnce, "track not called yet");
659
+ Assert.ok(!this.throwInternalSpy.called, "No internal errors");
660
+ }].concat(this.waitForException(1))
661
+ .concat(() => {
662
+
663
+ let isLocal = window.location.protocol === "file:";
664
+ let exp = this.trackSpy.args[0];
665
+ const payloadStr: string[] = this.getPayloadMessages(this.trackSpy);
666
+ if (payloadStr.length > 0) {
667
+ const payload = JSON.parse(payloadStr[0]);
668
+ const data = payload.data;
669
+ Assert.ok(data, "Has Data");
670
+ if (data) {
671
+ Assert.ok(data.baseData, "Has BaseData");
672
+ let baseData = data.baseData;
673
+ if (baseData) {
674
+ const ex = baseData.exceptions[0];
675
+ if (isLocal) {
676
+ Assert.ok(ex.message.indexOf("Script error:") !== -1, "Make sure the error message is present [" + ex.message + "]");
677
+ Assert.equal("String", ex.typeName, "Got the correct typename [" + ex.typeName + "]");
678
+ } else {
679
+ Assert.ok(ex.message.indexOf("ug is not a function") !== -1, "Make sure the error message is present [" + ex.message + "]");
680
+ Assert.equal("TypeError", ex.typeName, "Got the correct typename [" + ex.typeName + "]");
681
+ Assert.ok(baseData.properties["columnNumber"], "has column number");
682
+ Assert.ok(baseData.properties["lineNumber"], "has Line number");
683
+ }
684
+
685
+ Assert.ok(ex.stack.length > 0, "Has stack");
686
+ Assert.ok(ex.parsedStack, "Stack was parsed");
687
+ Assert.ok(ex.hasFullStack, "Stack has been decoded");
688
+ Assert.ok(baseData.properties["url"], "has Url");
689
+ Assert.ok(baseData.properties["errorSrc"].indexOf("window.onerror@") !== -1, "has source");
690
+ }
691
+ }
692
+ }
693
+ })
694
+
695
+ });
696
+
697
+ this.testCaseAsync({
698
+ name: "OnErrorTests: _onerror logs name of unexpected error thrown by trackException for diagnostics with a text exception",
699
+ stepDelay: 1,
700
+ useFakeTimers: true,
701
+ steps: [() => {
702
+ // setup
703
+ const sender: Sender = new Sender();
704
+ const core = new AppInsightsCore();
705
+ core.initialize(
706
+ {
707
+ instrumentationKey: "key",
708
+ extensionConfig: {
709
+ [sender.identifier]: {
710
+ enableSessionStorageBuffer: false,
711
+ maxBatchInterval: 1
712
+ }
713
+ }
714
+ },
715
+ [sender]
716
+ );
717
+ const appInsights = new ApplicationInsights();
718
+ appInsights.initialize({ instrumentationKey: "key" }, core, []);
719
+ appInsights.addTelemetryInitializer((item: ITelemetryItem) => {
720
+ Assert.equal("4.0", item.ver, "Telemetry items inside telemetry initializers should be in CS4.0 format");
721
+ });
722
+
723
+ this.throwInternalSpy = this.sandbox.spy(appInsights.core.logger, "throwInternal");
724
+ sender._sender = (payload:string[], isAsync:boolean) => {
725
+ sender._onSuccess(payload, payload.length);
726
+ };
727
+ this.sandbox.spy()
728
+ this.trackSpy = this.sandbox.spy(sender, "_onSuccess");
729
+
730
+ this.exceptionHelper.capture(appInsights);
731
+ this.causeException(() => {
732
+ this.exceptionHelper.throw("Test Text Error!");
733
+ });
734
+
735
+ Assert.ok(!this.trackSpy.calledOnce, "track not called yet");
736
+ Assert.ok(!this.throwInternalSpy.called, "No internal errors");
737
+ }].concat(this.waitForException(1))
738
+ .concat(() => {
739
+
740
+ let exp = this.trackSpy.args[0];
741
+ const payloadStr: string[] = this.getPayloadMessages(this.trackSpy);
742
+ if (payloadStr.length > 0) {
743
+ const payload = JSON.parse(payloadStr[0]);
744
+ const data = payload.data;
745
+ Assert.ok(data, "Has Data");
746
+ if (data) {
747
+ Assert.ok(data.baseData, "Has BaseData");
748
+ let baseData = data.baseData;
749
+ if (baseData) {
750
+ const ex = baseData.exceptions[0];
751
+ Assert.ok(ex.message.indexOf("Test Text Error!") !== -1, "Make sure the error message is present [" + ex.message + "]");
752
+ Assert.ok(baseData.properties["columnNumber"], "has column number");
753
+ Assert.ok(baseData.properties["lineNumber"], "has Line number");
754
+ Assert.equal("String", ex.typeName, "Got the correct typename");
755
+ Assert.ok(ex.stack.length > 0, "Has stack");
756
+ Assert.ok(ex.parsedStack, "Stack was parsed");
757
+ Assert.ok(ex.hasFullStack, "Stack has been decoded");
758
+ Assert.ok(baseData.properties["url"], "has Url");
759
+ Assert.ok(baseData.properties["errorSrc"].indexOf("window.onerror@") !== -1, "has source");
760
+ }
761
+ }
762
+ }
763
+ })
764
+ });
765
+
766
+ this.testCaseAsync({
767
+ name: "OnErrorTests: _onerror logs name of unexpected error thrown by trackException for diagnostics with a custom direct exception",
768
+ stepDelay: 1,
769
+ useFakeTimers: true,
770
+ steps: [() => {
771
+ // setup
772
+ const sender: Sender = new Sender();
773
+ const core = new AppInsightsCore();
774
+ core.initialize(
775
+ {
776
+ instrumentationKey: "key",
777
+ extensionConfig: {
778
+ [sender.identifier]: {
779
+ enableSessionStorageBuffer: false,
780
+ maxBatchInterval: 1
781
+ }
782
+ }
783
+ },
784
+ [sender]
785
+ );
786
+ const appInsights = new ApplicationInsights();
787
+ appInsights.initialize({ instrumentationKey: "key" }, core, []);
788
+ appInsights.addTelemetryInitializer((item: ITelemetryItem) => {
789
+ Assert.equal("4.0", item.ver, "Telemetry items inside telemetry initializers should be in CS4.0 format");
790
+ });
791
+
792
+ this.throwInternalSpy = this.sandbox.spy(appInsights.core.logger, "throwInternal");
793
+ sender._sender = (payload:string[], isAsync:boolean) => {
794
+ sender._onSuccess(payload, payload.length);
795
+ };
796
+ this.sandbox.spy()
797
+ this.trackSpy = this.sandbox.spy(sender, "_onSuccess");
798
+
799
+ this.exceptionHelper.capture(appInsights);
800
+ this.causeException(() => {
801
+ this.exceptionHelper.throw(new CustomTestError("Test Text Error!"));
802
+ });
803
+
804
+ Assert.ok(!this.trackSpy.calledOnce, "track not called yet");
805
+ Assert.ok(!this.throwInternalSpy.called, "No internal errors");
806
+ }].concat(this.waitForException(1))
807
+ .concat(() => {
808
+
809
+ let isLocal = window.location.protocol === "file:";
810
+ let exp = this.trackSpy.args[0];
811
+ const payloadStr: string[] = this.getPayloadMessages(this.trackSpy);
812
+ if (payloadStr.length > 0) {
813
+ const payload = JSON.parse(payloadStr[0]);
814
+ const data = payload.data;
815
+ Assert.ok(data, "Has Data");
816
+ if (data) {
817
+ Assert.ok(data.baseData, "Has BaseData");
818
+ let baseData = data.baseData;
819
+ if (baseData) {
820
+ const ex = baseData.exceptions[0];
821
+ if (isLocal) {
822
+ Assert.ok(ex.message.indexOf("Script error:") !== -1, "Make sure the error message is present [" + ex.message + "]");
823
+ Assert.equal("String", ex.typeName, "Got the correct typename");
824
+ } else {
825
+ Assert.ok(ex.message.indexOf("Test Text Error!") !== -1, "Make sure the error message is present [" + ex.message + "]");
826
+ Assert.ok(ex.message.indexOf("CustomTestError") !== -1, "Make sure the error type is present [" + ex.message + "]");
827
+ Assert.equal("CustomTestError", ex.typeName, "Got the correct typename");
828
+ Assert.ok(baseData.properties["columnNumber"], "has column number");
829
+ Assert.ok(baseData.properties["lineNumber"], "has Line number");
830
+ }
831
+
832
+ Assert.ok(ex.stack.length > 0, "Has stack");
833
+ Assert.ok(ex.parsedStack, "Stack was parsed");
834
+ Assert.ok(ex.hasFullStack, "Stack has been decoded");
835
+ Assert.ok(baseData.properties["url"], "has Url");
836
+ Assert.ok(baseData.properties["errorSrc"].indexOf("window.onerror@") !== -1, "has source");
837
+ }
838
+ }
839
+ }
840
+ })
841
+ });
842
+
843
+ this.testCaseAsync({
844
+ name: "OnErrorTests: _onerror logs name of unexpected error thrown by trackException for diagnostics with a strict custom direct exception",
845
+ stepDelay: 1,
846
+ useFakeTimers: true,
847
+ steps: [() => {
848
+ // setup
849
+ const sender: Sender = new Sender();
850
+ const core = new AppInsightsCore();
851
+ core.initialize(
852
+ {
853
+ instrumentationKey: "key",
854
+ extensionConfig: {
855
+ [sender.identifier]: {
856
+ enableSessionStorageBuffer: false,
857
+ maxBatchInterval: 1
858
+ }
859
+ }
860
+ },
861
+ [sender]
862
+ );
863
+ const appInsights = new ApplicationInsights();
864
+ appInsights.initialize({ instrumentationKey: "key" }, core, []);
865
+ appInsights.addTelemetryInitializer((item: ITelemetryItem) => {
866
+ Assert.equal("4.0", item.ver, "Telemetry items inside telemetry initializers should be in CS4.0 format");
867
+ });
868
+
869
+ this.throwInternalSpy = this.sandbox.spy(appInsights.core.logger, "throwInternal");
870
+ sender._sender = (payload:string[], isAsync:boolean) => {
871
+ sender._onSuccess(payload, payload.length);
872
+ };
873
+ this.sandbox.spy()
874
+ this.trackSpy = this.sandbox.spy(sender, "_onSuccess");
875
+
876
+ this.exceptionHelper.capture(appInsights);
877
+ this.causeException(() => {
878
+ this.exceptionHelper.throwStrict(new CustomTestError("Test Text Error!"));
879
+ });
880
+
881
+ Assert.ok(!this.trackSpy.calledOnce, "track not called yet");
882
+ Assert.ok(!this.throwInternalSpy.called, "No internal errors");
883
+ }].concat(this.waitForException(1))
884
+ .concat(() => {
885
+
886
+ let isLocal = window.location.protocol === "file:";
887
+ let exp = this.trackSpy.args[0];
888
+ const payloadStr: string[] = this.getPayloadMessages(this.trackSpy);
889
+ if (payloadStr.length > 0) {
890
+ const payload = JSON.parse(payloadStr[0]);
891
+ const data = payload.data;
892
+ Assert.ok(data, "Has Data");
893
+ if (data) {
894
+ Assert.ok(data.baseData, "Has BaseData");
895
+ let baseData = data.baseData;
896
+ if (baseData) {
897
+ const ex = baseData.exceptions[0];
898
+ if (isLocal) {
899
+ Assert.ok(ex.message.indexOf("Script error:") !== -1, "Make sure the error message is present [" + ex.message + "]");
900
+ Assert.equal("String", ex.typeName, "Got the correct typename");
901
+ } else {
902
+ Assert.ok(ex.message.indexOf("Test Text Error!") !== -1, "Make sure the error message is present [" + ex.message + "]");
903
+ Assert.ok(ex.message.indexOf("CustomTestError") !== -1, "Make sure the error type is present [" + ex.message + "]");
904
+ Assert.equal("CustomTestError", ex.typeName, "Got the correct typename");
905
+ Assert.ok(baseData.properties["columnNumber"], "has column number");
906
+ Assert.ok(baseData.properties["lineNumber"], "has Line number");
907
+ }
908
+
909
+ Assert.ok(ex.stack.length > 0, "Has stack");
910
+ Assert.ok(ex.parsedStack, "Stack was parsed");
911
+ Assert.ok(ex.hasFullStack, "Stack has been decoded");
912
+ Assert.ok(baseData.properties["url"], "has Url");
913
+ Assert.ok(baseData.properties["errorSrc"].indexOf("window.onerror@") !== -1, "has source");
914
+ }
915
+ }
916
+ }
917
+ })
918
+ });
919
+ }
920
+
921
+ private throwStrictRuntimeException() {
922
+ "use strict";
923
+ function doThrow() {
924
+ var ug: any = "Hello";
925
+ // This should throw
926
+ ug();
927
+ }
928
+
929
+ doThrow();
930
+ }
931
+
932
+ private addStartStopTrackPageTests() {
933
+ const testValues = {
934
+ name: "name",
935
+ url: "url",
936
+ duration: 200,
937
+ properties: {
938
+ "property1": "5",
939
+ "property2": "10",
940
+ "refUri": "test.com"
941
+ },
942
+ measurements: {
943
+ "measurement": 300
944
+ }
945
+ };
946
+
947
+ this.testCase({
948
+ name: "Timing Tests: Start/StopPageView pass correct duration",
949
+ useFakeTimers: true,
950
+ test: () => {
951
+ // setup
952
+ const plugin = new ChannelPlugin();
953
+ const core = new AppInsightsCore();
954
+ core.initialize(
955
+ {instrumentationKey: "key"},
956
+ [plugin]
957
+ );
958
+ const appInsights = new ApplicationInsights();
959
+ appInsights.initialize({ "instrumentationKey": "ikey" }, core, []);
960
+ const spy = this.sandbox.spy(appInsights, "sendPageViewInternal");
961
+ this.clock.tick(1);
962
+
963
+ // act
964
+ appInsights.startTrackPage(testValues.name);
965
+ this.clock.tick(testValues.duration);
966
+ appInsights.stopTrackPage(testValues.name, testValues.url, testValues.properties, testValues.measurements);
967
+
968
+ // verify
969
+ Assert.ok(spy.calledOnce, "stop track page view sent data");
970
+ const actual = spy.args[0][0];
971
+ Assert.equal(testValues.name, actual.name);
972
+ Assert.equal(testValues.url, actual.uri);
973
+
974
+ const actualProperties = actual.properties;
975
+ const actualMeasurements = actual.measurements;
976
+ Assert.equal(testValues.duration, actualProperties.duration, "duration is calculated and sent correctly");
977
+ Assert.equal(testValues.properties.property1, actualProperties.property1);
978
+ Assert.equal(testValues.properties.property2, actualProperties.property2);
979
+ Assert.equal(testValues.properties.refUri, actualProperties.refUri);
980
+ Assert.equal(testValues.measurements.measurement, actualMeasurements.measurement);
981
+ }
982
+ });
983
+ this.testCase({
984
+ name: "Timing Tests: Start/StopPageView tracks single page view with no parameters",
985
+ useFakeTimers: true,
986
+ test: () => {
987
+ // setup
988
+ const core = new AppInsightsCore();
989
+ this.sandbox.stub(core, "getTransmissionControls");
990
+ const appInsights = new ApplicationInsights();
991
+ appInsights.initialize({ "instrumentationKey": "ikey" }, core, []);
992
+ const trackStub = this.sandbox.stub(appInsights.core, "track");
993
+ this.clock.tick(10); // Needed to ensure the duration calculation works
994
+
995
+ // act
996
+ appInsights.startTrackPage();
997
+ this.clock.tick(testValues.duration);
998
+ appInsights.stopTrackPage();
999
+ Assert.ok(trackStub.calledOnce, "single page view tracking stopped");
1000
+
1001
+ // verify
1002
+ const telemetry: ITelemetryItem = trackStub.args[0][0];
1003
+ Assert.equal(window.document.title, telemetry.baseData.name);
1004
+ Assert.equal(testValues.duration, telemetry.baseData.properties.duration);
1005
+ }
1006
+ });
1007
+
1008
+ this.testCase({
1009
+ name: "Timing Tests: Multiple Start/StopPageView track single pages view ",
1010
+ useFakeTimers: true,
1011
+ test: () => {
1012
+ // setup
1013
+ const core = new AppInsightsCore();
1014
+ this.sandbox.stub(core, "getTransmissionControls");
1015
+ const appInsights = new ApplicationInsights();
1016
+ appInsights.initialize({ "instrumentationKey": "ikey" }, core, []);
1017
+ const trackStub = this.sandbox.stub(appInsights.core, "track");
1018
+ this.clock.tick(10); // Needed to ensure the duration calculation works
1019
+
1020
+ // act
1021
+ appInsights.startTrackPage(testValues.name);
1022
+ this.clock.tick(testValues.duration);
1023
+
1024
+ appInsights.startTrackPage();
1025
+ this.clock.tick(testValues.duration);
1026
+ appInsights.stopTrackPage();
1027
+ Assert.ok(trackStub.calledOnce, "single page view tracking stopped no parameters");
1028
+
1029
+ this.clock.tick(testValues.duration);
1030
+ appInsights.stopTrackPage(testValues.name, testValues.url, testValues.properties);
1031
+ Assert.ok(trackStub.calledTwice, "single page view tracking stopped all parameters");
1032
+
1033
+ // verify
1034
+ // Empty parameters
1035
+ let telemetry: ITelemetryItem = trackStub.args[0][0];
1036
+ Assert.equal(window.document.title, telemetry.baseData.name);
1037
+ Assert.equal(window.document.location.href, telemetry.baseData.uri);
1038
+
1039
+ // // All parameters
1040
+ telemetry = trackStub.args[1][0];
1041
+ Assert.equal(testValues.name, telemetry.baseData.name);
1042
+ Assert.equal(testValues.url, telemetry.baseData.uri);
1043
+ Assert.deepEqual(testValues.properties, telemetry.baseData.properties);
1044
+ }
1045
+ });
1046
+
1047
+ this.testCase({
1048
+ name: "Timing Tests: Multiple startTrackPage",
1049
+ test:
1050
+ () => {
1051
+ // setup
1052
+ const plugin = new ChannelPlugin();
1053
+ const core = new AppInsightsCore();
1054
+ core.initialize(
1055
+ {instrumentationKey: "key"},
1056
+ [plugin]
1057
+ );
1058
+ const appInsights = new ApplicationInsights();
1059
+ appInsights.initialize({ "instrumentationKey": "ikey" }, core, []);
1060
+ const logStub = this.sandbox.stub(core.logger, "throwInternal");
1061
+ core.logger.consoleLoggingLevel = () => 999;
1062
+
1063
+ // act
1064
+ appInsights.startTrackPage();
1065
+ appInsights.startTrackPage();
1066
+
1067
+ // verify
1068
+ Assert.ok(logStub.calledOnce, "calling start twice triggers warning to user");
1069
+ }
1070
+ });
1071
+
1072
+ this.testCase({
1073
+ name: "Timing Tests: stopTrackPage called without a corresponding start",
1074
+ test:
1075
+ () => {
1076
+ // setup
1077
+ const plugin = new ChannelPlugin();
1078
+ const core = new AppInsightsCore();
1079
+ core.initialize(
1080
+ {instrumentationKey: "key"},
1081
+ [plugin]
1082
+ );
1083
+ const appInsights = new ApplicationInsights();
1084
+ appInsights.initialize({ "instrumentationKey": "ikey" }, core, []);
1085
+ const logStub = this.sandbox.stub(core.logger, "throwInternal");
1086
+ core.logger.consoleLoggingLevel = () => 999;
1087
+
1088
+ // act
1089
+ appInsights.stopTrackPage();
1090
+
1091
+ // verify
1092
+ Assert.ok(logStub.calledOnce, "calling stop without a corresponding start triggers warning to user");
1093
+ }
1094
+ });
1095
+ }
1096
+
1097
+ private addTrackMetricTests() {
1098
+ this.testCase({
1099
+ name: 'TrackMetricTests: trackMetric batches metrics sent in a hot loop',
1100
+ useFakeTimers: true,
1101
+ test: () => {
1102
+ // Setup
1103
+ const plugin = new ChannelPlugin();
1104
+ const core = new AppInsightsCore();
1105
+ core.initialize(
1106
+ {instrumentationKey: "key"},
1107
+ [plugin]
1108
+ );
1109
+ const appInsights = new ApplicationInsights();
1110
+ appInsights.initialize({ "instrumentationKey": "ikey" }, core, []);
1111
+ const trackStub = this.sandbox.stub(appInsights.core, "track");
1112
+
1113
+ // Act
1114
+ appInsights.trackMetric({name: "test metric", average: 0});
1115
+ this.clock.tick(1);
1116
+
1117
+ // Verify
1118
+
1119
+ Assert.ok(trackStub.calledOnce, "core.track was called once after sending one metric");
1120
+ trackStub.reset();
1121
+
1122
+ // Act
1123
+ for (let i = 0; i < 100; i++) {
1124
+ appInsights.trackMetric({name: "test metric", average: 0});
1125
+ }
1126
+ this.clock.tick(1);
1127
+
1128
+ // Test
1129
+ Assert.equal(100, trackStub.callCount, "core.track was called 100 times for sending 100 metrics");
1130
+ }
1131
+ });
1132
+ }
1133
+
1134
+ private addTelemetryInitializerTests(): void {
1135
+ this.testCase({
1136
+ name: "TelemetryContext: onBeforeSendTelemetry is called within track() and gets the envelope as an argument",
1137
+ useFakeTimers: true,
1138
+ test: () => {
1139
+ // Setup
1140
+ const plugin = new ChannelPlugin();
1141
+ const core = new AppInsightsCore();
1142
+ const appInsights = new ApplicationInsights();
1143
+ core.initialize(
1144
+ {instrumentationKey: "key"},
1145
+ [plugin, appInsights]
1146
+ );
1147
+ appInsights.initialize({ "instrumentationKey": "ikey" }, core, [plugin, appInsights]);
1148
+ plugin.initialize({instrumentationKey: 'ikey'}, core, [plugin, appInsights]);
1149
+
1150
+ const trackStub = this.sandbox.spy(appInsights.core.getTransmissionControls()[0][0], 'processTelemetry');
1151
+ const telemetryInitializer = {
1152
+ initializer: (envelope) => { }
1153
+ }
1154
+ const spy = this.sandbox.spy(telemetryInitializer, "initializer");
1155
+
1156
+ // act
1157
+ appInsights.addTelemetryInitializer(telemetryInitializer.initializer);
1158
+ appInsights.trackEvent({name: 'test event'});
1159
+ this.clock.tick(1);
1160
+
1161
+ // verify
1162
+ Assert.ok(spy.calledOnce, 'telemetryInitializer was called');
1163
+ Assert.deepEqual(trackStub.args[0][0], spy.args[0][0], 'expected envelope is used');
1164
+ }
1165
+ });
1166
+
1167
+ this.testCase({
1168
+ name: "TelemetryContext: onBeforeSendTelemetry changes the envelope props and sender gets them",
1169
+ useFakeTimers: true,
1170
+ test: () => {
1171
+ // Setup
1172
+ const plugin = new ChannelPlugin();
1173
+ const core = new AppInsightsCore();
1174
+ const appInsights = new ApplicationInsights();
1175
+ core.initialize(
1176
+ {instrumentationKey: "key"},
1177
+ [plugin, appInsights]
1178
+ );
1179
+ appInsights.initialize({ "instrumentationKey": "ikey" }, core, [plugin, appInsights]);
1180
+ plugin.initialize({instrumentationKey: 'ikey'}, core, [plugin, appInsights]);
1181
+ const trackStub = this.sandbox.spy(appInsights.core.getTransmissionControls()[0][0], 'processTelemetry');
1182
+ const nameOverride = "my unique name";
1183
+ const telemetryInitializer = {
1184
+ initializer: (envelope) => {
1185
+ envelope.name = nameOverride;
1186
+ return true;}
1187
+ }
1188
+
1189
+ // act
1190
+ appInsights.addTelemetryInitializer(telemetryInitializer.initializer);
1191
+ appInsights.trackTrace({message: 'test message'});
1192
+ this.clock.tick(1);
1193
+
1194
+ // verify
1195
+ Assert.ok(trackStub.calledOnce, "channel sender was called");
1196
+
1197
+ const envelope: ITelemetryItem = trackStub.args[0][0];
1198
+ Assert.equal(envelope.name, nameOverride, 'expected envelope is used');
1199
+ }
1200
+ });
1201
+
1202
+ this.testCase({
1203
+ name: "TelemetryContext: telemetry initializer can modify the contents of an envelope",
1204
+ test: () => {
1205
+ // Setup
1206
+ const plugin = new ChannelPlugin();
1207
+ const core = new AppInsightsCore();
1208
+ const appInsights = new ApplicationInsights();
1209
+ core.initialize(
1210
+ {instrumentationKey: "key"},
1211
+ [plugin, appInsights]
1212
+ );
1213
+ appInsights.initialize({ "instrumentationKey": "ikey" }, core, [plugin, appInsights]);
1214
+ plugin.initialize({instrumentationKey: 'ikey'}, core, [plugin, appInsights]);
1215
+ const trackStub = this.sandbox.spy(appInsights.core.getTransmissionControls()[0][0], 'processTelemetry');
1216
+
1217
+ const messageOverride = "my unique name";
1218
+ const propOverride = "val1";
1219
+ const telemetryInitializer = {
1220
+ // This illustrates how to use telemetry initializer (onBeforeSendTelemetry)
1221
+ // to access/ modify the contents of an envelope.
1222
+ initializer: (envelope) => {
1223
+ if (envelope.baseType ===
1224
+ Trace.dataType) {
1225
+ const telemetryItem = envelope.baseData;
1226
+ telemetryItem.message = messageOverride;
1227
+ telemetryItem.properties = telemetryItem.properties || {};
1228
+ telemetryItem.properties["prop1"] = propOverride;
1229
+ return true;
1230
+ }
1231
+ }
1232
+ }
1233
+
1234
+ appInsights.addTelemetryInitializer(telemetryInitializer.initializer);
1235
+
1236
+ // act
1237
+ appInsights.trackTrace({message: 'test message'});
1238
+
1239
+ // verify
1240
+ Assert.ok(trackStub.calledOnce, "sender should be called");
1241
+
1242
+ const envelope: ITelemetryItem = trackStub.args[0][0];
1243
+ Assert.equal(messageOverride, envelope.baseData.message);
1244
+ Assert.equal(propOverride, envelope.baseData.properties["prop1"]);
1245
+ }
1246
+ });
1247
+
1248
+ this.testCase({
1249
+ name: "TelemetryContext: all added telemetry initializers get invoked",
1250
+ test: () => {
1251
+ // Setup
1252
+ const plugin = new ChannelPlugin();
1253
+ const core = new AppInsightsCore();
1254
+ const appInsights = new ApplicationInsights();
1255
+ core.initialize(
1256
+ {instrumentationKey: "key"},
1257
+ [plugin, appInsights]
1258
+ );
1259
+ appInsights.initialize({ "instrumentationKey": "ikey" }, core, [plugin, appInsights]);
1260
+ plugin.initialize({instrumentationKey: 'ikey'}, core, [plugin, appInsights]);
1261
+ const initializer1 = { init: () => { } };
1262
+ const initializer2 = { init: () => { } };
1263
+ const spy1 = this.sandbox.spy(initializer1, "init");
1264
+ const spy2 = this.sandbox.spy(initializer2, "init");
1265
+
1266
+ // act
1267
+ appInsights.addTelemetryInitializer(initializer1.init);
1268
+ appInsights.addTelemetryInitializer(initializer2.init);
1269
+
1270
+ appInsights.trackTrace({message: 'test message'});
1271
+
1272
+ // verify
1273
+ Assert.ok(spy1.calledOnce);
1274
+ Assert.ok(spy2.calledOnce);
1275
+ }
1276
+ });
1277
+
1278
+ this.testCase({
1279
+ name: "TelemetryContext: all added telemetry initializers get invoked for trackException",
1280
+ test: () => {
1281
+ // Setup
1282
+ const plugin = new ChannelPlugin();
1283
+ const core = new AppInsightsCore();
1284
+ const appInsights = new ApplicationInsights();
1285
+ core.initialize(
1286
+ {instrumentationKey: "key"},
1287
+ [plugin, appInsights]
1288
+ );
1289
+ appInsights.initialize({ "instrumentationKey": "ikey" }, core, [plugin, appInsights]);
1290
+ plugin.initialize({instrumentationKey: 'ikey'}, core, [plugin, appInsights]);
1291
+ const initializer1 = { init: (item: ITelemetryItem) => {
1292
+ if (item.data !== undefined) {
1293
+ item.data.init1 = true;
1294
+ }
1295
+ } };
1296
+ const initializer2 = { init: (item: ITelemetryItem) => {
1297
+ if (item.data !== undefined) {
1298
+ item.data.init2 = true;
1299
+ }
1300
+ } };
1301
+ const spy1 = this.sandbox.spy(initializer1, "init");
1302
+ const spy2 = this.sandbox.spy(initializer2, "init");
1303
+
1304
+ // act
1305
+ appInsights.addTelemetryInitializer(initializer1.init);
1306
+ appInsights.addTelemetryInitializer(initializer2.init);
1307
+
1308
+ // Act
1309
+ appInsights._onerror({message: "msg", url: "some://url", lineNumber: 123, columnNumber: 456, error: new Error()});
1310
+
1311
+ // verify
1312
+ Assert.ok(spy1.calledOnce);
1313
+ Assert.ok(spy2.calledOnce);
1314
+ }
1315
+ });
1316
+
1317
+ this.testCase({
1318
+ name: "TelemetryContext: all added telemetry initializers get invoked for _onError calls",
1319
+ test: () => {
1320
+ // Setup
1321
+ const plugin = new ChannelPlugin();
1322
+ const core = new AppInsightsCore();
1323
+ const appInsights = new ApplicationInsights();
1324
+ core.initialize(
1325
+ {instrumentationKey: "key"},
1326
+ [plugin, appInsights]
1327
+ );
1328
+ appInsights.initialize({ "instrumentationKey": "ikey" }, core, [plugin, appInsights]);
1329
+ plugin.initialize({instrumentationKey: 'ikey'}, core, [plugin, appInsights]);
1330
+ const initializer1 = { init: () => { } };
1331
+ const initializer2 = { init: () => { } };
1332
+ const spy1 = this.sandbox.spy(initializer1, "init");
1333
+ const spy2 = this.sandbox.spy(initializer2, "init");
1334
+
1335
+ // act
1336
+ appInsights.addTelemetryInitializer(initializer1.init);
1337
+ appInsights.addTelemetryInitializer(initializer2.init);
1338
+
1339
+ appInsights.trackException({exception: new Error(), severityLevel: SeverityLevel.Critical});
1340
+
1341
+ // verify
1342
+ Assert.ok(spy1.calledOnce);
1343
+ Assert.ok(spy2.calledOnce);
1344
+ }
1345
+ });
1346
+
1347
+ this.testCase({
1348
+ name: "TelemetryContext: telemetry initializer - returning false means don't send an item",
1349
+ test: () => {
1350
+ // Setup
1351
+ const plugin = new ChannelPlugin();
1352
+ const core = new AppInsightsCore();
1353
+ const appInsights = new ApplicationInsights();
1354
+ core.initialize(
1355
+ {instrumentationKey: "key"},
1356
+ [plugin, appInsights]
1357
+ );
1358
+ appInsights.initialize({ "instrumentationKey": "ikey" }, core, [plugin, appInsights]);
1359
+ plugin.initialize({instrumentationKey: 'ikey'}, core, [plugin, appInsights]);
1360
+ const trackStub = this.sandbox.spy(appInsights.core.getTransmissionControls()[0][0], 'processTelemetry');
1361
+
1362
+ // act
1363
+ appInsights.addTelemetryInitializer(() => false);
1364
+ appInsights.trackTrace({message: 'test message'});
1365
+
1366
+ // verify
1367
+ Assert.ok(trackStub.notCalled);
1368
+ }
1369
+ });
1370
+
1371
+ this.testCase({
1372
+ name: "TelemetryContext: telemetry initializer - returning void means do send an item (back compact with older telemetry initializers)",
1373
+ test: () => {
1374
+ // Setup
1375
+ const plugin = new ChannelPlugin();
1376
+ const core = new AppInsightsCore();
1377
+ const appInsights = new ApplicationInsights();
1378
+ core.initialize(
1379
+ {instrumentationKey: "key"},
1380
+ [plugin, appInsights]
1381
+ );
1382
+ appInsights.initialize({ "instrumentationKey": "ikey" }, core, [plugin, appInsights]);
1383
+ plugin.initialize({instrumentationKey: 'ikey'}, core, [plugin, appInsights]);
1384
+ const trackStub = this.sandbox.spy(appInsights.core.getTransmissionControls()[0][0], 'processTelemetry');
1385
+
1386
+ // act
1387
+ appInsights.addTelemetryInitializer(() => { return; });
1388
+ appInsights.trackTrace({message: 'test message'});
1389
+
1390
+ // verify
1391
+ Assert.ok(trackStub.calledOnce); // TODO: use sender
1392
+ }
1393
+ });
1394
+
1395
+ this.testCase({
1396
+ name: "TelemetryContext: telemetry initializer - returning true means do send an item",
1397
+ test: () => {
1398
+ // Setup
1399
+ const plugin = new ChannelPlugin();
1400
+ const core = new AppInsightsCore();
1401
+ const appInsights = new ApplicationInsights();
1402
+ core.initialize(
1403
+ {instrumentationKey: "key"},
1404
+ [plugin, appInsights]
1405
+ );
1406
+ appInsights.initialize({ "instrumentationKey": "ikey" }, core, [plugin, appInsights]);
1407
+ plugin.initialize({instrumentationKey: 'ikey'}, core, [plugin, appInsights]);
1408
+ const trackStub = this.sandbox.spy(appInsights.core.getTransmissionControls()[0][0], 'processTelemetry');
1409
+
1410
+ // act
1411
+ appInsights.addTelemetryInitializer(() => true);
1412
+ appInsights.trackTrace({message: 'test message'});
1413
+
1414
+ // verify
1415
+ Assert.ok(trackStub.calledOnce);
1416
+ }
1417
+ });
1418
+
1419
+ this.testCase({
1420
+ name: "TelemetryContext: telemetry initializer - if one of initializers returns false than item is not sent",
1421
+ test: () => {
1422
+ // Setup
1423
+ const plugin = new ChannelPlugin();
1424
+ const core = new AppInsightsCore();
1425
+ const appInsights = new ApplicationInsights();
1426
+ core.initialize(
1427
+ {instrumentationKey: "key"},
1428
+ [plugin, appInsights]
1429
+ );
1430
+ appInsights.initialize({ "instrumentationKey": "ikey" }, core, [plugin, appInsights]);
1431
+ plugin.initialize({instrumentationKey: 'ikey'}, core, [plugin, appInsights]);
1432
+ const trackStub = this.sandbox.spy(appInsights.core.getTransmissionControls()[0][0], 'processTelemetry');
1433
+
1434
+ // act
1435
+ appInsights.addTelemetryInitializer(() => true);
1436
+ appInsights.addTelemetryInitializer(() => false);
1437
+
1438
+ appInsights.trackTrace({message: 'test message'});
1439
+
1440
+ // verify
1441
+ Assert.ok(trackStub.notCalled);
1442
+ }
1443
+ });
1444
+
1445
+ this.testCase({
1446
+ name: "TelemetryContext: telemetry initializer - if one of initializers returns false (any order) than item is not sent",
1447
+ test: () => {
1448
+ // Setup
1449
+ const plugin = new ChannelPlugin();
1450
+ const core = new AppInsightsCore();
1451
+ const appInsights = new ApplicationInsights();
1452
+ core.initialize(
1453
+ {instrumentationKey: "key"},
1454
+ [plugin, appInsights]
1455
+ );
1456
+ appInsights.initialize({ "instrumentationKey": "ikey" }, core, [plugin, appInsights]);
1457
+ plugin.initialize({instrumentationKey: 'ikey'}, core, [plugin, appInsights]);
1458
+ const trackStub = this.sandbox.spy(appInsights.core.getTransmissionControls()[0][0], 'processTelemetry');
1459
+
1460
+ // act
1461
+ appInsights.addTelemetryInitializer(() => false);
1462
+ appInsights.addTelemetryInitializer(() => true);
1463
+
1464
+ appInsights.trackTrace({message: 'test message'});
1465
+
1466
+ // verify
1467
+ Assert.ok(trackStub.notCalled);
1468
+ }
1469
+ });
1470
+
1471
+ this.testCase({
1472
+ name: "TelemetryContext: telemetry initializer - returning not boolean/undefined/null means do send an item (back compat with older telemetry initializers)",
1473
+ test: () => {
1474
+ // Setup
1475
+ const plugin = new ChannelPlugin();
1476
+ const core = new AppInsightsCore();
1477
+ const appInsights = new ApplicationInsights();
1478
+ core.initialize(
1479
+ {instrumentationKey: "key"},
1480
+ [plugin, appInsights]
1481
+ );
1482
+ appInsights.initialize({ "instrumentationKey": "ikey" }, core, [plugin, appInsights]);
1483
+ plugin.initialize({instrumentationKey: 'ikey'}, core, [plugin, appInsights]);
1484
+ const trackStub = this.sandbox.spy(appInsights.core.getTransmissionControls()[0][0], 'processTelemetry');
1485
+
1486
+ // act
1487
+ appInsights.addTelemetryInitializer((() => "asdf") as any);
1488
+ appInsights.addTelemetryInitializer(() => null);
1489
+ appInsights.addTelemetryInitializer(() => undefined);
1490
+ appInsights.trackTrace({message: 'test message'});
1491
+
1492
+ // verify
1493
+ Assert.ok(trackStub.calledOnce); // TODO: use sender
1494
+ }
1495
+ });
1496
+
1497
+ this.testCase({
1498
+ name: "TelemetryContext: telemetry initializer - if one initializer fails then error logged and is still sent",
1499
+ test: () => {
1500
+ // Setup
1501
+ const plugin = new ChannelPlugin();
1502
+ const core = new AppInsightsCore();
1503
+ const appInsights = new ApplicationInsights();
1504
+ core.initialize(
1505
+ {instrumentationKey: "key"},
1506
+ [plugin, appInsights]
1507
+ );
1508
+ appInsights.initialize({ "instrumentationKey": "ikey" }, core, [plugin, appInsights]);
1509
+ plugin.initialize({instrumentationKey: 'ikey'}, core, [plugin, appInsights]);
1510
+ const trackStub = this.sandbox.spy(appInsights.core.getTransmissionControls()[0][0], 'processTelemetry');
1511
+ const logStub = this.sandbox.spy(appInsights.core.logger, "throwInternal")
1512
+ // act
1513
+ appInsights.addTelemetryInitializer(() => { throw new Error("Test error IGNORE"); });
1514
+ appInsights.addTelemetryInitializer(() => { });
1515
+ appInsights.trackTrace({message: 'test message'});
1516
+
1517
+ // verify
1518
+ Assert.ok(trackStub.calledOnce);
1519
+ Assert.ok(logStub.calledOnce);
1520
+
1521
+ }
1522
+ });
1523
+ }
1524
+
1525
+ private getFirstResult(action: string, trackStub: SinonStub, skipSessionState?: boolean): ITelemetryItem {
1526
+ const index: number = skipSessionState ? 1 : 0;
1527
+
1528
+ Assert.ok(trackStub.args && trackStub.args[index] && trackStub.args[index][0], "track was called for: " + action);
1529
+ return trackStub.args[index][0] as ITelemetryItem;
1530
+ }
1531
+
1532
+ private checkNoInternalErrors() {
1533
+ if (this.throwInternalSpy) {
1534
+ Assert.ok(this.throwInternalSpy.notCalled, "Check no internal errors");
1535
+ if (this.throwInternalSpy.called) {
1536
+ Assert.ok(false, JSON.stringify(this.throwInternalSpy.args[0]));
1537
+ }
1538
+ }
1539
+ }
1540
+
1541
+ private waitForException: any = (expectedCount:number, action: string = "", includeInit:boolean = false) => [
1542
+ () => {
1543
+ const message = "polling: " + new Date().toISOString() + " " + action;
1544
+ Assert.ok(true, message);
1545
+ console.log(message);
1546
+ this.checkNoInternalErrors();
1547
+ this.clock.tick(500);
1548
+ },
1549
+ (PollingAssert.createPollingAssert(() => {
1550
+ this.checkNoInternalErrors();
1551
+ let argCount = 0;
1552
+ if (this.trackSpy.called) {
1553
+ this.trackSpy.args.forEach(call => {
1554
+ argCount += call.length;
1555
+ });
1556
+ }
1557
+
1558
+ Assert.ok(true, "* [" + argCount + " of " + expectedCount + "] checking spy " + new Date().toISOString());
1559
+
1560
+ try {
1561
+ if (argCount >= expectedCount) {
1562
+ const payload = JSON.parse(this.trackSpy.args[0][0]);
1563
+ const baseType = payload.data.baseType;
1564
+ // call the appropriate Validate depending on the baseType
1565
+ switch (baseType) {
1566
+ case Event.dataType:
1567
+ return EventValidator.EventValidator.Validate(payload, baseType);
1568
+ case Trace.dataType:
1569
+ return TraceValidator.TraceValidator.Validate(payload, baseType);
1570
+ case Exception.dataType:
1571
+ return ExceptionValidator.ExceptionValidator.Validate(payload, baseType);
1572
+ case Metric.dataType:
1573
+ return MetricValidator.MetricValidator.Validate(payload, baseType);
1574
+ case PageView.dataType:
1575
+ return PageViewValidator.PageViewValidator.Validate(payload, baseType);
1576
+ case PageViewPerformance.dataType:
1577
+ return PageViewPerformanceValidator.PageViewPerformanceValidator.Validate(payload, baseType);
1578
+ case RemoteDependencyData.dataType:
1579
+ return RemoteDepdencyValidator.RemoteDepdencyValidator.Validate(payload, baseType);
1580
+
1581
+ default:
1582
+ return EventValidator.EventValidator.Validate(payload, baseType);
1583
+ }
1584
+ }
1585
+ } finally {
1586
+ this.clock.tick(500);
1587
+ }
1588
+
1589
+ return false;
1590
+ }, "sender succeeded", 10, 1000))
1591
+ ];
1592
+ }
1593
+
1594
+ class ChannelPlugin implements IPlugin {
1595
+
1596
+ public isFlushInvoked = false;
1597
+ public isTearDownInvoked = false;
1598
+ public isResumeInvoked = false;
1599
+ public isPauseInvoked = false;
1600
+
1601
+ public identifier = "Sender";
1602
+
1603
+ public priority: number = 1001;
1604
+
1605
+ constructor() {
1606
+ this.processTelemetry = this._processTelemetry.bind(this);
1607
+ }
1608
+ public pause(): void {
1609
+ this.isPauseInvoked = true;
1610
+ }
1611
+
1612
+ public resume(): void {
1613
+ this.isResumeInvoked = true;
1614
+ }
1615
+
1616
+ public teardown(): void {
1617
+ this.isTearDownInvoked = true;
1618
+ }
1619
+
1620
+ flush(async?: boolean, callBack?: () => void): void {
1621
+ this.isFlushInvoked = true;
1622
+ if (callBack) {
1623
+ callBack();
1624
+ }
1625
+ }
1626
+
1627
+ public processTelemetry(env: ITelemetryItem) {}
1628
+
1629
+ setNextPlugin(next: any) {
1630
+ // no next setup
1631
+ }
1632
+
1633
+ public initialize = (config: IConfiguration, core: IAppInsightsCore, plugin: IPlugin[]) => {
1634
+ }
1635
+
1636
+ private _processTelemetry(env: ITelemetryItem) {
1637
+
1638
+ }
1639
+ }
1640
+
1641
+ class CustomTestError extends Error {
1642
+ constructor(message = "") {
1643
+ super(message);
1644
+ this.name = "CustomTestError";
1645
+ this.message = message + " -- test error.";
1646
+ }
1647
+ }