Skip to content

Commit

Permalink
feat: add reporting for shadowSupportMode (#3980)
Browse files Browse the repository at this point in the history
* feat: add reporting for shadowSupportMode
  • Loading branch information
jye-sf committed Feb 7, 2024
1 parent 314ab66 commit 72c8c09
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 1 deletion.
12 changes: 12 additions & 0 deletions packages/@lwc/engine-core/src/framework/def.ts
Expand Up @@ -48,6 +48,7 @@ import {
HTMLElementConstructor,
} from './base-bridge-element';
import { getComponentOrSwappedComponent } from './hot-swaps';
import { isReportingEnabled, report, ReportingEventId } from './reporting';

export interface ComponentDef {
name: string;
Expand Down Expand Up @@ -198,6 +199,17 @@ function createComponentDef(Ctor: LightningElementConstructor): ComponentDef {
let shadowSupportMode = superDef.shadowSupportMode;
if (!isUndefined(ctorShadowSupportMode)) {
shadowSupportMode = ctorShadowSupportMode;

if (
isReportingEnabled() &&
(shadowSupportMode === ShadowSupportMode.Any ||
shadowSupportMode === ShadowSupportMode.Native)
) {
report(ReportingEventId.ShadowSupportModeUsage, {
tagName: Ctor.name,
mode: shadowSupportMode,
});
}
}

let renderMode = superDef.renderMode;
Expand Down
10 changes: 9 additions & 1 deletion packages/@lwc/engine-core/src/framework/reporting.ts
Expand Up @@ -6,7 +6,7 @@
*/
import { noop } from '@lwc/shared';

import { ShadowMode } from './vm';
import { ShadowMode, ShadowSupportMode } from './vm';

export const enum ReportingEventId {
CrossRootAriaInSyntheticShadow = 'CrossRootAriaInSyntheticShadow',
Expand All @@ -16,6 +16,7 @@ export const enum ReportingEventId {
StylesheetMutation = 'StylesheetMutation',
ConnectedCallbackWhileDisconnected = 'ConnectedCallbackWhileDisconnected',
ShadowModeUsage = 'ShadowModeUsage',
ShadowSupportModeUsage = 'ShadowSupportModeUsage',
}

export interface BasePayload {
Expand Down Expand Up @@ -51,6 +52,12 @@ export interface ShadowModeUsagePayload extends BasePayload {
mode: ShadowMode;
}

// TODO [#3981]: Add schema to o11y schema repo so that we can use 'ctorName' or 'name'
// instead of overloading 'tagName'.
export interface ShadowSupportModeUsagePayload extends BasePayload {
mode: ShadowSupportMode;
}

export type ReportingPayloadMapping = {
[ReportingEventId.CrossRootAriaInSyntheticShadow]: CrossRootAriaInSyntheticShadowPayload;
[ReportingEventId.CompilerRuntimeVersionMismatch]: CompilerRuntimeVersionMismatchPayload;
Expand All @@ -59,6 +66,7 @@ export type ReportingPayloadMapping = {
[ReportingEventId.StylesheetMutation]: StylesheetMutationPayload;
[ReportingEventId.ConnectedCallbackWhileDisconnected]: ConnectedCallbackWhileDisconnectedPayload;
[ReportingEventId.ShadowModeUsage]: ShadowModeUsagePayload;
[ReportingEventId.ShadowSupportModeUsage]: ShadowSupportModeUsagePayload;
};

export type ReportingDispatcher<T extends ReportingEventId = ReportingEventId> = (
Expand Down
@@ -0,0 +1,66 @@
import { createElement } from 'lwc';
import { attachReportingControlDispatcher, detachReportingControlDispatcher } from 'test-utils';

import Any from 'x/any';
import Reset from 'x/reset';
import None from 'x/none';
import NativeOnly from 'x/native';

// Should be kept in sync with the enum in vm.ts
const ShadowSupportMode = {
Any: 'any',
Default: 'reset',
Native: 'native',
};

/**
* These tests must be the first ones to generate the component def for the components they use.
* This is because subsequent calls to create the component will use the cached ctor rather than
* recreating the entire def. We only report on that initial def creation for perf reasons.
*/
describe('shadow support mode reporting', () => {
let dispatcher;

beforeEach(() => {
dispatcher = jasmine.createSpy();
attachReportingControlDispatcher(dispatcher, ['ShadowSupportModeUsage']);
});

afterEach(() => {
detachReportingControlDispatcher();
});

it('should report use of value "any"', () => {
expect(() => {
createElement('x-any', { is: Any });
}).toLogWarningDev(/Invalid value 'any' for static property shadowSupportMode/);

expect(dispatcher).toHaveBeenCalledTimes(1);
expect(dispatcher).toHaveBeenCalledWith('ShadowSupportModeUsage', {
tagName: Any.name,
mode: ShadowSupportMode.Any,
});
});

it('should report use of value "native"', () => {
createElement('x-native', { is: NativeOnly });

expect(dispatcher).toHaveBeenCalledTimes(1);
expect(dispatcher).toHaveBeenCalledWith('ShadowSupportModeUsage', {
tagName: NativeOnly.name,
mode: ShadowSupportMode.Native,
});
});

it('should not report use of value "reset"', () => {
createElement('x-reset', { is: Reset });

expect(dispatcher).toHaveBeenCalledTimes(0);
});

it('should not report when no value is provided', () => {
createElement('x-none', { is: None });

expect(dispatcher).toHaveBeenCalledTimes(0);
});
});
@@ -0,0 +1,5 @@
import { LightningElement } from 'lwc';

export default class Any extends LightningElement {
static shadowSupportMode = 'any';
}
@@ -0,0 +1,5 @@
import { LightningElement } from 'lwc';

export default class Native extends LightningElement {
static shadowSupportMode = 'native';
}
@@ -0,0 +1,3 @@
import { LightningElement } from 'lwc';

export default class None extends LightningElement {}
@@ -0,0 +1,5 @@
import { LightningElement } from 'lwc';

export default class Reset extends LightningElement {
static shadowSupportMode = 'reset';
}

0 comments on commit 72c8c09

Please sign in to comment.