diff --git a/Declarations/Constants.ts b/Declarations/Constants.ts index a89ef8173..d40624675 100644 --- a/Declarations/Constants.ts +++ b/Declarations/Constants.ts @@ -58,7 +58,7 @@ export const PerformanceToQuickPulseCounter: {[key: string]: QuickPulseCounter} // Note: Explicitly define these types instead of using enum due to // potential 'export enum' issues with typescript < 2.0. -export type QuickPulseDocumentType = "Event" | "Exception" | "Trace" | "Metric" | "Request" | "RemoteDependency" | "Availability"; +export type QuickPulseDocumentType = "Event" | "Exception" | "Trace" | "Metric" | "Request" | "RemoteDependency" | "Availability" | "PageView"; export type QuickPulseType = | "EventTelemetryDocument" | "ExceptionTelemetryDocument" @@ -66,7 +66,8 @@ export type QuickPulseType = | "MetricTelemetryDocument" | "RequestTelemetryDocument" | "DependencyTelemetryDocument" - | "AvailabilityTelemetryDocument"; + | "AvailabilityTelemetryDocument" + | "PageViewTelemetryDocument"; export const QuickPulseDocumentType: {[key in Contracts.TelemetryTypeKeys]: QuickPulseDocumentType} = { Event: "Event", @@ -75,7 +76,8 @@ export const QuickPulseDocumentType: {[key in Contracts.TelemetryTypeKeys]: Quic Metric: "Metric", Request: "Request", Dependency: "RemoteDependency", - Availability: "Availability" + Availability: "Availability", + PageView: "PageView", }; export const QuickPulseType: {[key in Contracts.TelemetryTypeKeys]: QuickPulseType} = { @@ -85,7 +87,8 @@ export const QuickPulseType: {[key in Contracts.TelemetryTypeKeys]: QuickPulseTy Metric: "MetricTelemetryDocument", Request: "RequestTelemetryDocument", Dependency: "DependencyTelemetryDocument", - Availability: "AvailabilityTelemetryDocument" + Availability: "AvailabilityTelemetryDocument", + PageView: "PageViewTelemetryDocument", }; export const TelemetryTypeStringToQuickPulseType: {[key in Contracts.TelemetryTypeValues]: QuickPulseType} = { @@ -95,7 +98,8 @@ export const TelemetryTypeStringToQuickPulseType: {[key in Contracts.TelemetryTy MetricData: QuickPulseType.Metric, RequestData: QuickPulseType.Request, RemoteDependencyData: QuickPulseType.Dependency, - AvailabilityData: QuickPulseType.Availability + AvailabilityData: QuickPulseType.Availability, + PageViewData: QuickPulseType.PageView }; export const TelemetryTypeStringToQuickPulseDocumentType: {[key in Contracts.TelemetryTypeValues]: QuickPulseDocumentType} = { @@ -105,5 +109,6 @@ export const TelemetryTypeStringToQuickPulseDocumentType: {[key in Contracts.Tel MetricData: QuickPulseDocumentType.Metric, RequestData: QuickPulseDocumentType.Request, RemoteDependencyData: QuickPulseDocumentType.Dependency, - AvailabilityData: QuickPulseDocumentType.Availability + AvailabilityData: QuickPulseDocumentType.Availability, + PageViewData: QuickPulseDocumentType.PageView }; diff --git a/Declarations/Contracts/TelemetryTypes/PageViewTelemetry.ts b/Declarations/Contracts/TelemetryTypes/PageViewTelemetry.ts new file mode 100644 index 000000000..af2126e42 --- /dev/null +++ b/Declarations/Contracts/TelemetryTypes/PageViewTelemetry.ts @@ -0,0 +1,27 @@ +import { Telemetry } from "./Telemetry"; + +/** + * Telemetry type used for availability web test results. + */ +export interface PageViewTelemetry extends Telemetry { + + /** + * Name of the test that these availability results represent. + */ + name?: string; + + /** + * URL of the page to track. + */ + url?: string; + + /** + * Request duration in ms + */ + duration?: number; + + /** + * Metrics associated with this event, displayed in Metrics Explorer on the portal. + */ + measurements?: { [key: string]: number; }; +} \ No newline at end of file diff --git a/Declarations/Contracts/TelemetryTypes/TelemetryType.ts b/Declarations/Contracts/TelemetryTypes/TelemetryType.ts index 24c4ffdc2..a473c90e7 100644 --- a/Declarations/Contracts/TelemetryTypes/TelemetryType.ts +++ b/Declarations/Contracts/TelemetryTypes/TelemetryType.ts @@ -1,4 +1,4 @@ -export type TelemetryTypeKeys = "Event" | "Exception" | "Trace" | "Metric" | "Request" | "Dependency" | "Availability"; +export type TelemetryTypeKeys = "Event" | "Exception" | "Trace" | "Metric" | "Request" | "Dependency" | "Availability" | "PageView"; export type TelemetryTypeValues = | "EventData" | "ExceptionData" @@ -6,7 +6,8 @@ export type TelemetryTypeValues = | "MetricData" | "RequestData" | "RemoteDependencyData" - | "AvailabilityData"; + | "AvailabilityData" + | "PageViewData"; /** * Converts the user-friendly enumeration TelemetryType to the underlying schema baseType value @@ -28,6 +29,8 @@ export function telemetryTypeToBaseType(type: TelemetryType): TelemetryTypeValue return "RemoteDependencyData"; case TelemetryType.Availability: return "AvailabilityData"; + case TelemetryType.PageView: + return "PageViewData"; } return undefined; } @@ -52,6 +55,8 @@ export function baseTypeToTelemetryType(baseType: TelemetryTypeValues): Telemetr return TelemetryType.Dependency; case "AvailabilityData": return TelemetryType.Availability; + case "PageViewData": + return TelemetryType.PageView; } return undefined; } @@ -63,7 +68,8 @@ export const TelemetryTypeString: {[key: string]: TelemetryTypeValues} = { Metric: "MetricData", Request: "RequestData", Dependency: "RemoteDependencyData", - Availability: "AvailabilityData" + Availability: "AvailabilityData", + PageView: "PageViewData", } /** @@ -76,7 +82,8 @@ export enum TelemetryType { Metric, Request, Dependency, - Availability + Availability, + PageView } export interface Identified { diff --git a/Declarations/Contracts/TelemetryTypes/index.ts b/Declarations/Contracts/TelemetryTypes/index.ts index a2493e866..c7dd2ed24 100644 --- a/Declarations/Contracts/TelemetryTypes/index.ts +++ b/Declarations/Contracts/TelemetryTypes/index.ts @@ -9,5 +9,6 @@ export * from "./Telemetry"; export * from "./NodeHttpDependencyTelemetry"; export * from "./NodeHttpRequestTelemetry"; export * from "./AvailabilityTelemetry"; +export * from "./PageViewTelemetry"; export * from "./TelemetryType"; \ No newline at end of file diff --git a/Library/EnvelopeFactory.ts b/Library/EnvelopeFactory.ts index 3ee5924b3..7cd499f7e 100644 --- a/Library/EnvelopeFactory.ts +++ b/Library/EnvelopeFactory.ts @@ -51,6 +51,9 @@ class EnvelopeFactory { case Contracts.TelemetryType.Availability: data = EnvelopeFactory.createAvailabilityData(telemetry); break; + case Contracts.TelemetryType.PageView: + data = EnvelopeFactory.createPageViewData(telemetry); + break; } if (commonProperties && Contracts.domainSupportsProperties(data.baseData)) { // Do instanceof check. TS will automatically cast and allow the properties property @@ -246,6 +249,24 @@ class EnvelopeFactory { return data; } + private static createPageViewData( + telemetry: Contracts.PageViewTelemetry & Contracts.Identified, + ): Contracts.Data { + let pageViewData = new Contracts.PageViewData(); + + pageViewData.name = telemetry.name; + pageViewData.duration = Util.msToTimeSpan(telemetry.duration); + pageViewData.url = telemetry.url; + pageViewData.measurements = telemetry.measurements; + pageViewData.properties = telemetry.properties; + + let data = new Contracts.Data(); + data.baseType = Contracts.telemetryTypeToBaseType(Contracts.TelemetryType.PageView); + data.baseData = pageViewData; + + return data; + } + private static getTags(context: Context, tagOverrides?: { [key: string]: string; }) { var correlationContext = CorrelationContextManager.getCurrentContext(); diff --git a/Library/TelemetryClient.ts b/Library/TelemetryClient.ts index 054880e5f..214297f43 100644 --- a/Library/TelemetryClient.ts +++ b/Library/TelemetryClient.ts @@ -49,6 +49,14 @@ class TelemetryClient { this.track(telemetry, Contracts.TelemetryType.Availability); } + /** + * Log a page view + * @param telemetry Object encapsulating tracking options + */ + public trackPageView(telemetry: Contracts.PageViewTelemetry): void { + this.track(telemetry, Contracts.TelemetryType.PageView); + } + /** * Log a trace message * @param telemetry Object encapsulating tracking options diff --git a/Tests/Library/Client.tests.ts b/Tests/Library/Client.tests.ts index e86f6f1ca..540c4fa61 100644 --- a/Tests/Library/Client.tests.ts +++ b/Tests/Library/Client.tests.ts @@ -109,6 +109,33 @@ describe("Library/TelemetryClient", () => { }); }); + describe("#trackPageView()", () => { + it("should track Page View with correct data", () => { + trackStub.reset(); + client.trackPageView({ name: name }); + client.trackPageView({ name: name, properties, measurements }); + client.trackPageView({ name: name, url: "https://www.test.com", duration: 100 }); + + assert.ok(trackStub.calledThrice); + + var eventTelemetry1 = trackStub.firstCall.args[0]; + var eventTelemetry2 = trackStub.secondCall.args[0]; + var eventTelemetry3 = trackStub.thirdCall.args[0]; + + assert.equal(eventTelemetry1.name, name); + assert.equal(eventTelemetry2.name, name); + assert.deepEqual(eventTelemetry2.properties, properties); + assert.deepEqual(eventTelemetry2.measurements, measurements); + assert.equal(eventTelemetry3.name, name); + assert.equal(eventTelemetry3.url, "https://www.test.com"); + assert.equal(eventTelemetry3.duration, 100); + }); + + it("should not crash with invalid input", () => { + invalidInputHelper("trackPageView"); + }); + }); + describe("#trackTrace()", () => { it("should track Trace with correct data", () => { trackStub.reset(); diff --git a/Tests/Library/EnvelopeFactoryTests.ts b/Tests/Library/EnvelopeFactoryTests.ts index b31ac5ae1..8d30a984a 100644 --- a/Tests/Library/EnvelopeFactoryTests.ts +++ b/Tests/Library/EnvelopeFactoryTests.ts @@ -170,4 +170,33 @@ describe("Library/EnvelopeFactory", () => { }); }); + + describe("PageViewData", () => { + let pageViewTelemetry: Contracts.PageViewTelemetry; + beforeEach(() => { + pageViewTelemetry = { + duration: 100, + measurements: { "m1" : 1}, + properties: { + "prop1" : "prop1 value" + }, + url: "https://www.test.com", + name: "availability test name", + }; + }); + + it("creates data with given content", () => { + var envelope = EnvelopeFactory.createEnvelope(pageViewTelemetry, Contracts.TelemetryType.PageView); + var data = >envelope.data; + + assert.deepEqual(data.baseType, "PageViewData"); + + assert.deepEqual(data.baseData.url, pageViewTelemetry.url); + assert.deepEqual(data.baseData.measurements, pageViewTelemetry.measurements); + assert.deepEqual(data.baseData.name, pageViewTelemetry.name); + assert.deepEqual(data.baseData.properties, pageViewTelemetry.properties); + assert.deepEqual(data.baseData.duration, Util.msToTimeSpan(pageViewTelemetry.duration)); + + }); + }); });