Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions AISKU/Tests/Unit/src/AISKUSize.Tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ function _checkSize(checkType: string, maxSize: number, size: number, isNightly:
}

export class AISKUSizeCheck extends AITestClass {
private readonly MAX_RAW_SIZE = 144;
private readonly MAX_BUNDLE_SIZE = 144;
private readonly MAX_RAW_SIZE = 145;
private readonly MAX_BUNDLE_SIZE = 145;
private readonly MAX_RAW_DEFLATE_SIZE = 58;
private readonly MAX_BUNDLE_DEFLATE_SIZE = 58;
private readonly rawFilePath = "../dist/es5/applicationinsights-web.min.js";
Expand Down
197 changes: 196 additions & 1 deletion AISKU/Tests/Unit/src/applicationinsights.e2e.tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,15 @@ import { TelemetryContext } from '@microsoft/applicationinsights-properties-js';
import { createAsyncResolvedPromise } from '@nevware21/ts-async';
import { CONFIG_ENDPOINT_URL } from '../../../src/InternalConstants';
import { OfflineChannel } from '@microsoft/applicationinsights-offlinechannel-js';

import { IStackFrame } from '@microsoft/applicationinsights-common/src/Interfaces/Contracts/IStackFrame';

function _checkExpectedFrame(expectedFrame: IStackFrame, actualFrame: IStackFrame, index: number) {
Assert.equal(expectedFrame.assembly, actualFrame.assembly, index + ") Assembly is not as expected");
Assert.equal(expectedFrame.fileName, actualFrame.fileName, index + ") FileName is not as expected");
Assert.equal(expectedFrame.line, actualFrame.line, index + ") Line is not as expected");
Assert.equal(expectedFrame.method, actualFrame.method, index + ") Method is not as expected");
Assert.equal(expectedFrame.level, actualFrame.level, index + ") Level is not as expected");
}

export class ApplicationInsightsTests extends AITestClass {
private static readonly _instrumentationKey = 'b7170927-2d1c-44f1-acec-59f4e1751c11';
Expand Down Expand Up @@ -1058,6 +1066,193 @@ export class ApplicationInsightsTests extends AITestClass {
})
});

this.testCaseAsync({
name: "E2E.GenericTests: trackException with multiple stack frame formats",
stepDelay: 1,
steps: [() => {
let errObj = {
name: "E2E.GenericTests",
reason:{
message: "Test_Error_Throwing_Inside_UseCallback",
stack: "Error: Test_Error_Throwing_Inside_UseCallback\n" +
"at http://localhost:3000/static/js/main.206f4846.js:2:296748\n" + // Anonymous function with no function name attribution (firefox/ios)
"at Object.Re (http://localhost:3000/static/js/main.206f4846.js:2:16814)\n" + // With class.function attribution
"at je (http://localhost:3000/static/js/main.206f4846.js:2:16968)\n" + // With function name attribution
"at Object.<anonymous> (http://localhost:3000/static/js/main.206f4846.js:2:42819)\n" + // With Object.<anonymous> attribution
"at Object.<anonymous> (../localfile.js:2:1234)\n" + // With Object.<anonymous> attribution and local file
"at (anonymous) @ VM60:1\n" + // With (anonymous) attribution
"at [native code]\n" + // With [native code] attribution
"at (at eval at <anonymous> (http://localhost:3000/static/js/main.206f4846.js:2:296748), <anonymous>:1:1)\n" + // With eval attribution
"at Object.eval (http://localhost:3000/static/js/main.206f4846.js:2:296748)\n" + // With eval attribution
"at eval (http://localhost:3000/static/js/main.206f4846.js:2:296748)\n" + // With eval attribution
"at eval (webpack-internal:///./src/App.tsx:1:1)\n" + // With eval attribution
"at [arguments not available])@file://localhost/stacktrace.js:21\n" + // With arguments not available attribution
"at file://C:/Temp/stacktrace.js:27:1\n" + // With file://localhost attribution
" Line 21 of linked script file://localhost/C:/Temp/stacktrace.js\n" + // With Line 21 of linked script attribution
" Line 11 of inline#1 script in http://localhost:3000/static/js/main.206f4846.js:2:296748\n" + // With Line 11 of inline#1 script attribution
" Line 68 of inline#2 script in file://localhost/teststack.html\n" + // With Line 68 of inline#2 script attribution
"at Function.Module._load (module.js:407:3)\n" +
" at Function.Module.runMain (module.js:575:10)\n"+
" at startup (node.js:159:18)\n" +
"at Global code (http://example.com/stacktrace.js:11:1)\n" +
"at Object.Module._extensions..js (module.js:550:10)\n" +
" at c@http://example.com/stacktrace.js:9:3\n" +
" at b@http://example.com/stacktrace.js:6:3\n" +
" at a@http://example.com/stacktrace.js:3:3\n" +
"http://localhost:3000/static/js/main.206f4846.js:2:296748\n" + // Anonymous function with no function name attribution (firefox/ios)
" c@http://example.com/stacktrace.js:9:3\n" +
" b@http://example.com/stacktrace.js:6:3\n" +
" a@http://example.com/stacktrace.js:3:3\n" +
" at Object.testMethod (http://localhost:9001/shared/AppInsightsCommon/node_modules/@microsoft/ai-test-framework/dist/es5/ai-test-framework.js:53058:48)"
}
};

let exception = Exception.CreateAutoException("Test_Error_Throwing_Inside_UseCallback",
"url",
9,
0,
errObj
);
this._ai.trackException({ exception: exception }, { custom: "custom value" });
}].concat(this.asserts(1)).concat(() => {

const expectedParsedStack: IStackFrame[] = [
{ level: 0, method: "<no_method>", assembly: "at http://localhost:3000/static/js/main.206f4846.js:2:296748", fileName: "http://localhost:3000/static/js/main.206f4846.js", line: 2 },
{ level: 1, method: "Object.Re", assembly: "at Object.Re (http://localhost:3000/static/js/main.206f4846.js:2:16814)", fileName: "http://localhost:3000/static/js/main.206f4846.js", line: 2 },
{ level: 2, method: "je", assembly: "at je (http://localhost:3000/static/js/main.206f4846.js:2:16968)", fileName: "http://localhost:3000/static/js/main.206f4846.js", line: 2 },
{ level: 3, method: "Object.<anonymous>", assembly: "at Object.<anonymous> (http://localhost:3000/static/js/main.206f4846.js:2:42819)", fileName: "http://localhost:3000/static/js/main.206f4846.js", line: 2 },
{ level: 4, method: "Object.<anonymous>", assembly: "at Object.<anonymous> (../localfile.js:2:1234)", fileName: "../localfile.js", line: 2 },
{ level: 5, method: "<anonymous>", assembly: "at (anonymous) @ VM60:1", fileName: "VM60", line: 1 },
{ level: 6, method: "<no_method>", assembly: "at [native code]", fileName: "", line: 0 },
{ level: 7, method: "<no_method>", assembly: "at (at eval at <anonymous> (http://localhost:3000/static/js/main.206f4846.js:2:296748), <anonymous>:1:1)", fileName: "http://localhost:3000/static/js/main.206f4846.js", line: 2 },
{ level: 8, method: "Object.eval", assembly: "at Object.eval (http://localhost:3000/static/js/main.206f4846.js:2:296748)", fileName: "http://localhost:3000/static/js/main.206f4846.js", line: 2 },
{ level: 9, method: "eval", assembly: "at eval (http://localhost:3000/static/js/main.206f4846.js:2:296748)", fileName: "http://localhost:3000/static/js/main.206f4846.js", line: 2 },
{ level: 10, method: "eval", assembly: "at eval (webpack-internal:///./src/App.tsx:1:1)", fileName: "webpack-internal:///./src/App.tsx", line: 1 },
{ level: 11, method: "<no_method>", assembly: "at [arguments not available])@file://localhost/stacktrace.js:21", fileName: "file://localhost/stacktrace.js", line: 21 },
{ level: 12, method: "<no_method>", assembly: "at file://C:/Temp/stacktrace.js:27:1", fileName: "file://C:/Temp/stacktrace.js", line: 27 },
{ level: 13, method: "<no_method>", assembly: "Line 21 of linked script file://localhost/C:/Temp/stacktrace.js", fileName: "file://localhost/C:/Temp/stacktrace.js", line: 0 },
{ level: 14, method: "<no_method>", assembly: "Line 11 of inline#1 script in http://localhost:3000/static/js/main.206f4846.js:2:296748", fileName: "http://localhost:3000/static/js/main.206f4846.js", line: 2 },
{ level: 15, method: "<no_method>", assembly: "Line 68 of inline#2 script in file://localhost/teststack.html", fileName: "file://localhost/teststack.html", line: 0 },
{ level: 16, method: "Function.Module._load", assembly: "at Function.Module._load (module.js:407:3)", fileName: "module.js", line: 407 },
{ level: 17, method: "Function.Module.runMain", assembly: "at Function.Module.runMain (module.js:575:10)", fileName: "module.js", line: 575 },
{ level: 18, method: "startup", assembly: "at startup (node.js:159:18)", fileName: "node.js", line: 159 },
{ level: 19, method: "<no_method>", assembly: "at Global code (http://example.com/stacktrace.js:11:1)", fileName: "http://example.com/stacktrace.js", line: 11 },
{ level: 20, method: "Object.Module._extensions..js", assembly: "at Object.Module._extensions..js (module.js:550:10)", fileName: "module.js", line: 550 },
{ level: 21, method: "c", assembly: "at c@http://example.com/stacktrace.js:9:3", fileName: "http://example.com/stacktrace.js", line: 9 },
{ level: 22, method: "b", assembly: "at b@http://example.com/stacktrace.js:6:3", fileName: "http://example.com/stacktrace.js", line: 6 },
{ level: 23, method: "a", assembly: "at a@http://example.com/stacktrace.js:3:3", fileName: "http://example.com/stacktrace.js", line: 3 },
{ level: 24, method: "<no_method>", assembly: "http://localhost:3000/static/js/main.206f4846.js:2:296748", fileName: "http://localhost:3000/static/js/main.206f4846.js", line: 2 },
{ level: 25, method: "c", assembly: "c@http://example.com/stacktrace.js:9:3", fileName: "http://example.com/stacktrace.js", line: 9 },
{ level: 26, method: "b", assembly: "b@http://example.com/stacktrace.js:6:3", fileName: "http://example.com/stacktrace.js", line: 6 },
{ level: 27, method: "a", assembly: "a@http://example.com/stacktrace.js:3:3", fileName: "http://example.com/stacktrace.js", line: 3 },
{ level: 28, method: "Object.testMethod", assembly: "at Object.testMethod (http://localhost:9001/shared/AppInsightsCommon/node_modules/@microsoft/ai-test-framework/dist/es5/ai-test-framework.js:53058:48)", fileName: "http://localhost:9001/shared/AppInsightsCommon/node_modules/@microsoft/ai-test-framework/dist/es5/ai-test-framework.js", line: 53058 }
];

const payloadStr: string[] = this.getPayloadMessages(this.successSpy);
if (payloadStr.length > 0) {
const payload = JSON.parse(payloadStr[0]);
const data = payload.data;
Assert.ok(data, "Has Data");
if (data) {
Assert.ok(data.baseData, "Has BaseData");
let baseData = data.baseData;
if (baseData) {
const ex = baseData.exceptions[0];
Assert.ok(ex.message.indexOf("Test_Error_Throwing_Inside_UseCallback") !== -1, "Make sure the error message is present [" + ex.message + "]");
Assert.ok(ex.stack.length > 0, "Has stack");
Assert.ok(ex.parsedStack, "Stack was parsed");
Assert.ok(ex.hasFullStack, "Stack has been decoded");
Assert.equal(ex.parsedStack.length, 29);
for (let lp = 0; lp < ex.parsedStack.length; lp++) {
_checkExpectedFrame(expectedParsedStack[lp], ex.parsedStack[lp], lp);
}

Assert.ok(baseData.properties, "Has BaseData properties");
Assert.equal(baseData.properties.custom, "custom value");

}
}
}
})
})

this.testCaseAsync({
name: "E2E.GenericTests: trackException with multiple line message",
stepDelay: 1,
steps: [() => {
let message = "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n" +
"1. You might have mismatching versions of React and the renderer (such as React DOM)\n" +
"2. You might be breaking the Rules of Hooks\n" +
"3. You might have more than one copy of React in the same app\n" +
"See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.";
let errObj = {
typeName: "Error",
reason:{
message: "Error: " + message,
stack: "Error: " + message + "\n" +
" at Object.throwInvalidHookError (https://localhost:44365/static/js/bundle.js:201419:13)\n" +
" at useContext (https://localhost:44365/static/js/bundle.js:222943:25)\n" +
" at useTenantContext (https://localhost:44365/static/js/bundle.js:5430:68)\n" +
" at https://localhost:44365/static/js/bundle.js:4337:72\n" +
" at _ZoneDelegate.invoke (https://localhost:44365/static/js/bundle.js:227675:158)\n" +
" at ZoneImpl.run (https://localhost:44365/static/js/bundle.js:227446:35)\n" +
" at https://localhost:44365/static/js/bundle.js:229764:30\n" +
" at _ZoneDelegate.invokeTask (https://localhost:44365/static/js/bundle.js:227700:171)\n" +
" at ZoneImpl.runTask (https://localhost:44365/static/js/bundle.js:227499:37)\n" +
" at ZoneImpl.patchRunTask (https://localhost:44365/static/js/bundle.js:144112:27)"
}
};

let exception = Exception.CreateAutoException(message,
"url",
9,
0,
errObj
);
this._ai.trackException({ exception: exception }, { custom: "custom value" });
}].concat(this.asserts(1)).concat(() => {

const expectedParsedStack: IStackFrame[] = [
{ level: 0, method: "Object.throwInvalidHookError", assembly: "at Object.throwInvalidHookError (https://localhost:44365/static/js/bundle.js:201419:13)", fileName: "https://localhost:44365/static/js/bundle.js", line: 201419 },
{ level: 1, method: "useContext", assembly: "at useContext (https://localhost:44365/static/js/bundle.js:222943:25)", fileName: "https://localhost:44365/static/js/bundle.js", line: 222943 },
{ level: 2, method: "useTenantContext", assembly: "at useTenantContext (https://localhost:44365/static/js/bundle.js:5430:68)", fileName: "https://localhost:44365/static/js/bundle.js", line: 5430 },
{ level: 3, method: "<no_method>", assembly: "at https://localhost:44365/static/js/bundle.js:4337:72", fileName: "https://localhost:44365/static/js/bundle.js", line: 4337 },
{ level: 4, method: "_ZoneDelegate.invoke", assembly: "at _ZoneDelegate.invoke (https://localhost:44365/static/js/bundle.js:227675:158)", fileName: "https://localhost:44365/static/js/bundle.js", line: 227675 },
{ level: 5, method: "ZoneImpl.run", assembly: "at ZoneImpl.run (https://localhost:44365/static/js/bundle.js:227446:35)", fileName: "https://localhost:44365/static/js/bundle.js", line: 227446 },
{ level: 6, method: "<no_method>", assembly: "at https://localhost:44365/static/js/bundle.js:229764:30", fileName: "https://localhost:44365/static/js/bundle.js", line: 229764 },
{ level: 7, method: "_ZoneDelegate.invokeTask", assembly: "at _ZoneDelegate.invokeTask (https://localhost:44365/static/js/bundle.js:227700:171)", fileName: "https://localhost:44365/static/js/bundle.js", line: 227700 },
{ level: 8, method: "ZoneImpl.runTask", assembly: "at ZoneImpl.runTask (https://localhost:44365/static/js/bundle.js:227499:37)", fileName: "https://localhost:44365/static/js/bundle.js", line: 227499 },
{ level: 9, method: "ZoneImpl.patchRunTask", assembly: "at ZoneImpl.patchRunTask (https://localhost:44365/static/js/bundle.js:144112:27)", fileName: "https://localhost:44365/static/js/bundle.js", line: 144112 }
];

const payloadStr: string[] = this.getPayloadMessages(this.successSpy);
if (payloadStr.length > 0) {
const payload = JSON.parse(payloadStr[0]);
const data = payload.data;
Assert.ok(data, "Has Data");
if (data) {
Assert.ok(data.baseData, "Has BaseData");
let baseData = data.baseData;
if (baseData) {
const ex = baseData.exceptions[0];
Assert.ok(ex.message.indexOf("Invalid hook call") !== -1, "Make sure the error message is present [" + ex.message + "]");
Assert.ok(ex.stack.length > 0, "Has stack");
Assert.ok(ex.parsedStack, "Stack was parsed");
Assert.ok(ex.hasFullStack, "Stack has been decoded");
Assert.equal(ex.parsedStack.length, 10);
for (let lp = 0; lp < ex.parsedStack.length; lp++) {
_checkExpectedFrame(expectedParsedStack[lp], ex.parsedStack[lp], lp);
}

Assert.ok(baseData.properties, "Has BaseData properties");
Assert.equal(baseData.properties.custom, "custom value");

}
}
}
})
})

this.testCaseAsync({
name: "TelemetryContext: track metric",
stepDelay: 1,
Expand Down
Loading
Loading