diff --git a/packages/core/src/tools/experimentalFeatures.ts b/packages/core/src/tools/experimentalFeatures.ts index c4b40642d9..9a05a48029 100644 --- a/packages/core/src/tools/experimentalFeatures.ts +++ b/packages/core/src/tools/experimentalFeatures.ts @@ -17,6 +17,7 @@ export enum ExperimentalFeature { WRITABLE_RESOURCE_GRAPHQL = 'writable_resource_graphql', CUSTOM_VITALS = 'custom_vitals', TOLERANT_RESOURCE_TIMINGS = 'tolerant_resource_timings', + ENABLE_PRIVACY_FOR_ACTION_NAME = 'enable_privacy_for_action_name', MICRO_FRONTEND = 'micro_frontend', } diff --git a/packages/rum-core/src/domain/action/getActionNameFromElement.spec.ts b/packages/rum-core/src/domain/action/getActionNameFromElement.spec.ts index 3ef7567603..5017702347 100644 --- a/packages/rum-core/src/domain/action/getActionNameFromElement.spec.ts +++ b/packages/rum-core/src/domain/action/getActionNameFromElement.spec.ts @@ -1,348 +1,602 @@ import { appendElement } from '../../../test' +import { NodePrivacyLevel } from '../privacy' +import type { RumConfiguration } from '../configuration' import { getActionNameFromElement } from './getActionNameFromElement' +const defaultConfiguration = {} as RumConfiguration + describe('getActionNameFromElement', () => { it('extracts the textual content of an element', () => { - expect(getActionNameFromElement(appendElement('
Foo
bar
'))).toBe('Foo bar') + const name = getActionNameFromElement(appendElement('
Foo
bar
'), defaultConfiguration) + expect(name).toBe('Foo bar') }) it('extracts the text of an input button', () => { - expect(getActionNameFromElement(appendElement(''))).toBe('Click') + const name = getActionNameFromElement(appendElement(''), defaultConfiguration) + expect(name).toBe('Click') }) it('extracts the alt text of an image', () => { - expect(getActionNameFromElement(appendElement('bar'))).toBe('bar') + const name = getActionNameFromElement(appendElement('bar'), defaultConfiguration) + expect(name).toBe('bar') }) it('extracts the title text of an image', () => { - expect(getActionNameFromElement(appendElement(''))).toBe('foo') + const name = getActionNameFromElement(appendElement(''), defaultConfiguration) + expect(name).toBe('foo') }) it('extracts the text of an aria-label attribute', () => { - expect(getActionNameFromElement(appendElement(''))).toBe('Foo') + const name = getActionNameFromElement(appendElement(''), defaultConfiguration) + expect(name).toBe('Foo') }) it('gets the parent element textual content if everything else fails', () => { - expect(getActionNameFromElement(appendElement('
Foo
'))).toBe('Foo') + const name = getActionNameFromElement(appendElement('
Foo
'), defaultConfiguration) + expect(name).toBe('Foo') }) it("doesn't get the value of a text input", () => { - expect(getActionNameFromElement(appendElement(''))).toBe('') + const name = getActionNameFromElement(appendElement(''), defaultConfiguration) + expect(name).toBe('') }) it("doesn't get the value of a password input", () => { - expect(getActionNameFromElement(appendElement(''))).toBe('') + const name = getActionNameFromElement(appendElement(''), defaultConfiguration) + expect(name).toBe('') }) it('limits the name length to a reasonable size', () => { - expect( - getActionNameFromElement( - appendElement( - '
Foooooooooooooooooo baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaar baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaz
' - ) - ) - ).toBe('Foooooooooooooooooo baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa [...]') + const name = getActionNameFromElement( + appendElement( + '
Foooooooooooooooooo baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaar baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaz
' + ), + defaultConfiguration + ) + expect(name).toBe( + 'Foooooooooooooooooo baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa [...]' + ) }) it('normalize white spaces', () => { - expect(getActionNameFromElement(appendElement('
foo\tbar\n\n baz
'))).toBe('foo bar baz') + const name = getActionNameFromElement(appendElement('
foo\tbar\n\n baz
'), defaultConfiguration) + expect(name).toBe('foo bar baz') }) it('ignores the inline script textual content', () => { - expect(getActionNameFromElement(appendElement("
b
"))).toBe('b') + const name = getActionNameFromElement( + appendElement("
b
"), + defaultConfiguration + ) + expect(name).toBe('b') }) it('extracts text from SVG elements', () => { - expect(getActionNameFromElement(appendElement('foo bar'))).toBe('foo bar') + const name = getActionNameFromElement(appendElement('foo bar'), defaultConfiguration) + expect(name).toBe('foo bar') }) it('extracts text from an associated label', () => { - expect( - getActionNameFromElement( - appendElement(` -
- -
ignored
- -
- `) - ) - ).toBe('label text') + const name = getActionNameFromElement( + appendElement(` +
+ +
ignored
+ +
+ `), + defaultConfiguration + ) + expect(name).toBe('label text') }) it('extracts text from a parent label', () => { - expect( - getActionNameFromElement( - appendElement(` - - `) - ) - ).toBe('foo bar') + const name = getActionNameFromElement( + appendElement(` + + `), + defaultConfiguration + ) + expect(name).toBe('foo bar') }) it('extracts text from the first OPTION element when clicking on a SELECT', () => { - expect( - getActionNameFromElement( - appendElement(` - - `) - ) - ).toBe('foo') + const name = getActionNameFromElement( + appendElement(` + + `), + defaultConfiguration + ) + expect(name).toBe('foo') }) it('extracts text from a aria-labelledby associated element', () => { - expect( - getActionNameFromElement( - appendElement(` -
- -
ignored
- -
- `) - ) - ).toBe('label text') + const name = getActionNameFromElement( + appendElement(` +
+ +
ignored
+ +
+ `), + defaultConfiguration + ) + expect(name).toBe('label text') }) it('extracts text from multiple aria-labelledby associated elements', () => { - expect( - getActionNameFromElement( - appendElement(` -
- -
ignored
- -
ignored
- -
- `) - ) - ).toBe('label text') + const name = getActionNameFromElement( + appendElement(` +
+ +
ignored
+ +
ignored
+ +
+ `), + defaultConfiguration + ) + expect(name).toBe('label text') }) it('extracts text from a BUTTON element', () => { - expect( - getActionNameFromElement( - appendElement(` -
-
ignored
- -
- `) - ) - ).toBe('foo') + const name = getActionNameFromElement( + appendElement(` +
+
ignored
+ +
+ `), + defaultConfiguration + ) + expect(name).toBe('foo') }) it('extracts text from a role=button element', () => { - expect( - getActionNameFromElement( - appendElement(` -
-
ignored
-
foo
-
- `) - ) - ).toBe('foo') + const name = getActionNameFromElement( + appendElement(` +
+
ignored
+
foo
+
+ `), + defaultConfiguration + ) + expect(name).toBe('foo') }) it('limits the recursion to the 10th parent', () => { - expect( - getActionNameFromElement( - appendElement(` -
-
ignored
- - - -
- `) - ) - ).toBe('') + const name = getActionNameFromElement( + appendElement(` +
+
ignored
+ + + +
+ `), + defaultConfiguration + ) + expect(name).toBe('') }) it('limits the recursion to the BODY element', () => { - expect( - getActionNameFromElement( - appendElement(` -
ignored
- - `) - ) - ).toBe('') + const name = getActionNameFromElement( + appendElement(` +
ignored
+ + `), + defaultConfiguration + ) + expect(name).toBe('') }) it('limits the recursion to a FORM element', () => { - expect( - getActionNameFromElement( - appendElement(` -
-
ignored
-
- -
-
- `) - ) - ).toBe('') + const name = getActionNameFromElement( + appendElement(` +
+
ignored
+
+ +
+
+ `), + defaultConfiguration + ) + expect(name).toBe('') }) it('extracts the name from a parent FORM element', () => { - expect( - getActionNameFromElement( - appendElement(` -
-
ignored
-
- -
-
- `) - ) - ).toBe('foo') + const name = getActionNameFromElement( + appendElement(` +
+
ignored
+
+ +
+
+ `), + defaultConfiguration + ) + expect(name).toBe('foo') }) it('extracts the whole textual content of a button', () => { - expect( - getActionNameFromElement( - appendElement(` - - `) - ) - ).toBe('foo bar') + const name = getActionNameFromElement( + appendElement(` + + `), + defaultConfiguration + ) + expect(name).toBe('foo bar') }) it('ignores the textual content of contenteditable elements', () => { - expect( - getActionNameFromElement( - appendElement(` -
- ignored - ignored -
- `) - ) - ).toBe('') + const name = getActionNameFromElement( + appendElement(` +
+ ignored + ignored +
+ `), + defaultConfiguration + ) + expect(name).toBe('') }) it('extracts the name from attributes of contenteditable elements', () => { - expect( - getActionNameFromElement( - appendElement(` -
- ignored - ignored -
- `) - ) - ).toBe('foo') + const name = getActionNameFromElement( + appendElement(` +
+ ignored + ignored +
+ `), + defaultConfiguration + ) + expect(name).toBe('foo') }) it('computes an action name on SVG elements (IE does not support parentElement property on them)', () => { - expect( - getActionNameFromElement( - appendElement(` -