Beta Part 5: Part of Mega Dynamic Load/Unload support (#1782)
- Add Missing Exports - AnalyticsPlugin: Implement teardown and initial test validation - Dependencies Plugin: Implement teardown and initial test validation - Add flush() to IAppInsightsCore
This commit is contained in:
Родитель
4936a52cee
Коммит
f2d1625a1e
|
@ -16,7 +16,7 @@ export class SenderTests extends AITestClass {
|
|||
this._offline = createOfflineListener("SenderTests");
|
||||
}
|
||||
|
||||
public testCleanup() {
|
||||
public testFinishedCleanup() {
|
||||
if (this._offline) {
|
||||
this._offline.unload();
|
||||
}
|
||||
|
|
|
@ -78,6 +78,16 @@ export class AITestClass {
|
|||
public fakeServerAutoRespond: boolean = false;
|
||||
public isEmulatingEs3: boolean;
|
||||
|
||||
/**
|
||||
* Automatically assert that all registered events have been removed
|
||||
*/
|
||||
public assertNoEvents: boolean = false;
|
||||
|
||||
/**
|
||||
* Automatically assert that all hooks have been removed
|
||||
*/
|
||||
public assertNoHooks: boolean = false;
|
||||
|
||||
protected _orgCrypto: Crypto | null;
|
||||
protected _orgLocation: Location | null;
|
||||
|
||||
|
@ -96,6 +106,8 @@ export class AITestClass {
|
|||
private _orgObjectFuncs: any = null;
|
||||
private _orgFetch: any = null;
|
||||
|
||||
private _onDoneFuncs: VoidFunction[] = [];
|
||||
|
||||
constructor(name?: string, emulateEs3?: boolean) {
|
||||
this._moduleName = (emulateEs3 ? "(ES3) " : "") + (name || _getObjName(this, ""));
|
||||
this.isEmulatingEs3 = emulateEs3
|
||||
|
@ -122,7 +134,24 @@ export class AITestClass {
|
|||
public testInitialize() {
|
||||
}
|
||||
|
||||
/** Method called after each test method has completed */
|
||||
/**
|
||||
* Method called immediately after the test case has finished, but before the automatic test case assertions.
|
||||
* Use this method to call unload / teardown so the SDK can remove it's own events before being validated
|
||||
*/
|
||||
public testFinishedCleanup() {
|
||||
this._onDoneFuncs.forEach((fn) => {
|
||||
try {
|
||||
fn();
|
||||
} catch (e) {
|
||||
// Do nothing during cleanup
|
||||
}
|
||||
});
|
||||
this._onDoneFuncs = [];
|
||||
}
|
||||
|
||||
/** Method called after each test method has completed and after the test sandbox has been cleanup up.
|
||||
* This is the final step before the next test is executed
|
||||
*/
|
||||
public testCleanup() {
|
||||
}
|
||||
|
||||
|
@ -185,14 +214,29 @@ export class AITestClass {
|
|||
this._emulateEs3();
|
||||
}
|
||||
|
||||
if (testInfo.assertNoEvents === undefined) {
|
||||
testInfo.assertNoEvents = this.assertNoEvents;
|
||||
}
|
||||
|
||||
if (testInfo.assertNoHooks === undefined) {
|
||||
testInfo.assertNoHooks = this.assertNoHooks;
|
||||
}
|
||||
|
||||
// Run the test.
|
||||
try {
|
||||
let self = this;
|
||||
let testComplete = false;
|
||||
let timeOutTimer: any = null;
|
||||
let stepIndex = 0;
|
||||
|
||||
|
||||
const testDone = () => {
|
||||
this._onDoneFuncs.forEach((fn) => {
|
||||
fn();
|
||||
});
|
||||
this._onDoneFuncs = [];
|
||||
|
||||
self.testFinishedCleanup();
|
||||
|
||||
if (testInfo.assertNoEvents) {
|
||||
self._assertEventsRemoved();
|
||||
}
|
||||
|
@ -325,6 +369,8 @@ export class AITestClass {
|
|||
AITestClass.currentTestInfo = testInfo;
|
||||
|
||||
function _testFinished(failed?: boolean) {
|
||||
self.testFinishedCleanup();
|
||||
|
||||
if (testInfo.assertNoEvents) {
|
||||
self._assertEventsRemoved();
|
||||
}
|
||||
|
@ -366,6 +412,14 @@ export class AITestClass {
|
|||
this._emulateEs3();
|
||||
}
|
||||
|
||||
if (testInfo.assertNoEvents === undefined) {
|
||||
testInfo.assertNoEvents = this.assertNoEvents;
|
||||
}
|
||||
|
||||
if (testInfo.assertNoHooks === undefined) {
|
||||
testInfo.assertNoHooks = this.assertNoHooks;
|
||||
}
|
||||
|
||||
// Run the test.
|
||||
try {
|
||||
this._testStarting();
|
||||
|
@ -472,6 +526,12 @@ export class AITestClass {
|
|||
Assert.ok(false, msg);
|
||||
}
|
||||
|
||||
protected onDone(cleanupFn: VoidFunction) {
|
||||
if (cleanupFn) {
|
||||
this._onDoneFuncs.push(cleanupFn);
|
||||
}
|
||||
}
|
||||
|
||||
protected setUserAgent(userAgent: string) {
|
||||
// Hook Send beacon which also mocks navigator
|
||||
this.hookSendBeacon(null);
|
||||
|
@ -829,6 +889,7 @@ export class AITestClass {
|
|||
|
||||
this._beaconHooks = [];
|
||||
this._cleanupAllHooks();
|
||||
this._cleanupEvents();
|
||||
this._restoreEs3();
|
||||
|
||||
if (failed) {
|
||||
|
@ -841,7 +902,6 @@ export class AITestClass {
|
|||
}
|
||||
|
||||
this.testCleanup();
|
||||
this._cleanupEvents();
|
||||
|
||||
// Clear the instance of the currently running suite.
|
||||
AITestClass.currentTestClass = null;
|
||||
|
@ -849,13 +909,20 @@ export class AITestClass {
|
|||
}
|
||||
|
||||
private _assertRemoveFuncHooks(fn:any, targetName: string) {
|
||||
let failed = false;
|
||||
|
||||
if (typeof fn === "function") {
|
||||
let aiHook:any = fn["_aiHooks"];
|
||||
|
||||
if (aiHook && aiHook.h) {
|
||||
aiHook.h.forEach((hook: any) => {
|
||||
Assert.ok(false, targetName + " Hook: " + aiHook.n + "." + _formatNamespace(hook.cbks.ns || "") + " exists");
|
||||
failed = true;
|
||||
});
|
||||
|
||||
if (!failed) {
|
||||
QUnit.assert.ok(true, "Validated [" + targetName + "] has no registered hooks");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -864,7 +931,7 @@ export class AITestClass {
|
|||
if (target) {
|
||||
Object.keys(target).forEach(name => {
|
||||
try {
|
||||
this._assertRemoveFuncHooks(target[name], targetName);
|
||||
this._assertRemoveFuncHooks(target[name], targetName + "." + name);
|
||||
} catch (e) {
|
||||
// eslint-disable-next-line no-empty
|
||||
}
|
||||
|
@ -994,17 +1061,29 @@ export class AITestClass {
|
|||
}
|
||||
|
||||
private _assertNoEvents(target: any, targetName: string): void {
|
||||
let failed = false;
|
||||
_getAllAiDataKeys(target, (name, value) => {
|
||||
if (value && name.startsWith("_aiDataEvents")) {
|
||||
let events = value.events;
|
||||
_objForEachKey(events, (evtName, evts) => {
|
||||
for (let lp = 0; lp < evts.length; lp++) {
|
||||
let theEvent = evts[lp];
|
||||
Assert.ok(false, "[" + targetName + "] has registered event handler [" + evtName + "." + (theEvent.evtName.ns || "") + "]");
|
||||
}
|
||||
});
|
||||
if (events) {
|
||||
_objForEachKey(events, (evtName, evts) => {
|
||||
if (evts) {
|
||||
for (let lp = 0; lp < evts.length; lp++) {
|
||||
let theEvent = evts[lp];
|
||||
if (theEvent) {
|
||||
Assert.ok(false, "[" + targetName + "] has registered event handler [" + evtName + "." + (theEvent.evtName.ns || "") + "]");
|
||||
failed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (!failed) {
|
||||
QUnit.assert.ok(true, "Validated [" + targetName + "] has no registered event handlers");
|
||||
}
|
||||
}
|
||||
|
||||
private _removeAllEvents(target: any, targetName: string): any {
|
||||
|
@ -1013,15 +1092,21 @@ export class AITestClass {
|
|||
if (value && name.startsWith("_aiDataEvents")) {
|
||||
dataName.push(name);
|
||||
let events = value.events;
|
||||
_objForEachKey(events, (evtName, evts) => {
|
||||
for (let lp = 0; lp < evts.length; lp++) {
|
||||
let theEvent = evts[lp];
|
||||
console && console.log("Removing [" + targetName + "] event handler " + evtName + "." + (theEvent.evtName.ns || ""));
|
||||
if (target.removeEventListener) {
|
||||
target.removeEventListener(evtName, theEvent.handler, theEvent.capture);
|
||||
if (events) {
|
||||
_objForEachKey(events, (evtName, evts) => {
|
||||
if (evts) {
|
||||
for (let lp = 0; lp < evts.length; lp++) {
|
||||
let theEvent = evts[lp];
|
||||
if (theEvent) {
|
||||
console && console.log("Removing [" + targetName + "] event handler " + evtName + "." + (theEvent.evtName.ns || ""));
|
||||
if (target.removeEventListener) {
|
||||
target.removeEventListener(evtName, theEvent.handler, theEvent.capture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
delete value.events;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,12 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
private throwInternalSpy:SinonSpy;
|
||||
private exceptionHelper: any = new ExceptionHelper();
|
||||
|
||||
constructor(name?: string, emulateEs3?: boolean) {
|
||||
super(name, emulateEs3);
|
||||
this.assertNoEvents = true;
|
||||
this.assertNoHooks = true;
|
||||
}
|
||||
|
||||
public testInitialize() {
|
||||
this._onerror = window.onerror;
|
||||
setEnableEnvMocks(false);
|
||||
|
@ -59,8 +65,6 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
|
||||
this.testCase({
|
||||
name: 'enableAutoRouteTracking: event listener is added to the popstate event',
|
||||
assertNoEvents: true,
|
||||
assertNoHooks: true,
|
||||
test: () => {
|
||||
// Setup
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
|
@ -72,6 +76,10 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
let registeredEvents = __getRegisteredEvents(window, null, evtNamespace);
|
||||
Assert.equal(0, registeredEvents.length, "No Events should be registered");
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
// Act
|
||||
core.initialize({
|
||||
instrumentationKey: '',
|
||||
|
@ -90,8 +98,6 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
|
||||
registeredEvents = __getRegisteredEvents(window, null, evtNamespace);
|
||||
Assert.equal(0, registeredEvents.length, "All Events should have been removed");
|
||||
|
||||
core.unload();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -117,6 +123,12 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
let registeredEvents = __getRegisteredEvents(window, null, evtNamespace);
|
||||
Assert.equal(0, registeredEvents.length, "No Events should be registered");
|
||||
|
||||
this.onDone(() => {
|
||||
if (core.isInitialized()) {
|
||||
core.unload(false);
|
||||
}
|
||||
});
|
||||
|
||||
// Act
|
||||
core.initialize({
|
||||
instrumentationKey: '',
|
||||
|
@ -169,6 +181,10 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
appInsights['_prevUri'] = "firstUri";
|
||||
const trackPageViewStub = this.sandbox.stub(appInsights, 'trackPageView');
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
// Act
|
||||
core.initialize({
|
||||
instrumentationKey: '',
|
||||
|
@ -211,6 +227,10 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
properties.context = { telemetryTrace: { traceID: 'not set', parentID: undefined} } as any;
|
||||
this.sandbox.stub(appInsights, 'trackPageView');
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
// Act
|
||||
core.initialize({
|
||||
instrumentationKey: '',
|
||||
|
@ -240,6 +260,10 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
instrumentationKey: 'ikey'
|
||||
};
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
config,
|
||||
[appInsights, channel]
|
||||
|
@ -265,6 +289,11 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
instrumentationKey: 'ikey',
|
||||
autoTrackPageVisitTime: true
|
||||
};
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
config,
|
||||
[appInsights, channel]
|
||||
|
@ -304,6 +333,10 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
}
|
||||
};
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
// Initialize
|
||||
core.initialize(config, [appInsights, channel, properties]);
|
||||
|
||||
|
@ -379,7 +412,12 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
[plugin]
|
||||
);
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
appInsights.initialize({instrumentationKey: core.config.instrumentationKey}, core, []);
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.addPlugin(appInsights);
|
||||
const trackStub = this.sandbox.stub(appInsights.core, "track");
|
||||
|
||||
let envelope: ITelemetryItem;
|
||||
|
@ -410,12 +448,17 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
// setup
|
||||
const plugin = new ChannelPlugin();
|
||||
const core = new AppInsightsCore();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{instrumentationKey: "key"},
|
||||
{instrumentationKey: "ikey"},
|
||||
[plugin]
|
||||
);
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
appInsights.initialize({ "instrumentationKey": "ikey" }, core, []);
|
||||
core.addPlugin(appInsights);
|
||||
const senderStub = this.sandbox.stub(appInsights.core, "track");
|
||||
|
||||
// Act
|
||||
|
@ -436,12 +479,17 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
// setup
|
||||
const plugin = new ChannelPlugin();
|
||||
const core = new AppInsightsCore();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{instrumentationKey: "key"},
|
||||
{instrumentationKey: "ikey"},
|
||||
[plugin]
|
||||
);
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
appInsights.initialize({ "instrumentationKey": "ikey" }, core, []);
|
||||
core.addPlugin(appInsights);
|
||||
const trackStub = this.sandbox.stub(appInsights.core, "track");
|
||||
|
||||
// Test
|
||||
|
@ -461,12 +509,17 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
// setup
|
||||
const plugin = new ChannelPlugin();
|
||||
const core = new AppInsightsCore();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{instrumentationKey: "key"},
|
||||
{instrumentationKey: "ikey"},
|
||||
[plugin]
|
||||
);
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
appInsights.initialize({ "instrumentationKey": "ikey" }, core, []);
|
||||
core.addPlugin(appInsights);
|
||||
const trackStub = this.sandbox.stub(appInsights.core, "track");
|
||||
|
||||
// Test
|
||||
|
@ -490,12 +543,17 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
// setup
|
||||
const plugin = new ChannelPlugin();
|
||||
const core = new AppInsightsCore();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{instrumentationKey: "key"},
|
||||
{instrumentationKey: "ikey"},
|
||||
[plugin]
|
||||
);
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
appInsights.initialize({ "instrumentationKey": "ikey" }, core, []);
|
||||
core.addPlugin(appInsights);
|
||||
|
||||
const unexpectedError = new Error();
|
||||
const expectedString = dumpObj(unexpectedError);
|
||||
|
@ -520,12 +578,17 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
// setup
|
||||
const plugin = new ChannelPlugin();
|
||||
const core = new AppInsightsCore();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{instrumentationKey: "key"},
|
||||
{instrumentationKey: "ikey"},
|
||||
[plugin]
|
||||
);
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
appInsights.initialize({ instrumentationKey: "ikey"}, core, []);
|
||||
core.addPlugin(appInsights);
|
||||
const unexpectedError = new Error("some message");
|
||||
const throwSpy = this.sandbox.spy(core.logger, "throwInternal");
|
||||
const stub = this.sandbox.stub(appInsights, "trackException").throws(unexpectedError);
|
||||
|
@ -547,12 +610,17 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
// setup
|
||||
const plugin = new ChannelPlugin();
|
||||
const core = new AppInsightsCore();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{instrumentationKey: "key"},
|
||||
[plugin]
|
||||
);
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
appInsights.initialize({ instrumentationKey: "key" }, core, []);
|
||||
core.addPlugin(appInsights);
|
||||
|
||||
const throwInternal = this.sandbox.spy(appInsights.core.logger, "throwInternal");
|
||||
|
||||
|
@ -573,12 +641,17 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
// setup
|
||||
const plugin = new ChannelPlugin();
|
||||
const core = new AppInsightsCore();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{instrumentationKey: "key"},
|
||||
{instrumentationKey: "ikey"},
|
||||
[plugin]
|
||||
);
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
appInsights.initialize({ "instrumentationKey": "ikey" }, core, []);
|
||||
core.addPlugin(appInsights);
|
||||
const trackSpy = this.sandbox.spy(appInsights.core, "track");
|
||||
|
||||
// Act
|
||||
|
@ -595,12 +668,17 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
// setup
|
||||
const plugin = new ChannelPlugin();
|
||||
const core = new AppInsightsCore();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{instrumentationKey: "key"},
|
||||
{instrumentationKey: "ikey"},
|
||||
[plugin]
|
||||
);
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
appInsights.initialize({ "instrumentationKey": "ikey" }, core, []);
|
||||
core.addPlugin(appInsights);
|
||||
const trackExceptionSpy = this.sandbox.spy(appInsights, "trackException");
|
||||
|
||||
// Act
|
||||
|
@ -619,12 +697,17 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
// setup
|
||||
const plugin = new ChannelPlugin();
|
||||
const core = new AppInsightsCore();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{instrumentationKey: "key"},
|
||||
[plugin]
|
||||
);
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
appInsights.initialize({ instrumentationKey: "key" }, core, []);
|
||||
core.addPlugin(appInsights);
|
||||
|
||||
const throwInternal = this.sandbox.spy(appInsights.core.logger, "throwInternal");
|
||||
|
||||
|
@ -653,6 +736,11 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
// setup
|
||||
const sender: Sender = new Sender();
|
||||
const core = new AppInsightsCore();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{
|
||||
instrumentationKey: "key",
|
||||
|
@ -666,7 +754,7 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
[sender]
|
||||
);
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
appInsights.initialize({ instrumentationKey: "key" }, core, []);
|
||||
core.addPlugin(appInsights);
|
||||
appInsights.addTelemetryInitializer((item: ITelemetryItem) => {
|
||||
Assert.equal("4.0", item.ver, "Telemetry items inside telemetry initializers should be in CS4.0 format");
|
||||
});
|
||||
|
@ -731,6 +819,11 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
// setup
|
||||
const sender: Sender = new Sender();
|
||||
const core = new AppInsightsCore();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{
|
||||
instrumentationKey: "key",
|
||||
|
@ -744,7 +837,7 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
[sender]
|
||||
);
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
appInsights.initialize({ instrumentationKey: "key" }, core, []);
|
||||
core.addPlugin(appInsights);
|
||||
appInsights.addTelemetryInitializer((item: ITelemetryItem) => {
|
||||
Assert.equal("4.0", item.ver, "Telemetry items inside telemetry initializers should be in CS4.0 format");
|
||||
});
|
||||
|
@ -800,6 +893,11 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
// setup
|
||||
const sender: Sender = new Sender();
|
||||
const core = new AppInsightsCore();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{
|
||||
instrumentationKey: "key",
|
||||
|
@ -813,7 +911,7 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
[sender]
|
||||
);
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
appInsights.initialize({ instrumentationKey: "key" }, core, []);
|
||||
core.addPlugin(appInsights);
|
||||
appInsights.addTelemetryInitializer((item: ITelemetryItem) => {
|
||||
Assert.equal("4.0", item.ver, "Telemetry items inside telemetry initializers should be in CS4.0 format");
|
||||
});
|
||||
|
@ -877,6 +975,11 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
// setup
|
||||
const sender: Sender = new Sender();
|
||||
const core = new AppInsightsCore();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{
|
||||
instrumentationKey: "key",
|
||||
|
@ -890,7 +993,7 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
[sender]
|
||||
);
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
appInsights.initialize({ instrumentationKey: "key" }, core, []);
|
||||
core.addPlugin(appInsights);
|
||||
appInsights.addTelemetryInitializer((item: ITelemetryItem) => {
|
||||
Assert.equal("4.0", item.ver, "Telemetry items inside telemetry initializers should be in CS4.0 format");
|
||||
});
|
||||
|
@ -980,12 +1083,17 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
// setup
|
||||
const plugin = new ChannelPlugin();
|
||||
const core = new AppInsightsCore();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{instrumentationKey: "key"},
|
||||
[plugin]
|
||||
);
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
appInsights.initialize({ "instrumentationKey": "ikey" }, core, []);
|
||||
core.addPlugin(appInsights);
|
||||
const spy = this.sandbox.spy(appInsights, "sendPageViewInternal");
|
||||
this.clock.tick(1);
|
||||
|
||||
|
@ -1015,8 +1123,13 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
test: () => {
|
||||
// setup
|
||||
const core = new AppInsightsCore();
|
||||
|
||||
this.sandbox.stub(core, "getTransmissionControls");
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
this.onDone(() => {
|
||||
appInsights.teardown();
|
||||
});
|
||||
|
||||
appInsights.initialize({ "instrumentationKey": "ikey" }, core, []);
|
||||
const trackStub = this.sandbox.stub(appInsights.core, "track");
|
||||
this.clock.tick(10); // Needed to ensure the duration calculation works
|
||||
|
@ -1040,8 +1153,13 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
test: () => {
|
||||
// setup
|
||||
const core = new AppInsightsCore();
|
||||
|
||||
this.sandbox.stub(core, "getTransmissionControls");
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
this.onDone(() => {
|
||||
appInsights.teardown();
|
||||
});
|
||||
|
||||
appInsights.initialize({ "instrumentationKey": "ikey" }, core, []);
|
||||
const trackStub = this.sandbox.stub(appInsights.core, "track");
|
||||
this.clock.tick(10); // Needed to ensure the duration calculation works
|
||||
|
@ -1080,12 +1198,17 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
// setup
|
||||
const plugin = new ChannelPlugin();
|
||||
const core = new AppInsightsCore();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{instrumentationKey: "key"},
|
||||
{instrumentationKey: "ikey"},
|
||||
[plugin]
|
||||
);
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
appInsights.initialize({ "instrumentationKey": "ikey" }, core, []);
|
||||
core.addPlugin(appInsights);
|
||||
const logStub = this.sandbox.stub(core.logger, "throwInternal");
|
||||
core.logger.consoleLoggingLevel = () => 999;
|
||||
|
||||
|
@ -1105,12 +1228,17 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
// setup
|
||||
const plugin = new ChannelPlugin();
|
||||
const core = new AppInsightsCore();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{instrumentationKey: "key"},
|
||||
{instrumentationKey: "ikey"},
|
||||
[plugin]
|
||||
);
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
appInsights.initialize({ "instrumentationKey": "ikey" }, core, []);
|
||||
core.addPlugin(appInsights);
|
||||
const logStub = this.sandbox.stub(core.logger, "throwInternal");
|
||||
core.logger.consoleLoggingLevel = () => 999;
|
||||
|
||||
|
@ -1131,12 +1259,17 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
// Setup
|
||||
const plugin = new ChannelPlugin();
|
||||
const core = new AppInsightsCore();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{instrumentationKey: "key"},
|
||||
{instrumentationKey: "ikey"},
|
||||
[plugin]
|
||||
);
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
appInsights.initialize({ "instrumentationKey": "ikey" }, core, []);
|
||||
core.addPlugin(appInsights);
|
||||
const trackStub = this.sandbox.stub(appInsights.core, "track");
|
||||
|
||||
// Act
|
||||
|
@ -1169,12 +1302,15 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
const plugin = new ChannelPlugin();
|
||||
const core = new AppInsightsCore();
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{instrumentationKey: "key"},
|
||||
{instrumentationKey: "ikey"},
|
||||
[plugin, appInsights]
|
||||
);
|
||||
appInsights.initialize({ "instrumentationKey": "ikey" }, core, [plugin, appInsights]);
|
||||
plugin.initialize({instrumentationKey: 'ikey'}, core, [plugin, appInsights]);
|
||||
|
||||
const trackStub = this.sandbox.spy(appInsights.core.getTransmissionControls()[0][0], 'processTelemetry');
|
||||
const telemetryInitializer = {
|
||||
|
@ -1201,12 +1337,16 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
const plugin = new ChannelPlugin();
|
||||
const core = new AppInsightsCore();
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{instrumentationKey: "key"},
|
||||
{instrumentationKey: "ikey"},
|
||||
[plugin, appInsights]
|
||||
);
|
||||
appInsights.initialize({ "instrumentationKey": "ikey" }, core, [plugin, appInsights]);
|
||||
plugin.initialize({instrumentationKey: 'ikey'}, core, [plugin, appInsights]);
|
||||
|
||||
const trackStub = this.sandbox.spy(appInsights.core.getTransmissionControls()[0][0], 'processTelemetry');
|
||||
const nameOverride = "my unique name";
|
||||
const telemetryInitializer = {
|
||||
|
@ -1235,12 +1375,16 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
const plugin = new ChannelPlugin();
|
||||
const core = new AppInsightsCore();
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{instrumentationKey: "key"},
|
||||
{instrumentationKey: "ikey"},
|
||||
[plugin, appInsights]
|
||||
);
|
||||
appInsights.initialize({ "instrumentationKey": "ikey" }, core, [plugin, appInsights]);
|
||||
plugin.initialize({instrumentationKey: 'ikey'}, core, [plugin, appInsights]);
|
||||
|
||||
const trackStub = this.sandbox.spy(appInsights.core.getTransmissionControls()[0][0], 'processTelemetry');
|
||||
|
||||
const messageOverride = "my unique name";
|
||||
|
@ -1281,12 +1425,16 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
const plugin = new ChannelPlugin();
|
||||
const core = new AppInsightsCore();
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{instrumentationKey: "key"},
|
||||
{instrumentationKey: "ikey"},
|
||||
[plugin, appInsights]
|
||||
);
|
||||
appInsights.initialize({ "instrumentationKey": "ikey" }, core, [plugin, appInsights]);
|
||||
plugin.initialize({instrumentationKey: 'ikey'}, core, [plugin, appInsights]);
|
||||
|
||||
const initializer1 = { init: () => { } };
|
||||
const initializer2 = { init: () => { } };
|
||||
const spy1 = this.sandbox.spy(initializer1, "init");
|
||||
|
@ -1311,12 +1459,16 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
const plugin = new ChannelPlugin();
|
||||
const core = new AppInsightsCore();
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{instrumentationKey: "key"},
|
||||
{instrumentationKey: "ikey"},
|
||||
[plugin, appInsights]
|
||||
);
|
||||
appInsights.initialize({ "instrumentationKey": "ikey" }, core, [plugin, appInsights]);
|
||||
plugin.initialize({instrumentationKey: 'ikey'}, core, [plugin, appInsights]);
|
||||
|
||||
const initializer1 = { init: (item: ITelemetryItem) => {
|
||||
if (item.data !== undefined) {
|
||||
item.data.init1 = true;
|
||||
|
@ -1350,12 +1502,16 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
const plugin = new ChannelPlugin();
|
||||
const core = new AppInsightsCore();
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{instrumentationKey: "key"},
|
||||
{instrumentationKey: "ikey"},
|
||||
[plugin, appInsights]
|
||||
);
|
||||
appInsights.initialize({ "instrumentationKey": "ikey" }, core, [plugin, appInsights]);
|
||||
plugin.initialize({instrumentationKey: 'ikey'}, core, [plugin, appInsights]);
|
||||
|
||||
const initializer1 = { init: () => { } };
|
||||
const initializer2 = { init: () => { } };
|
||||
const spy1 = this.sandbox.spy(initializer1, "init");
|
||||
|
@ -1380,12 +1536,16 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
const plugin = new ChannelPlugin();
|
||||
const core = new AppInsightsCore();
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{instrumentationKey: "key"},
|
||||
{instrumentationKey: "ikey"},
|
||||
[plugin, appInsights]
|
||||
);
|
||||
appInsights.initialize({ "instrumentationKey": "ikey" }, core, [plugin, appInsights]);
|
||||
plugin.initialize({instrumentationKey: 'ikey'}, core, [plugin, appInsights]);
|
||||
|
||||
const trackStub = this.sandbox.spy(appInsights.core.getTransmissionControls()[0][0], 'processTelemetry');
|
||||
|
||||
// act
|
||||
|
@ -1404,12 +1564,16 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
const plugin = new ChannelPlugin();
|
||||
const core = new AppInsightsCore();
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{instrumentationKey: "key"},
|
||||
{instrumentationKey: "ikey"},
|
||||
[plugin, appInsights]
|
||||
);
|
||||
appInsights.initialize({ "instrumentationKey": "ikey" }, core, [plugin, appInsights]);
|
||||
plugin.initialize({instrumentationKey: 'ikey'}, core, [plugin, appInsights]);
|
||||
|
||||
const trackStub = this.sandbox.spy(appInsights.core.getTransmissionControls()[0][0], 'processTelemetry');
|
||||
|
||||
// act
|
||||
|
@ -1428,12 +1592,16 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
const plugin = new ChannelPlugin();
|
||||
const core = new AppInsightsCore();
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{instrumentationKey: "key"},
|
||||
{instrumentationKey: "ikey"},
|
||||
[plugin, appInsights]
|
||||
);
|
||||
appInsights.initialize({ "instrumentationKey": "ikey" }, core, [plugin, appInsights]);
|
||||
plugin.initialize({instrumentationKey: 'ikey'}, core, [plugin, appInsights]);
|
||||
|
||||
const trackStub = this.sandbox.spy(appInsights.core.getTransmissionControls()[0][0], 'processTelemetry');
|
||||
|
||||
// act
|
||||
|
@ -1452,12 +1620,16 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
const plugin = new ChannelPlugin();
|
||||
const core = new AppInsightsCore();
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{instrumentationKey: "key"},
|
||||
{instrumentationKey: "ikey"},
|
||||
[plugin, appInsights]
|
||||
);
|
||||
appInsights.initialize({ "instrumentationKey": "ikey" }, core, [plugin, appInsights]);
|
||||
plugin.initialize({instrumentationKey: 'ikey'}, core, [plugin, appInsights]);
|
||||
|
||||
const trackStub = this.sandbox.spy(appInsights.core.getTransmissionControls()[0][0], 'processTelemetry');
|
||||
|
||||
// act
|
||||
|
@ -1478,12 +1650,16 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
const plugin = new ChannelPlugin();
|
||||
const core = new AppInsightsCore();
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{instrumentationKey: "key"},
|
||||
{instrumentationKey: "ikey"},
|
||||
[plugin, appInsights]
|
||||
);
|
||||
appInsights.initialize({ "instrumentationKey": "ikey" }, core, [plugin, appInsights]);
|
||||
plugin.initialize({instrumentationKey: 'ikey'}, core, [plugin, appInsights]);
|
||||
|
||||
const trackStub = this.sandbox.spy(appInsights.core.getTransmissionControls()[0][0], 'processTelemetry');
|
||||
|
||||
// act
|
||||
|
@ -1504,12 +1680,16 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
const plugin = new ChannelPlugin();
|
||||
const core = new AppInsightsCore();
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{instrumentationKey: "key"},
|
||||
{instrumentationKey: "ikey"},
|
||||
[plugin, appInsights]
|
||||
);
|
||||
appInsights.initialize({ "instrumentationKey": "ikey" }, core, [plugin, appInsights]);
|
||||
plugin.initialize({instrumentationKey: 'ikey'}, core, [plugin, appInsights]);
|
||||
|
||||
const trackStub = this.sandbox.spy(appInsights.core.getTransmissionControls()[0][0], 'processTelemetry');
|
||||
|
||||
// act
|
||||
|
@ -1530,12 +1710,16 @@ export class AnalyticsPluginTests extends AITestClass {
|
|||
const plugin = new ChannelPlugin();
|
||||
const core = new AppInsightsCore();
|
||||
const appInsights = new AnalyticsPlugin();
|
||||
|
||||
this.onDone(() => {
|
||||
core.unload(false);
|
||||
});
|
||||
|
||||
core.initialize(
|
||||
{instrumentationKey: "key"},
|
||||
{instrumentationKey: "ikey"},
|
||||
[plugin, appInsights]
|
||||
);
|
||||
appInsights.initialize({ "instrumentationKey": "ikey" }, core, [plugin, appInsights]);
|
||||
plugin.initialize({instrumentationKey: 'ikey'}, core, [plugin, appInsights]);
|
||||
|
||||
const trackStub = this.sandbox.spy(appInsights.core.getTransmissionControls()[0][0], 'processTelemetry');
|
||||
const logStub = this.sandbox.spy(appInsights.core.logger, "throwInternal")
|
||||
// act
|
||||
|
|
|
@ -26,15 +26,27 @@ export class TelemetryItemCreatorTests extends AITestClass {
|
|||
private _core: IAppInsightsCore;
|
||||
private _appInsights: AnalyticsPlugin;
|
||||
|
||||
constructor(name?: string, emulateEs3?: boolean) {
|
||||
super(name, emulateEs3);
|
||||
this.assertNoEvents = true;
|
||||
this.assertNoHooks = true;
|
||||
}
|
||||
|
||||
public testInitialize() {
|
||||
const plugin: IPlugin = new ChannelPlugin();
|
||||
this._core = new AppInsightsCore();
|
||||
this._core.initialize(
|
||||
{instrumentationKey: "key"},
|
||||
{instrumentationKey: "ikey"},
|
||||
[plugin]
|
||||
);
|
||||
this._appInsights = new AnalyticsPlugin();
|
||||
this._appInsights.initialize({ "instrumentationKey": "ikey" }, this._core, []);
|
||||
this._core.addPlugin(this._appInsights);
|
||||
}
|
||||
|
||||
public testFinishedCleanup(): void {
|
||||
if (this._core) {
|
||||
this._core.unload(false);
|
||||
}
|
||||
}
|
||||
|
||||
public registerTests() {
|
||||
|
|
|
@ -543,7 +543,7 @@ export class AnalyticsPlugin extends BaseTelemetryPlugin implements IAppInsights
|
|||
|
||||
_base.initialize(config, core, extensions, pluginChain);
|
||||
try {
|
||||
_evtNamespace = mergeEvtNamespace(createUniqueNamespace("AnalyticsPlugin"), core.evtNamespace && core.evtNamespace());
|
||||
_evtNamespace = mergeEvtNamespace(createUniqueNamespace(_self.identifier), core.evtNamespace && core.evtNamespace());
|
||||
if (_preInitTelemetryInitializers) {
|
||||
arrForEach(_preInitTelemetryInitializers, (initializer) => {
|
||||
core.addTelemetryInitializer(initializer);
|
||||
|
@ -605,6 +605,8 @@ export class AnalyticsPlugin extends BaseTelemetryPlugin implements IAppInsights
|
|||
};
|
||||
|
||||
_self._doTeardown = (unloadCtx?: IProcessTelemetryUnloadContext, unloadState?: ITelemetryUnloadState) => {
|
||||
_pageViewManager && _pageViewManager.teardown(unloadCtx, unloadState)
|
||||
|
||||
// Just register to remove all events associated with this namespace
|
||||
eventOff(window, null, null, _evtNamespace);
|
||||
_initDefaults();
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
} from "@microsoft/applicationinsights-common";
|
||||
import {
|
||||
IAppInsightsCore, IDiagnosticLogger, LoggingSeverity,
|
||||
_InternalMessageId, getDocument, getLocation, arrForEach, isNullOrUndefined, getExceptionName, dumpObj
|
||||
_InternalMessageId, getDocument, getLocation, arrForEach, isNullOrUndefined, getExceptionName, dumpObj, IProcessTelemetryUnloadContext, ITelemetryUnloadState
|
||||
} from "@microsoft/applicationinsights-core-js";
|
||||
import { PageViewPerformanceManager } from "./PageViewPerformanceManager";
|
||||
import dynamicProto from "@microsoft/dynamicproto-js";
|
||||
|
@ -40,11 +40,9 @@ export class PageViewManager {
|
|||
_logger = core.logger;
|
||||
}
|
||||
|
||||
function _flushChannels() {
|
||||
function _flushChannels(isAsync: boolean) {
|
||||
if (core) {
|
||||
arrForEach(core.getTransmissionControls(), queues => {
|
||||
arrForEach(queues, (q) => { q.flush(true); })
|
||||
});
|
||||
core.flush(isAsync);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,7 +70,7 @@ export class PageViewManager {
|
|||
|
||||
if (doFlush) {
|
||||
// We process at least one item so flush the queue
|
||||
_flushChannels();
|
||||
_flushChannels(true);
|
||||
}
|
||||
}), 100);
|
||||
}
|
||||
|
@ -99,7 +97,7 @@ export class PageViewManager {
|
|||
pageView,
|
||||
customProperties
|
||||
);
|
||||
_flushChannels();
|
||||
_flushChannels(true);
|
||||
|
||||
// no navigation timing (IE 8, iOS Safari 8.4, Opera Mini 8 - see http://caniuse.com/#feat=nav-timing)
|
||||
_logger.throwInternal(
|
||||
|
@ -143,7 +141,7 @@ export class PageViewManager {
|
|||
pageView,
|
||||
customProperties
|
||||
);
|
||||
_flushChannels();
|
||||
_flushChannels(true);
|
||||
pageViewSent = true;
|
||||
}
|
||||
|
||||
|
@ -207,7 +205,24 @@ export class PageViewManager {
|
|||
|
||||
return processed;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
_self.teardown = (unloadCtx?: IProcessTelemetryUnloadContext, unloadState?: ITelemetryUnloadState) => {
|
||||
if (intervalHandle) {
|
||||
clearInterval(intervalHandle);
|
||||
intervalHandle = null;
|
||||
|
||||
let allItems = itemQueue.slice(0);
|
||||
let doFlush = false;
|
||||
itemQueue = [];
|
||||
arrForEach(allItems, (item) => {
|
||||
if (item()) {
|
||||
doFlush = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -224,4 +239,8 @@ export class PageViewManager {
|
|||
public trackPageView(pageView: IPageViewTelemetry, customProperties?: { [key: string]: any }) {
|
||||
// @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
|
||||
}
|
||||
|
||||
public teardown(unloadCtx?: IProcessTelemetryUnloadContext, unloadState?: ITelemetryUnloadState) {
|
||||
// @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,18 +44,27 @@ export class AjaxTests extends AITestClass {
|
|||
private _ajax:AjaxMonitor = null;
|
||||
private _context:any = {};
|
||||
|
||||
constructor(name?: string, emulateEs3?: boolean) {
|
||||
super(name, emulateEs3);
|
||||
this.assertNoEvents = true;
|
||||
this.assertNoHooks = true;
|
||||
}
|
||||
|
||||
public testInitialize() {
|
||||
this._context = {};
|
||||
this.useFakeServer = true;
|
||||
this._fetch = getGlobalInst("fetch");
|
||||
}
|
||||
|
||||
public testCleanup() {
|
||||
this._context = {};
|
||||
public testFinishedCleanup(): void {
|
||||
if (this._ajax !== null) {
|
||||
this._ajax.teardown();
|
||||
this._ajax = null;
|
||||
}
|
||||
}
|
||||
|
||||
public testCleanup() {
|
||||
this._context = {};
|
||||
getGlobal().fetch = this._fetch;
|
||||
}
|
||||
|
||||
|
@ -1912,9 +1921,10 @@ export class AjaxPerfTrackTests extends AITestClass {
|
|||
private _perfEntries: PerformanceEntry[];
|
||||
private _context:any;
|
||||
|
||||
constructor(name?: string) {
|
||||
super(name);
|
||||
|
||||
constructor(name?: string, emulateEs3?: boolean) {
|
||||
super(name, emulateEs3);
|
||||
this.assertNoEvents = true;
|
||||
this.assertNoHooks = true;
|
||||
this.useFakeServer = false;
|
||||
this._perfEntries = [];
|
||||
this._context = {};
|
||||
|
@ -1971,12 +1981,15 @@ export class AjaxPerfTrackTests extends AITestClass {
|
|||
}
|
||||
}
|
||||
|
||||
public testCleanup() {
|
||||
this._context = {};
|
||||
public testFinishedCleanup(): void {
|
||||
if (this._ajax) {
|
||||
this._ajax.teardown();
|
||||
this._ajax = null;
|
||||
}
|
||||
}
|
||||
|
||||
public testCleanup() {
|
||||
this._context = {};
|
||||
|
||||
if (this._initialPerformance) {
|
||||
(<any>window).performance = this._initialPerformance;
|
||||
|
@ -2500,8 +2513,10 @@ export class AjaxFrozenTests extends AITestClass {
|
|||
private _ajax:AjaxMonitor;
|
||||
private _context:any;
|
||||
|
||||
constructor(name?: string) {
|
||||
super(name);
|
||||
constructor(name?: string, emulateEs3?: boolean) {
|
||||
super(name, emulateEs3);
|
||||
this.assertNoEvents = true;
|
||||
this.assertNoHooks = true;
|
||||
|
||||
this.useFakeServer = false;
|
||||
this._context = {};
|
||||
|
@ -2513,12 +2528,15 @@ export class AjaxFrozenTests extends AITestClass {
|
|||
this._xmlHttpRequest = getGlobalInst("XMLHttpRquest)");
|
||||
}
|
||||
|
||||
public testCleanup() {
|
||||
this._context = {};
|
||||
public testFinishedCleanup(): void {
|
||||
if (this._ajax) {
|
||||
this._ajax.teardown();
|
||||
this._ajax = null;
|
||||
}
|
||||
}
|
||||
|
||||
public testCleanup() {
|
||||
this._context = {};
|
||||
|
||||
// Restore the real fetch
|
||||
window.fetch = this._fetch;
|
||||
|
|
|
@ -11,7 +11,9 @@ import { IProcessTelemetryContext } from "./IProcessTelemetryContext";
|
|||
import { IPerfManagerProvider } from "./IPerfManager";
|
||||
import { ICookieMgr } from "./ICookieMgr";
|
||||
import { ITelemetryInitializerHandler, TelemetryInitializerFunction } from "./ITelemetryInitializers";
|
||||
import { UnloadHandler } from "../applicationinsights-core-js";
|
||||
import { ITelemetryUnloadState } from "./ITelemetryUnloadState";
|
||||
import { UnloadHandler } from "../JavaScriptSDK/UnloadHandlerContainer";
|
||||
import { SendRequestReason } from "../JavaScriptSDK.Enums/SendRequestReason";
|
||||
|
||||
export interface ILoadedPlugin<T extends IPlugin> {
|
||||
plugin: T;
|
||||
|
@ -116,8 +118,11 @@ export interface IAppInsightsCore extends IPerfManagerProvider {
|
|||
* approach is to create a new instance and initialize that instance.
|
||||
* This is due to possible unexpected side effects caused by plugins not supporting unload / teardown, unable
|
||||
* to successfully remove any global references or they may just be completing the unload process asynchronously.
|
||||
* @param isAsync - Can the unload be performed asynchronously (default)
|
||||
* @param unloadComplete - An optional callback that will be called once the unload has completed
|
||||
* @param cbTimeout - An optional timeout to wait for any flush operations to complete before proceeding with the unload. Defaults to 5 seconds.
|
||||
*/
|
||||
unload(isAsync?: boolean, unloadComplete?: () => void): void;
|
||||
unload(isAsync?: boolean, unloadComplete?: (unloadState: ITelemetryUnloadState) => void, cbTimeout?: number): void;
|
||||
|
||||
/**
|
||||
* Find and return the (first) plugin with the specified identifier if present
|
||||
|
@ -128,10 +133,11 @@ export interface IAppInsightsCore extends IPerfManagerProvider {
|
|||
/**
|
||||
* Add a new plugin to the installation
|
||||
* @param plugin - The new plugin to add
|
||||
* @param replaceExisting - should any existing plugin be replaced
|
||||
* @param replaceExisting - should any existing plugin be replaced, default is false
|
||||
* @param doAsync - Should the add be performed asynchronously
|
||||
* @param addCb - [Optional] callback to call after the plugin has been added
|
||||
*/
|
||||
addPlugin<T extends IPlugin = ITelemetryPlugin>(plugin: T, replaceExisting: boolean, doAsync: boolean, addCb?: (added?: boolean) => void): void;
|
||||
addPlugin<T extends IPlugin = ITelemetryPlugin>(plugin: T, replaceExisting?: boolean, doAsync?: boolean, addCb?: (added?: boolean) => void): void;
|
||||
|
||||
/**
|
||||
* Returns the unique event namespace that should be used when registering events
|
||||
|
@ -143,4 +149,15 @@ export interface IAppInsightsCore extends IPerfManagerProvider {
|
|||
* @param handler - the handler
|
||||
*/
|
||||
addUnloadCb(handler: UnloadHandler): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush and send any batched / cached data immediately
|
||||
* @param async - send data asynchronously when true (defaults to true)
|
||||
* @param callBack - if specified, notify caller when send is complete, the channel should return true to indicate to the caller that it will be called.
|
||||
* If the caller doesn't return true the caller should assume that it may never be called.
|
||||
* @param sendReason - specify the reason that you are calling "flush" defaults to ManualFlush (1) if not specified
|
||||
* @param cbTimeout - An optional timeout to wait for any flush operations to complete before proceeding with the unload. Defaults to 5 seconds.
|
||||
* @returns - true if the callback will be return after the flush is complete otherwise the caller should assume that any provided callback will never be called
|
||||
*/
|
||||
flush(isAsync?: boolean, callBack?: (flushComplete?: boolean) => void, sendReason?: SendRequestReason, cbTimeout?: number): boolean | void;
|
||||
}
|
||||
|
|
|
@ -194,7 +194,7 @@ export class BaseCore implements IAppInsightsCore {
|
|||
|
||||
_initPluginChain(config, null);
|
||||
|
||||
if (_self.getTransmissionControls().length === 0) {
|
||||
if (!_channelQueue || _channelQueue.length === 0) {
|
||||
throwError("No channels available");
|
||||
}
|
||||
|
||||
|
@ -379,16 +379,14 @@ export class BaseCore implements IAppInsightsCore {
|
|||
processUnloadCtx.processNext(unloadState);
|
||||
}
|
||||
|
||||
if (_channelControl) {
|
||||
_channelControl.flush(isAsync, _doUnload, SendRequestReason.SdkUnload, cbTimeout);
|
||||
} else {
|
||||
_doUnload(true);
|
||||
if (!_flushChannels(isAsync, _doUnload, SendRequestReason.SdkUnload, cbTimeout)) {
|
||||
_doUnload(false);
|
||||
}
|
||||
};
|
||||
|
||||
_self.getPlugin = _getPlugin;
|
||||
|
||||
_self.addPlugin = <T extends IPlugin = ITelemetryPlugin>(plugin: T, replaceExisting: boolean, isAsync: boolean = true, addCb?: (added?: boolean) => void): void => {
|
||||
_self.addPlugin = <T extends IPlugin = ITelemetryPlugin>(plugin: T, replaceExisting?: boolean, isAsync?: boolean, addCb?: (added?: boolean) => void): void => {
|
||||
if (!plugin) {
|
||||
addCb && addCb(false);
|
||||
_logOrThrowError(strValidationError);
|
||||
|
@ -442,6 +440,8 @@ export class BaseCore implements IAppInsightsCore {
|
|||
return _evtNamespace;
|
||||
};
|
||||
|
||||
_self.flush = _flushChannels;
|
||||
|
||||
// Create the addUnloadCb
|
||||
proxyFunctionAs(_self, "addUnloadCb", () => _unloadHandlers, "add");
|
||||
|
||||
|
@ -662,6 +662,15 @@ export class BaseCore implements IAppInsightsCore {
|
|||
}
|
||||
}
|
||||
|
||||
function _flushChannels(isAsync?: boolean, callBack?: (flushComplete?: boolean) => void, sendReason?: SendRequestReason, cbTimeout?: number) {
|
||||
if (_channelControl) {
|
||||
return _channelControl.flush(isAsync, callBack, sendReason || SendRequestReason.SdkUnload, cbTimeout);
|
||||
}
|
||||
|
||||
callBack && callBack(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
function _initDebugListener(config: IConfiguration) {
|
||||
|
||||
if (config.disableDbgExt === true && _debugListener) {
|
||||
|
@ -815,10 +824,12 @@ export class BaseCore implements IAppInsightsCore {
|
|||
* approach is to create a new instance and initialize that instance.
|
||||
* This is due to possible unexpected side effects caused by plugins not supporting unload / teardown, unable
|
||||
* to successfully remove any global references or they may just be completing the unload process asynchronously.
|
||||
* @param isAsync - Can the unload be performed asynchronously (default)
|
||||
* @param unloadComplete - An optional callback that will be called once the unload has completed
|
||||
* @param cbTimeout - An optional timeout to wait for any flush operations to complete before proceeding with the unload. Defaults to 5 seconds.
|
||||
*/
|
||||
public unload(isAsync?: boolean, unloadComplete?: (unloadState: ITelemetryUnloadState) => void, cbTimeout?: number): void {
|
||||
// @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
|
||||
return null;
|
||||
}
|
||||
|
||||
public getPlugin<T extends IPlugin = IPlugin>(pluginIdentifier: string): ILoadedPlugin<T> {
|
||||
|
@ -826,7 +837,14 @@ export class BaseCore implements IAppInsightsCore {
|
|||
return null;
|
||||
}
|
||||
|
||||
public addPlugin<T extends IPlugin = ITelemetryPlugin>(plugin: T, replaceExisting: boolean, doAsync: boolean, addCb?: (added?: boolean) => void): void {
|
||||
/**
|
||||
* Add a new plugin to the installation
|
||||
* @param plugin - The new plugin to add
|
||||
* @param replaceExisting - should any existing plugin be replaced, default is false
|
||||
* @param doAsync - Should the add be performed asynchronously
|
||||
* @param addCb - [Optional] callback to call after the plugin has been added
|
||||
*/
|
||||
public addPlugin<T extends IPlugin = ITelemetryPlugin>(plugin: T, replaceExisting?: boolean, doAsync?: boolean, addCb?: (added?: boolean) => void): void {
|
||||
// @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
|
||||
}
|
||||
|
||||
|
@ -846,6 +864,18 @@ export class BaseCore implements IAppInsightsCore {
|
|||
// @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush and send any batched / cached data immediately
|
||||
* @param async - send data asynchronously when true (defaults to true)
|
||||
* @param callBack - if specified, notify caller when send is complete, the channel should return true to indicate to the caller that it will be called.
|
||||
* If the caller doesn't return true the caller should assume that it may never be called.
|
||||
* @param sendReason - specify the reason that you are calling "flush" defaults to ManualFlush (1) if not specified
|
||||
* @returns - true if the callback will be return after the flush is complete otherwise the caller should assume that any provided callback will never be called
|
||||
*/
|
||||
public flush(isAsync?: boolean, callBack?: (flushComplete?: boolean) => void, sendReason?: SendRequestReason): void {
|
||||
// @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
|
||||
}
|
||||
|
||||
protected releaseQueue() {
|
||||
// @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ export abstract class BaseTelemetryPlugin implements ITelemetryPlugin {
|
|||
// If this plugin has already been torn down (not operational) or is not initialized (core is not set)
|
||||
// or the core being used for unload was not the same core used for initialization.
|
||||
if (!_self.core || (unloadCtx && _self.core !== unloadCtx.core())) {
|
||||
// Do Nothing
|
||||
// Do Nothing as either the plugin is not initialized or was not initialized by the current core
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -237,6 +237,8 @@ export function createChannelControllerPlugin(channelQueue: _IInternalChannels[]
|
|||
doneIterating = true;
|
||||
doCallback();
|
||||
});
|
||||
|
||||
return true;
|
||||
},
|
||||
_setQueue: (queue: _IInternalChannels[]) => {
|
||||
channelQueue = queue;
|
||||
|
|
|
@ -31,8 +31,8 @@ export {
|
|||
} from "./JavaScriptSDK/HelperFuncs";
|
||||
export {
|
||||
attachEvent, detachEvent, addEventHandler, addEventListeners, addPageUnloadEventListener, addPageHideEventListener, addPageShowEventListener,
|
||||
removeEventHandler, removeEventListeners, removePageUnloadEventListener, removePageHideEventListener, eventOn, eventOff, mergeEvtNamespace,
|
||||
_IRegisteredEvents, __getRegisteredEvents
|
||||
removeEventHandler, removeEventListeners, removePageUnloadEventListener, removePageHideEventListener, removePageShowEventListener, eventOn, eventOff,
|
||||
mergeEvtNamespace, _IRegisteredEvents, __getRegisteredEvents
|
||||
} from "./JavaScriptSDK/EventHelpers";
|
||||
|
||||
export {
|
||||
|
|
Загрузка…
Ссылка в новой задаче