| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import * as Protocol from '../../generated/protocol.js'; |
| import { |
| createTarget, |
| } from '../../testing/EnvironmentHelpers.js'; |
| import { |
| describeWithMockConnection, |
| setMockConnectionResponseHandler, |
| } from '../../testing/MockConnection.js'; |
| import * as Platform from '../platform/platform.js'; |
| |
| import * as SDK from './sdk.js'; |
| |
| const {urlString} = Platform.DevToolsPath; |
| |
| describeWithMockConnection('OverlayModel', () => { |
| const DOCUMENT_URL_FOR_TEST = urlString`https://example.com/`; |
| |
| let cssModel: SDK.CSSModel.CSSModel|null; |
| let windowControls: SDK.OverlayModel.WindowControls|null; |
| let overlayModel: SDK.OverlayModel.OverlayModel|null; |
| |
| const header: Protocol.CSS.CSSStyleSheetHeader = { |
| styleSheetId: 'stylesheet' as Protocol.DOM.StyleSheetId, |
| frameId: 'frame' as Protocol.Page.FrameId, |
| sourceURL: `${DOCUMENT_URL_FOR_TEST}styles.css`, |
| origin: Protocol.CSS.StyleSheetOrigin.Regular, |
| title: 'title', |
| disabled: false, |
| isInline: false, |
| isMutable: false, |
| isConstructed: false, |
| loadingFailed: false, |
| startLine: 0, |
| startColumn: 0, |
| length: 0, |
| endLine: 0, |
| endColumn: 0, |
| }; |
| |
| const defaultStyleSheet = `.titlebar { |
| left: env(titlebar-area-x); |
| top: env(titlebar-area-y); |
| width: env(titlebar-area-width); |
| height: env(titlebar-area-height);}`; |
| |
| beforeEach(() => { |
| const target = createTarget({url: DOCUMENT_URL_FOR_TEST}); |
| overlayModel = target.model(SDK.OverlayModel.OverlayModel); |
| cssModel = target.model(SDK.CSSModel.CSSModel); |
| assert.exists(cssModel); |
| windowControls = new SDK.OverlayModel.WindowControls(cssModel); |
| |
| // Set up mock response handler to get the default style sheet |
| setMockConnectionResponseHandler('CSS.getStyleSheetText', () => { |
| return {text: defaultStyleSheet}; |
| }); |
| }); |
| |
| it('toggles controls toolbar', async () => { |
| assert.exists(overlayModel); |
| let config; |
| |
| // Set up mock response handler to set the configuration |
| setMockConnectionResponseHandler('Overlay.setShowWindowControlsOverlay', request => { |
| config = request; |
| return request as Protocol.Overlay.SetShowWindowControlsOverlayRequest; |
| }); |
| |
| // Verify the config is empty when toggling toolbar to be false |
| await overlayModel.toggleWindowControlsToolbar(false); |
| assert.deepEqual(config, {}, 'Expect config to be empty when toolbar is toggled false'); |
| |
| // Verify the current config is sent when toggling toolbar to be true |
| await overlayModel.toggleWindowControlsToolbar(true); |
| const expectedDefaultConfig = {windowControlsOverlayConfig: overlayModel.getWindowControlsConfig()}; |
| assert.deepEqual(config, expectedDefaultConfig, 'Expect default config sent when toolbar is toggled true'); |
| }); |
| |
| it('initializes the style sheet text', async () => { |
| assert.exists(cssModel); |
| assert.exists(windowControls); |
| |
| // Verify the style sheet is not initialized when no styles are present |
| const checkStyleSheet = await windowControls.initializeStyleSheetText(DOCUMENT_URL_FOR_TEST); |
| assert.isFalse(checkStyleSheet, 'Style should not be initialized if no CSS stylesheets are present'); |
| |
| // Add a style sheet and verify it gets added |
| cssModel.styleSheetAdded(header); |
| const styleSheetIds = cssModel.getStyleSheetIdsForURL(urlString`${`${DOCUMENT_URL_FOR_TEST}styles.css`}`); |
| assert.deepEqual(styleSheetIds, ['stylesheet']); |
| |
| // Verify style sheet gets initialized |
| const isInitialized = await windowControls.initializeStyleSheetText(DOCUMENT_URL_FOR_TEST); |
| assert.isTrue(isInitialized, 'Expect the style sheet to be initialized when CSS stylesheets are present'); |
| }); |
| |
| it('toggles the emulated overlay', async () => { |
| assert.exists(cssModel); |
| assert.exists(windowControls); |
| let styleSheet; |
| |
| // Set up mock response handler to set the style sheet |
| setMockConnectionResponseHandler('CSS.setStyleSheetText', req => { |
| styleSheet = req.text; |
| return req as unknown as Protocol.CSS.SetStyleSheetTextResponse; |
| }); |
| |
| // Toggle emulated overlay and verify no emulated overlay when no styles are preset |
| await windowControls.toggleEmulatedOverlay(true); |
| assert.isUndefined(styleSheet, 'Expect overlay to not be toggled if no styles are present'); |
| |
| // Add style sheet and verify it gets added |
| cssModel.styleSheetAdded(header); |
| const styleSheetIds = cssModel.getStyleSheetIdsForURL(urlString`${`${DOCUMENT_URL_FOR_TEST}styles.css`}`); |
| assert.deepEqual(styleSheetIds, ['stylesheet']); |
| |
| // Initialize style sheet & verify it gets initialized |
| const isInitialized = await windowControls.initializeStyleSheetText(DOCUMENT_URL_FOR_TEST); |
| assert.isTrue(isInitialized); |
| |
| // Toggle the emulated overlay and verify original style sheet gets replaced with emulated overlay |
| await windowControls.toggleEmulatedOverlay(true); |
| const expectedWindowsOverlay = `.titlebar { |
| left: env(titlebar-area-x, 0px); |
| top: env(titlebar-area-y, 0px); |
| width: env(titlebar-area-width, calc(100% - 238px)); |
| height: env(titlebar-area-height, 33px);}`; |
| |
| assert.strictEqual(styleSheet, expectedWindowsOverlay, 'Expect emulated overlay stylesheet to be used'); |
| |
| // Toggle the emulated overlay off and verify original style sheet is used |
| await windowControls.toggleEmulatedOverlay(false); |
| assert.strictEqual(styleSheet, defaultStyleSheet, 'Expect original default stylesheet to be used'); |
| }); |
| |
| it('parses styles and replaces variables for style sheet correctly', () => { |
| assert.exists(windowControls); |
| |
| const x = 85; |
| const y = 0; |
| const width = 185; |
| const height = 40; |
| |
| let originalStyleSheet = `.titlebar { |
| position: absolute; |
| left: env(titlebar-area-x); |
| top: env(titlebar-area-y); |
| width: env(titlebar-area-width); |
| height: env(titlebar-area-height); |
| }`; |
| |
| let expectedStyleSheet = `.titlebar { |
| position: absolute; |
| left: env(titlebar-area-x, ${x}px); |
| top: env(titlebar-area-y, ${y}px); |
| width: env(titlebar-area-width, calc(100% - ${width}px)); |
| height: env(titlebar-area-height, ${height}px); |
| }`; |
| |
| // Verify the original style sheet gets transformed to the expected style sheet for the given x, y, width, and height dimensions |
| let parsedStyleSheet = windowControls.transformStyleSheetforTesting(x, y, width, height, originalStyleSheet); |
| assert.strictEqual(parsedStyleSheet, expectedStyleSheet); |
| |
| // Verify the original style sheet does not get transformed when no original stylesheet |
| originalStyleSheet = ''; |
| parsedStyleSheet = windowControls.transformStyleSheetforTesting(x, y, width, height, originalStyleSheet); |
| assert.isUndefined(parsedStyleSheet); |
| |
| // Verify the original style sheet gets transformed to the expected style sheet for partial CSS properties |
| originalStyleSheet = ': env(titlebar-area-xxx, 9px); width: env(titlebar-area-width);'; |
| expectedStyleSheet = `: env(titlebar-area-xxx, 9px); width: env(titlebar-area-width, calc(100% - ${width}px));`; |
| parsedStyleSheet = windowControls.transformStyleSheetforTesting(x, y, width, height, originalStyleSheet); |
| assert.strictEqual(parsedStyleSheet, expectedStyleSheet); |
| }); |
| }); |