Skip to content

Port PR #8410 to dev: Track online/offline status change#8411

Open
Copilot wants to merge 5 commits intodevfrom
copilot/port-changes-to-dev-branch
Open

Port PR #8410 to dev: Track online/offline status change#8411
Copilot wants to merge 5 commits intodevfrom
copilot/port-changes-to-dev-branch

Conversation

Copy link
Contributor

Copilot AI commented Mar 11, 2026

  • Add startOnlineStatus and onlineStatusChangeCount fields to PerformanceEvent type in msal-common
  • Update BrowserPerformanceClient to add getOnlineStatus() method and capture startOnlineStatus in startMeasurement
  • Refactor StandardController event listener management: renamed methods, added addStateChangeListeners/removeStateChangeListeners helpers; added onlineStatusChangeCount tracking
  • Add test for online status capture in BrowserPerformanceClient.spec.ts
  • Update msal-common.api.md to include new fields
  • Create Beachball changefiles for @azure/msal-browser and @azure/msal-common
  • Create PR Port PR #8410 to dev: Track online/offline status change #8411

🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

Copilot AI and others added 2 commits March 10, 2026 23:30
Co-authored-by: tnorling <5307810+tnorling@users.noreply.github.com>
Co-authored-by: tnorling <5307810+tnorling@users.noreply.github.com>
@tnorling tnorling marked this pull request as ready for review March 11, 2026 23:03
@tnorling tnorling requested a review from a team as a code owner March 11, 2026 23:03
Copilot AI review requested due to automatic review settings March 11, 2026 23:03
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Ports telemetry enhancements to track browser online/offline status in performance events, extending msal-common’s PerformanceEvent and wiring capture/increment logic into msal-browser’s telemetry and controller flows.

Changes:

  • Add startOnlineStatus and onlineStatusChangeCount to PerformanceEvent (and API review output).
  • Capture navigator.onLine at BrowserPerformanceClient.startMeasurement() and track online/offline transitions during relevant StandardController operations.
  • Add/change tests and add Beachball changefiles for @azure/msal-common and @azure/msal-browser.

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
package-lock.json Lockfile metadata changes (appears unrelated to telemetry changes).
lib/msal-common/src/telemetry/performance/PerformanceEvent.ts Adds new performance telemetry fields for online status.
lib/msal-common/apiReview/msal-common.api.md Updates API review output to include the new fields.
lib/msal-browser/src/telemetry/BrowserPerformanceClient.ts Captures startOnlineStatus at measurement start.
lib/msal-browser/src/controllers/StandardController.ts Adds online/offline listener tracking and increments onlineStatusChangeCount.
lib/msal-browser/test/telemetry/BrowserPerformanceClient.spec.ts Adds/updates tests for online status capture.
change/@azure-msal-common-6ffbe68f-0ad5-41ae-94a3-401210f04254.json Beachball changefile for @azure/msal-common.
change/@azure-msal-browser-064efeaa-53d7-4265-a60b-0fe45d1835e2.json Beachball changefile for @azure/msal-browser.
Comments suppressed due to low confidence (1)

lib/msal-browser/src/controllers/StandardController.ts:2091

  • State change listeners are added before initializeSilentRequest is awaited, but they are only removed in the .finally attached to the result promise later. If initializeSilentRequest rejects/throws, execution exits early and removeStateChangeListeners is never called, leaking the listeners (now 3 listeners instead of 1). Wrap the listener lifecycle in a try/finally (or ensure removal on the await failure path) so listeners are always cleaned up.
        this.addStateChangeListeners(trackStateChange);

        const silentRequest = await invokeAsync(
            initializeSilentRequest,
            BrowserPerformanceEvents.InitializeSilentRequest,
            this.logger,
            this.performanceClient,
            request.correlationId
        )(request, account, this.config, this.performanceClient, this.logger);

Comment on lines +931 to +948
"Perf: Visibility change detected in ",
measurement.event.name
);
measurement.increment({
visibilityChangeCount: 1,
});
} else if (event.type === "online") {
this.logger.info(
"Perf: Online status change detected in ",
measurement.event.name
);
measurement.increment({
onlineStatusChangeCount: 1,
});
} else if (event.type === "offline") {
this.logger.info(
"Perf: Offline status change detected in ",
measurement.event.name
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logger.info's second parameter is a correlationId, but here measurement.event.name is being passed as that argument. This will log an incorrect correlationId and makes log correlation/debugging unreliable. Include measurement.event.name in the message string instead, and pass measurement.event.correlationId (or another real correlation id) as the second argument.

Suggested change
"Perf: Visibility change detected in ",
measurement.event.name
);
measurement.increment({
visibilityChangeCount: 1,
});
} else if (event.type === "online") {
this.logger.info(
"Perf: Online status change detected in ",
measurement.event.name
);
measurement.increment({
onlineStatusChangeCount: 1,
});
} else if (event.type === "offline") {
this.logger.info(
"Perf: Offline status change detected in ",
measurement.event.name
`Perf: Visibility change detected in ${measurement.event.name}`,
measurement.event.correlationId
);
measurement.increment({
visibilityChangeCount: 1,
});
} else if (event.type === "online") {
this.logger.info(
`Perf: Online status change detected in ${measurement.event.name}`,
measurement.event.correlationId
);
measurement.increment({
onlineStatusChangeCount: 1,
});
} else if (event.type === "offline") {
this.logger.info(
`Perf: Offline status change detected in ${measurement.event.name}`,
measurement.event.correlationId

Copilot uses AI. Check for mistakes.
Comment on lines +103 to 111
it("captures online status at measurement start", () => {
jest.spyOn(
Object.getPrototypeOf(navigator),
"onLine",
"get"
).mockReturnValue(true);
});

it("includes network information in performance event result", () => {
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new test captures online status at measurement start sets up a spy but never starts a measurement or asserts on the result, so it doesn't validate behavior and will pass even if startOnlineStatus is broken. Fold this setup/assertion into a real measurement (or remove the test) and ensure the spy is applied in the same test that asserts the field.

Suggested change
it("captures online status at measurement start", () => {
jest.spyOn(
Object.getPrototypeOf(navigator),
"onLine",
"get"
).mockReturnValue(true);
});
it("includes network information in performance event result", () => {
it("includes network information in performance event result", () => {
jest.spyOn(
Object.getPrototypeOf(navigator),
"onLine",
"get"
).mockReturnValue(true);

Copilot uses AI. Check for mistakes.
Comment on lines 111 to 138
@@ -125,6 +133,7 @@ describe("BrowserPerformanceClient.ts", () => {

const result = measurement.end();

expect(result?.startOnlineStatus).toBe(true);
expect(result?.networkEffectiveType).toBe("4g");
expect(result?.networkRtt).toBe(50);
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test expects startOnlineStatus to be true but doesn't mock navigator.onLine in this test. Because jest.restoreAllMocks() runs after each test, the spy created in the prior test won't be active here, making this assertion environment-dependent/flaky. Mock navigator.onLine (or define the property) within this test (or in a beforeEach) before calling startMeasurement.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants