UNPKG

chrome-devtools-frontend

Version:
272 lines (243 loc) • 11.7 kB
// Copyright 2023 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import * as Common from '../../core/common/common.js'; import * as Host from '../../core/host/host.js'; import {expectCalled} from '../../testing/ExpectStubCall.js'; import {getVeId} from '../../testing/VisualLoggingHelpers.js'; import * as VisualLogging from './visual_logging-testing.js'; describe('LoggingEvents', () => { let parent: Element; let element: Element; let veid: number; let throttler: Common.Throttler.Throttler; beforeEach(() => { parent = document.createElement('div'); element = document.createElement('div'); VisualLogging.LoggingState.getOrCreateLoggingState(parent, {ve: 1}); VisualLogging.LoggingState.getOrCreateLoggingState(element, {ve: 1, context: '42'}, parent); veid = getVeId(element); throttler = new Common.Throttler.Throttler(1000000); }); afterEach(async () => { await throttler.schedule(async () => {}, Common.Throttler.Scheduling.AS_SOON_AS_POSSIBLE); }); async function assertThrottled(stub: sinon.SinonStub) { await new Promise(resolve => setTimeout(resolve, 0)); sinon.assert.notCalled(stub); await throttler.process?.(); sinon.assert.calledOnce(stub); } it('calls UI binding to log an impression', async () => { const recordImpression = sinon.stub( Host.InspectorFrontendHost.InspectorFrontendHostInstance, 'recordImpression', ); await VisualLogging.LoggingEvents.logImpressions([element, parent]); sinon.assert.calledOnce(recordImpression); assert.sameDeepMembers(recordImpression.firstCall.firstArg.impressions, [ {id: veid, type: 1, context: 42, parent: getVeId(parent), height: 0, width: 0}, {id: getVeId(parent), type: 1, height: 0, width: 0}, ]); }); it('calls UI binding to log a click', async () => { const recordClick = sinon.stub( Host.InspectorFrontendHost.InspectorFrontendHostInstance, 'recordClick', ); // @ts-expect-error const event = new MouseEvent('click', {button: 0, sourceCapabilities: new InputDeviceCapabilities()}); VisualLogging.LoggingEvents.logClick(throttler)(element, event); await assertThrottled(recordClick); assert.deepEqual(recordClick.firstCall.firstArg, {veid, mouseButton: 0, doubleClick: false}); }); it('does not set mouse button for synthetic clicks', async () => { const recordClick = sinon.stub( Host.InspectorFrontendHost.InspectorFrontendHostInstance, 'recordClick', ); const event = new MouseEvent('click', {button: 0}); VisualLogging.LoggingEvents.logClick(throttler)(element, event); await assertThrottled(recordClick); assert.deepEqual(recordClick.firstCall.firstArg, {veid, doubleClick: false}); }); it('calls UI binding to log a double click', async () => { const recordClick = sinon.stub( Host.InspectorFrontendHost.InspectorFrontendHostInstance, 'recordClick', ); const event = new MouseEvent('dblclick', {button: 1}); VisualLogging.LoggingEvents.logClick(throttler)(element, event, {doubleClick: true}); await assertThrottled(recordClick); assert.deepEqual(recordClick.firstCall.firstArg, {veid, doubleClick: true}); }); it('calls UI binding to log a change', async () => { const recordChange = sinon.stub( Host.InspectorFrontendHost.InspectorFrontendHostInstance, 'recordChange', ); await VisualLogging.LoggingEvents.logChange(element); sinon.assert.calledOnce(recordChange); assert.deepEqual(recordChange.firstCall.firstArg, {veid}); }); it('calls UI binding to log a change of specific type', async () => { const recordChange = sinon.stub( Host.InspectorFrontendHost.InspectorFrontendHostInstance, 'recordChange', ); VisualLogging.LoggingState.getLoggingState(element)!.pendingChangeContext = 'instertText'; await VisualLogging.LoggingEvents.logChange(element); sinon.assert.calledOnce(recordChange); assert.deepEqual(recordChange.firstCall.firstArg, {veid, context: 296063892}); }); it('calls UI binding to log a keydown with any code', async () => { const recordKeyDown = sinon.stub( Host.InspectorFrontendHost.InspectorFrontendHostInstance, 'recordKeyDown', ); const event = new KeyboardEvent('keydown'); void VisualLogging.LoggingEvents.logKeyDown(throttler)(element, event); await assertThrottled(recordKeyDown); assert.deepEqual(recordKeyDown.firstCall.firstArg, {veid}); }); it('calls UI binding to log a keydown with a matching code', async () => { const recordKeyDown = sinon.stub( Host.InspectorFrontendHost.InspectorFrontendHostInstance, 'recordKeyDown', ); const event = new KeyboardEvent('keydown', {code: 'Enter', key: 'Enter'}); VisualLogging.LoggingState.getLoggingState(element)!.config.track = {keydown: 'Enter|Escape'}; void VisualLogging.LoggingEvents.logKeyDown(throttler)(element, event); await assertThrottled(recordKeyDown); assert.deepEqual(recordKeyDown.firstCall.firstArg, {veid, context: 513111094}); }); it('calls UI binding to log a keydown with a matching key', async () => { const recordKeyDown = sinon.stub( Host.InspectorFrontendHost.InspectorFrontendHostInstance, 'recordKeyDown', ); const event = new KeyboardEvent('keydown', {code: 'Period', key: '>'}); VisualLogging.LoggingState.getLoggingState(element)!.config.track = {keydown: '>'}; void VisualLogging.LoggingEvents.logKeyDown(throttler)(element, event); await assertThrottled(recordKeyDown); assert.deepEqual(recordKeyDown.firstCall.firstArg, {veid: getVeId(element), context: -1098575095}); }); it('calls UI binding to log a keydown with an provided context', async () => { const recordKeyDown = sinon.stub( Host.InspectorFrontendHost.InspectorFrontendHostInstance, 'recordKeyDown', ); const event = new KeyboardEvent('keydown', {code: 'Enter'}); void VisualLogging.LoggingEvents.logKeyDown(throttler)(element, event, '21'); await assertThrottled(recordKeyDown); assert.deepEqual(recordKeyDown.firstCall.firstArg, {veid, context: 21}); }); it('throttles subsequent keydowns', async () => { const recordKeyDown = sinon.stub( Host.InspectorFrontendHost.InspectorFrontendHostInstance, 'recordKeyDown', ); const event = new KeyboardEvent('keydown', {code: 'Enter'}); void VisualLogging.LoggingEvents.logKeyDown(throttler)(element, event); void VisualLogging.LoggingEvents.logKeyDown(throttler)(element, event); await assertThrottled(recordKeyDown); }); it('does not drop keydowns with a specific context', async () => { const recordKeyDown = sinon.stub( Host.InspectorFrontendHost.InspectorFrontendHostInstance, 'recordKeyDown', ); const event = new KeyboardEvent('keydown', {code: 'Enter'}); sinon.stub(event, 'currentTarget').value(element); void VisualLogging.LoggingEvents.logKeyDown(throttler)(element, event, '1'); void VisualLogging.LoggingEvents.logKeyDown(throttler)(element, event, '2'); await new Promise(resolve => setTimeout(resolve, 0)); sinon.assert.calledOnce(recordKeyDown); await throttler.process?.(); sinon.assert.calledTwice(recordKeyDown); assert.deepEqual(recordKeyDown.firstCall.firstArg, {veid, context: 1}); assert.deepEqual(recordKeyDown.secondCall.firstArg, {veid, context: 2}); }); it('throttles subsequent keydowns with the same context', async () => { const recordKeyDown = sinon.stub( Host.InspectorFrontendHost.InspectorFrontendHostInstance, 'recordKeyDown', ); const event = new KeyboardEvent('keydown', {code: 'Enter'}); sinon.stub(event, 'currentTarget').value(element); void VisualLogging.LoggingEvents.logKeyDown(throttler)(element, event, '1'); void VisualLogging.LoggingEvents.logKeyDown(throttler)(element, event, '1'); await assertThrottled(recordKeyDown); assert.deepEqual(recordKeyDown.firstCall.firstArg, {veid, context: 1}); }); it('does not call UI binding to log a keydown with a non-matching code', async () => { const recordKeyDown = sinon.stub( Host.InspectorFrontendHost.InspectorFrontendHostInstance, 'recordKeyDown', ); const event = new KeyboardEvent('keydown', {code: 'KeyQ'}); VisualLogging.LoggingState.getLoggingState(element)!.config.track = {keydown: 'Enter|Escape'}; void VisualLogging.LoggingEvents.logKeyDown(throttler)(element, event); sinon.assert.notCalled(recordKeyDown); }); it('calls UI binding to log a hover event', async () => { const recordHover = sinon.stub( Host.InspectorFrontendHost.InspectorFrontendHostInstance, 'recordHover', ); const event = new MouseEvent('click', {button: 1}); sinon.stub(event, 'currentTarget').value(element); void VisualLogging.LoggingEvents.logHover(new Common.Throttler.Throttler(0))(event); await expectCalled(recordHover); assert.deepEqual(recordHover.firstCall.firstArg, {veid}); }); it('calls UI binding to log a drag event', async () => { const recordDrag = sinon.stub( Host.InspectorFrontendHost.InspectorFrontendHostInstance, 'recordDrag', ); const event = new MouseEvent('click', {button: 1}); sinon.stub(event, 'currentTarget').value(element); void VisualLogging.LoggingEvents.logDrag(throttler)(event); await assertThrottled(recordDrag); assert.deepEqual(recordDrag.firstCall.firstArg, {veid}); }); it('calls UI binding to log a resize event', async () => { const recordResize = sinon.stub( Host.InspectorFrontendHost.InspectorFrontendHostInstance, 'recordResize', ); VisualLogging.LoggingEvents.logResize(element, new DOMRect(0, 0, 100, 50)); assert.deepEqual(recordResize.firstCall.firstArg, {veid, width: 100, height: 50}); }); it('throttles calls UI binding to log a resize event', async () => { const recordResize = sinon.stub( Host.InspectorFrontendHost.InspectorFrontendHostInstance, 'recordResize', ); VisualLogging.LoggingEvents.logResize(element, new DOMRect(0, 0, 100, 50)); assert.deepEqual(recordResize.firstCall.firstArg, {veid, width: 100, height: 50}); }); it('calls UI binding to log a setting access event', async () => { const recordSettingAccess = sinon.stub( Host.InspectorFrontendHost.InspectorFrontendHostInstance, 'recordSettingAccess', ); await VisualLogging.LoggingEvents.logSettingAccess('test-setting', 'test-value'); assert.deepEqual( recordSettingAccess.lastCall.firstArg, {name: -1361026584, numeric_value: undefined, string_value: 856719891}); await VisualLogging.LoggingEvents.logSettingAccess('test-setting', 123); assert.deepEqual( recordSettingAccess.lastCall.firstArg, {name: -1361026584, numeric_value: 123, string_value: undefined}); }); it('calls UI binding to log a function call event', async () => { const recordFunctionCall = sinon.stub( Host.InspectorFrontendHost.InspectorFrontendHostInstance, 'recordFunctionCall', ); await VisualLogging.LoggingEvents.logFunctionCall('test-function', 'test-context'); assert.deepEqual(recordFunctionCall.lastCall.firstArg, {name: -1470917656, context: 617717214}); await VisualLogging.LoggingEvents.logFunctionCall('test-function'); assert.deepEqual(recordFunctionCall.lastCall.firstArg, {name: -1470917656, context: undefined}); }); });