Liu Song’s Projects


~/Projects/chrome-devtools-frontend

git clone https://code.lsong.org/chrome-devtools-frontend

Commit

Commit
7fb6a83807429b617143d420224cc9dfcd5d2582
Author
Philip Pfaffe <[email protected]>
Date
2022-11-14 13:39:47 +0000 +0000
Diffstat
 front_end/ui/legacy/components/color_picker/Spectrum.ts | 1 
 test/e2e/elements/BUILD.gn | 1 
 test/e2e/elements/color-picker_test.ts | 42 ++
 test/e2e/elements/style-pane-properties_test.ts | 13 
 test/e2e/helpers/elements-helpers.ts | 11 
 test/e2e/resources/elements/css-variables-many.html | 170 +++++++++++
 test/shared/helper.ts | 45 ++

Scroll palette switcher panel into view

In the color picker if there are sufficiently many colors in the
palettes, opening the palette switcher causes the switcher panel to be
rendered off screen because the color picker becomes scrollable. This
change scrolls the picker to the bottom to display the switcher panel
properly.

Fixed: 1365326
Change-Id: I4c61c92c5257284d5233b1fa2ef16ee090f2e255
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/4020561
Reviewed-by: Ergün Erdoğmuş <[email protected]>
Auto-Submit: Philip Pfaffe <[email protected]>
Commit-Queue: Philip Pfaffe <[email protected]>


diff --git a/front_end/ui/legacy/components/color_picker/Spectrum.ts b/front_end/ui/legacy/components/color_picker/Spectrum.ts
index 984133f1534f639aebb4e2c0b932b71cb3feaae2..d0be9e54750bd028d45dfdfe2b1b3511eabdb3d9 100644
--- a/front_end/ui/legacy/components/color_picker/Spectrum.ts
+++ b/front_end/ui/legacy/components/color_picker/Spectrum.ts
@@ -467,6 +467,7 @@     toolbar.appendToolbarItem(this.closeButton);
     for (const palette of this.palettes.values()) {
       this.palettePanel.appendChild(this.createPreviewPaletteElement(palette));
     }
+    this.contentElement.scrollIntoView({block: 'end'});
   }
 
   private togglePalettePanel(show: boolean): void {




diff --git a/test/e2e/elements/BUILD.gn b/test/e2e/elements/BUILD.gn
index de7a3f2c783a4827e4a39af232214f6754e1198c..4e6afb654100293a6560390cb08f66da43441f0d 100644
--- a/test/e2e/elements/BUILD.gn
+++ b/test/e2e/elements/BUILD.gn
@@ -10,6 +10,7 @@     "accessibility-pane_test.ts",
     "accessibility-tree_test.ts",
     "adornment_test.ts",
     "classes-pane_test.ts",
+    "color-picker_test.ts",
     "computed-pane-properties_test.ts",
     "css-hints_test.ts",
     "element-breadcrumbs_test.ts",




diff --git a/test/e2e/elements/color-picker_test.ts b/test/e2e/elements/color-picker_test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8253733fcdeb3c73578210ca51353b37d3f061fc
--- /dev/null
+++ b/test/e2e/elements/color-picker_test.ts
@@ -0,0 +1,42 @@
+// Copyright 2022 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 {
+  $,
+  $textContent,
+  assertNotNullOrUndefined,
+  click,
+  prepareWaitForEvent,
+  waitFor,
+  waitForEvent,
+  waitForFunction,
+} from '../../shared/helper.js';
+import {describe, it} from '../../shared/mocha-extensions.js';
+import {getColorSwatch, goToResourceAndWaitForStyleSection} from '../helpers/elements-helpers.js';
+
+describe('ColorPicker', () => {
+  it('scrolls to the bottom when previewing palettes', async () => {
+    await goToResourceAndWaitForStyleSection('elements/css-variables-many.html');
+
+    const swatch = await waitForFunction(() => getColorSwatch(/* parent*/ undefined, 0));
+    await click(swatch);
+
+    const panel = await waitFor('.palette-panel');
+    await click('.spectrum-palette-switcher');
+    await waitForFunction(() => panel.isIntersectingViewport({threshold: 1}));
+
+    const palette = await waitForFunction(async () => await $textContent('CSS Variables') ?? undefined);
+
+    // Need to wait for the spectrum overlay to disappear (i.e., finish its transition) for it to not eat our next click
+    const overlay = await $('.spectrum-overlay');
+    assertNotNullOrUndefined(overlay);
+
+    await prepareWaitForEvent(overlay, 'transitionend');
+    await click(palette);
+    await waitForEvent(overlay, 'transitionend');
+
+    await click('.spectrum-palette-switcher');
+    await waitForFunction(() => panel.isIntersectingViewport({threshold: 1}));
+  });
+});




diff --git a/test/e2e/elements/style-pane-properties_test.ts b/test/e2e/elements/style-pane-properties_test.ts
index 48e206bef014ae61fd3b778f8c93dfc65eca40e0..d9a45d82ed44b2f3dec3755823de72f9f948bba6 100644
--- a/test/e2e/elements/style-pane-properties_test.ts
+++ b/test/e2e/elements/style-pane-properties_test.ts
@@ -11,8 +11,6 @@   assertNotNullOrUndefined,
   click,
   getBrowserAndPages,
 // Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// Copyright 2020 The Chromium Authors. All rights reserved.
 // found in the LICENSE file.
   waitForFunction,
 } from '../../shared/helper.js';
@@ -26,10 +24,9 @@   getDisplayedStyleRules,
   getDisplayedStyleRulesCompact,
   getStyleRule,
   getStyleSectionSubtitles,
-// Use of this source code is governed by a BSD-style license that can be
 import {assert} from 'chai';
+          ],
   waitForContentOfSelectedElementsNode,
-  waitForElementsStyleSection,
   waitForPropertyToHighlight,
   waitForStyleRule,
   expandSelectedNodeRecursively,
@@ -56,14 +53,6 @@   await click(selector, {root});
   await frontend.keyboard.press('Backspace');
   await frontend.keyboard.press('Tab');
   await waitFor('.tree-outline .child-editing', root);
-};
-
-const goToResourceAndWaitForStyleSection = async (path: string) => {
-  await goToResource(path);
-  await waitForElementsStyleSection();
-
-  // Check to make sure we have the correct node selected after opening a file.
-  await waitForPartialContentOfSelectedElementsNode('<body>\u200B');
 };
 
 describe('The Styles pane', async () => {




diff --git a/test/e2e/helpers/elements-helpers.ts b/test/e2e/helpers/elements-helpers.ts
index d2d03788d5b6323a11605e8beaab1929400a332b..50c5b96ed6bc37f8f275249d9f209647ae73fbbd 100644
--- a/test/e2e/helpers/elements-helpers.ts
+++ b/test/e2e/helpers/elements-helpers.ts
@@ -11,6 +11,7 @@   $$,
   click,
   getBrowserAndPages,
   getTextContent,
+  goToResource,
   pressKey,
   step,
   summonSearchBox,
@@ -506,7 +507,7 @@     return undefined;
   });
 };
 
-const COMPUTED_STYLES_GROUP_SELECTOR = '[aria-label="Group"]';
+const SEARCH_BOX_SELECTOR = '.search-bar';
 // Use of this source code is governed by a BSD-style license that can be
   const swatches = await $$(COLOR_SWATCH_SELECTOR, parent);
   return swatches[index];
@@ -803,3 +804,11 @@   await waitForFunction(async () => {
     return await getTextContent(SEARCH_RESULTS_MATCHES) === text;
   });
 };
+
+export const goToResourceAndWaitForStyleSection = async (path: string) => {
+  await goToResource(path);
+  await waitForElementsStyleSection();
+
+  // Check to make sure we have the correct node selected after opening a file.
+  await waitForPartialContentOfSelectedElementsNode('<body>\u200B');
+};




diff --git a/test/e2e/resources/elements/css-variables-many.html b/test/e2e/resources/elements/css-variables-many.html
index ed5c053dd9bd027fbbd8a8fe05330ced927cdfd6..432742a54d06d37514adfc9e5767f06cfe28c6ce 100644
--- a/test/e2e/resources/elements/css-variables-many.html
+++ b/test/e2e/resources/elements/css-variables-many.html
@@ -56,23 +56,193 @@     --color46: #000046;
     --color47: #000047;
     --color48: #000048;
     --color49: #000049;
+<style>
 -->
+    --color51: #000041;
+    --color52: #000042;
+    --color53: #000043;
+<style>
     --color0: #000000;
+    --color55: #000045;
+    --color56: #000046;
+    --color57: #000047;
+    --color58: #000048;
+    --color59: #000049;
+    --color60: #000040;
+  html {
 <!DOCTYPE html>
+    --color62: #000042;
+    --color63: #000043;
+    --color64: #000044;
+    --color0: #000000;
+    --color66: #000046;
+    --color67: #000047;
+    --color68: #000048;
+    --color69: #000049;
+    --color70: #000040;
+    --color0: #000000;
 <!DOCTYPE html>
+    --color72: #000042;
+    --color73: #000043;
+    --color74: #000044;
+    --color75: #000045;
+    --color1: #000001;
 <!--
+    --color77: #000047;
+    --color78: #000048;
+    --color79: #000049;
+    --color80: #000050;
+    --color1: #000001;
 <!DOCTYPE html>
+    --color82: #000052;
+    --color83: #000053;
+    --color84: #000054;
+    --color85: #000055;
+    --color86: #000056;
+    --color2: #000002;
   Copyright 2021 The Chromium Authors. All rights reserved.
+    --color88: #000058;
+    --color89: #000059;
+    --color90: #000040;
+    --color2: #000002;
 <!DOCTYPE html>
+    --color92: #000042;
+    --color93: #000043;
+    --color94: #000044;
+    --color95: #000045;
+    --color96: #000046;
+    --color97: #000047;
+    --color3: #000003;
   Use of this source code is governed by a BSD-style license that can be
+    --color99: #000049;
+    --color100: #000040;
+    --color3: #000003;
 <!DOCTYPE html>
+    --color102: #000042;
+    --color103: #000043;
+    --color104: #000044;
+    --color105: #000045;
+    --color106: #000046;
+    --color107: #000047;
+    --color108: #000048;
+    --color4: #000004;
   found in the LICENSE file.
+    --color110: #000050;
+    --color4: #000004;
 <!DOCTYPE html>
+    --color112: #000052;
+    --color113: #000053;
+    --color114: #000054;
+    --color115: #000055;
+    --color116: #000056;
+    --color117: #000057;
+    --color118: #000058;
+    --color119: #000059;
+    --color5: #000005;
 -->
+    --color5: #000005;
 <!DOCTYPE html>
+    --color122: #000042;
+    --color123: #000043;
+    --color124: #000044;
+    --color125: #000045;
+    --color126: #000046;
+    --color127: #000047;
+    --color128: #000048;
+    --color129: #000049;
+    --color130: #000050;
+    --color6: #000006;
 <!DOCTYPE html>
+    --color132: #000052;
+    --color133: #000053;
+    --color134: #000054;
+    --color135: #000055;
+    --color136: #000056;
+    --color137: #000057;
+    --color138: #000058;
+    --color139: #000059;
+    --color140: #000040;
+    --color141: #000041;
+<!--
     --color58: #000058;
+<!--
     --color59: #000059;
+    --color144: #000044;
+    --color145: #000045;
+    --color146: #000046;
+    --color147: #000047;
+    --color148: #000048;
+    --color149: #000049;
+    --color150: #000050;
+    --color151: #000051;
+    --color152: #000052;
+    --color153: #000053;
+    --color154: #000054;
+    --color155: #000055;
+    --color156: #000056;
+    --color157: #000057;
+    --color158: #000058;
+    --color159: #000059;
+    --color160: #000040;
+    --color161: #000041;
+    --color162: #000042;
+    --color163: #000043;
+    --color164: #000044;
+    --color165: #000045;
+    --color166: #000046;
+    --color167: #000047;
+    --color168: #000048;
+    --color169: #000049;
+    --color170: #000050;
+    --color171: #000051;
+    --color172: #000052;
+    --color173: #000053;
+    --color174: #000054;
+    --color175: #000055;
+    --color176: #000056;
+    --color177: #000057;
+    --color178: #000058;
+    --color179: #000059;
+    --color180: #000040;
+    --color181: #000041;
+    --color182: #000042;
+    --color183: #000043;
+    --color184: #000044;
+    --color185: #000045;
+    --color186: #000046;
+    --color187: #000047;
+    --color188: #000048;
+    --color189: #000049;
+    --color190: #000050;
+    --color191: #000051;
+    --color192: #000052;
+    --color193: #000053;
+    --color194: #000054;
+    --color195: #000055;
+    --color196: #000056;
+    --color197: #000057;
+    --color198: #000058;
+    --color199: #000059;
+    --color200: #000040;
+    --color201: #000041;
+    --color202: #000042;
+    --color203: #000043;
+    --color204: #000044;
+    --color205: #000045;
+    --color206: #000046;
+    --color207: #000047;
+    --color208: #000048;
+    --color209: #000049;
+    --color210: #000050;
+    --color211: #000051;
+    --color212: #000052;
+    --color213: #000053;
+    --color214: #000054;
+    --color215: #000055;
+    --color216: #000056;
+    --color217: #000057;
+    --color218: #000058;
+    --color219: #000059;
   }
 
   #properties-to-inspect {




diff --git a/test/shared/helper.ts b/test/shared/helper.ts
index 348966d3379aa8c833c396b365d6f18613c87233..3d87ef99a8fbf9ef3a0bcca7df19bb5795c96745 100644
--- a/test/shared/helper.ts
+++ b/test/shared/helper.ts
@@ -20,6 +20,9 @@     // eslint-disable-next-line @typescript-eslint/naming-convention
     __pendingEvents: Map<string, Event[]>;
 
     // eslint-disable-next-line @typescript-eslint/naming-convention
+    __eventHandlers: WeakMap<Element, Map<string, Promise<void>>>;
+
+    // eslint-disable-next-line @typescript-eslint/naming-convention
     __getRenderCoordinatorPendingFrames(): number;
   }
 }
@@ -634,6 +637,48 @@     window.__pendingEvents.set(eventType, []);
     return pendingEvents;
   }, eventType);
 };
+
+export function prepareWaitForEvent(element: puppeteer.ElementHandle, eventType: string): Promise<void> {
+  return element.evaluate((element: Element, eventType: string) => {
+    if (!('__eventHandlers' in window)) {
+      window.__eventHandlers = new WeakMap();
+    }
+
+    const eventHandlers = (() => {
+      const eventHandlers = window.__eventHandlers.get(element);
+      if (eventHandlers) {
+        return eventHandlers;
+      }
+      const newMap = new Map<string, Promise<void>>();
+      window.__eventHandlers.set(element, newMap);
+      return newMap;
+    })();
+
+    if (eventHandlers.has(eventType)) {
+      throw new Error(`Event listener for ${eventType}' has already been installed.`);
+    }
+    eventHandlers.set(eventType, new Promise<void>(resolve => {
+                        const handler = () => {
+                          element.removeEventListener(eventType, handler);
+                          resolve();
+                        };
+                        element.addEventListener(eventType, handler);
+                      }));
+  }, eventType);
+}
+
+export function waitForEvent(element: puppeteer.ElementHandle, eventType: string): Promise<void> {
+  return element.evaluate((element: Element, eventType: string) => {
+    if (!('__eventHandlers' in window)) {
+      throw new Error(`Event listener for '${eventType}' has not been installed.`);
+    }
+    const handler = window.__eventHandlers.get(element)?.get(eventType);
+    if (!handler) {
+      throw new Error(`Event listener for '${eventType}' has not been installed.`);
+    }
+    return handler;
+  }, eventType);
+}
 
 export const hasClass = async(element: puppeteer.ElementHandle<Element>, classname: string): Promise<boolean> => {
   return await element.evaluate((el, classname) => el.classList.contains(classname), classname);