blob: e404fa982d6542c6e1f38e8d43b451010ba52688 [file] [log] [blame]
Patrick Brossetdd3309c2020-05-18 13:35:251// Copyright 2020 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Randolf Jungbcb3bc82023-06-26 16:30:145import type * as puppeteer from 'puppeteer-core';
Patrick Brossetdd3309c2020-05-18 13:35:256
Guangyue Xuc3d32b22024-04-03 04:22:497import {getBrowserAndPages} from '../../conductor/puppeteer-state.js';
8import {
9 $,
10 click,
11 goToResource,
12 platform,
13 waitFor,
14 waitForAria,
15 waitForElementWithTextContent,
16 waitForFunction,
17 waitForMany,
18} from '../../shared/helper.js';
Almothana Athamneh8d4391d2020-10-20 11:58:0619
Danil Somsikov241e3c02024-07-01 13:57:1520import {veImpression} from './visual-logging-helpers.js';
21
Kim-Anh Trane71698b2024-04-17 07:43:5222export const FILTER_TEXTBOX_SELECTOR = '[aria-label="Filter"]';
Almothana Athamneh8d4391d2020-10-20 11:58:0623export const RECORD_BUTTON_SELECTOR = '[aria-label="Record"]';
Adam Raineb4c1b9e2024-06-27 19:45:1224export const RELOAD_AND_RECORD_BUTTON_SELECTOR = '[aria-label="Record and reload"]';
Almothana Athamneh8d4391d2020-10-20 11:58:0625export const STOP_BUTTON_SELECTOR = '[aria-label="Stop"]';
26export const SUMMARY_TAB_SELECTOR = '[aria-label="Summary"]';
27export const BOTTOM_UP_SELECTOR = '[aria-label="Bottom-Up"]';
28export const CALL_TREE_SELECTOR = '[aria-label="Call Tree"]';
29export const ACTIVITY_COLUMN_SELECTOR = '.activity-column.disclosure';
30export const TOTAL_TIME_SELECTOR =
31 'div:nth-child(1) > div.vbox.timeline-details-chip-body > div:nth-child(1) > div.timeline-details-view-row-value';
Guangyue Xuc3d32b22024-04-03 04:22:4932const RECALCULATE_STYLE_TITLE = 'Recalculate Style';
33const SELECTOR_STATS_SELECTOR = '[aria-label="Selector Stats"]';
Paul Irishf33df5d2024-05-08 13:47:3534const CSS_SELECTOR_STATS_TITLE = 'Enable CSS selector stats (slow)';
Guangyue Xuc3d32b22024-04-03 04:22:4935const TIMELINE_SETTINGS_PANE = '.timeline-settings-pane';
Patrick Brossetdd3309c2020-05-18 13:35:2536
Patrick Brosset60bf7bf2020-06-08 17:04:2937export async function navigateToPerformanceTab(testName?: string) {
38 if (testName) {
Patrick Brosset0805f4a2020-06-11 09:34:3239 await goToResource(`performance/${testName}.html`);
Patrick Brosset60bf7bf2020-06-08 17:04:2940 }
Patrick Brossetdd3309c2020-05-18 13:35:2541
42 // Click on the tab.
43 await click('#tab-timeline');
44
45 // Make sure the landing page is shown.
46 await waitFor('.timeline-landing-page');
47}
48
Philip Pfaffeb26de252022-05-23 11:53:3049export async function openCaptureSettings(sectionClassName: string) {
50 const captureSettingsButton = await waitForAria('Capture settings');
51 await captureSettingsButton.click();
52 return await waitFor(sectionClassName);
53}
54
Almothana Athamneh8d4391d2020-10-20 11:58:0655export async function searchForComponent(frontend: puppeteer.Page, searchEntry: string) {
Kim-Anh Trane7b90202022-07-06 09:29:4256 const modifierKey = platform === 'mac' ? 'Meta' : 'Control';
57 await frontend.keyboard.down(modifierKey);
Almothana Athamneh8d4391d2020-10-20 11:58:0658 await frontend.keyboard.press('KeyF');
Kim-Anh Trane7b90202022-07-06 09:29:4259 await frontend.keyboard.up(modifierKey);
Almothana Athamneh8d4391d2020-10-20 11:58:0660 await frontend.keyboard.type(searchEntry);
Almothana Athamneh8d4391d2020-10-20 11:58:0661}
62
63export async function navigateToSummaryTab() {
64 await click(SUMMARY_TAB_SELECTOR);
65}
66
67export async function navigateToBottomUpTab() {
68 await click(BOTTOM_UP_SELECTOR);
69}
70
71export async function navigateToCallTreeTab() {
72 await click(CALL_TREE_SELECTOR);
73}
74
Vidal Diazleal0cd74d42023-11-17 20:59:0075export async function setFilter(filter: string) {
76 const filterBoxElement = await click(FILTER_TEXTBOX_SELECTOR);
77 await filterBoxElement.type(filter);
78}
79
80export async function toggleCaseSensitive() {
81 const matchCaseButton = await waitForAria('Match Case');
82 await matchCaseButton.click();
83}
84
85export async function toggleRegExButtonBottomUp() {
86 const regexButton = await waitForAria('Use Regular Expression');
87 await regexButton.click();
88}
89
90export async function toggleMatchWholeWordButtonBottomUp() {
91 const wholeWordButton = await waitForAria('Match whole word');
92 await wholeWordButton.click();
93}
94
Patrick Brossetdd3309c2020-05-18 13:35:2595export async function startRecording() {
96 await click(RECORD_BUTTON_SELECTOR);
97
Patrick Brosset60bf7bf2020-06-08 17:04:2998 // Wait for the button to turn to its stop state.
99 await waitFor(STOP_BUTTON_SELECTOR);
Patrick Brossetdd3309c2020-05-18 13:35:25100}
101
Jack Franklin60caeab2023-07-14 09:05:52102export async function reloadAndRecord() {
103 await click(RELOAD_AND_RECORD_BUTTON_SELECTOR);
104 // Make sure the timeline details panel appears. It's a sure way to assert
105 // that a recording is actually displayed as some of the other elements in
106 // the timeline remain in the DOM even after the recording has been cleared.
107 await waitFor('.timeline-details-chip-body');
108}
109
Patrick Brossetdd3309c2020-05-18 13:35:25110export async function stopRecording() {
111 await click(STOP_BUTTON_SELECTOR);
112
113 // Make sure the timeline details panel appears. It's a sure way to assert
114 // that a recording is actually displayed as some of the other elements in
115 // the timeline remain in the DOM even after the recording has been cleared.
116 await waitFor('.timeline-details-chip-body');
117}
118
119export async function getTotalTimeFromSummary(): Promise<number> {
Johan Bay504a6f12020-08-04 13:32:53120 const pieChartTotal = await waitFor('.pie-chart-total');
Johan Baye8245712020-08-04 13:32:10121 const totalText = await pieChartTotal.evaluate(node => node.textContent as string);
Patrick Brossetdd3309c2020-05-18 13:35:25122 return parseInt(totalText, 10);
123}
Patrick Brosset60bf7bf2020-06-08 17:04:29124
Guangyue Xuc3d32b22024-04-03 04:22:49125export async function getRenderingTimeFromSummary(): Promise<[number, string]> {
126 const pieChartSizes = await waitForMany('.pie-chart-size', 6);
127 const pieChartNames = await waitForMany('.pie-chart-name', 6);
128
129 // update the index if the rendering time is showing in a different row
130 const chartName = await pieChartNames[2].evaluate(node => node.textContent as string);
131 const chartSize = await pieChartSizes[2].evaluate(node => node.textContent as string);
132
133 return [parseInt(chartSize, 10), chartName];
134}
135
Almothana Athamneh8d4391d2020-10-20 11:58:06136export async function retrieveSelectedAndExpandedActivityItems(frontend: puppeteer.Page) {
Sigurd Schneider123977a2021-02-15 14:17:46137 const treeItems = await frontend.$$('.expanded > td.activity-column,.selected > td.activity-column');
Almothana Athamneh8d4391d2020-10-20 11:58:06138 const tree = [];
Sigurd Schneider123977a2021-02-15 14:17:46139 for (const item of treeItems) {
Almothana Athamneh8d4391d2020-10-20 11:58:06140 tree.push(await frontend.evaluate(el => el.innerText.split('\n')[0], item));
141 }
142
143 return tree;
144}
145
Patrick Brosset60bf7bf2020-06-08 17:04:29146export async function navigateToPerformanceSidebarTab(tabName: string) {
147 await click(`[aria-label="${tabName}"]`);
148}
149
Almothana Athamneh8d4391d2020-10-20 11:58:06150export async function clickOnFunctionLink() {
Alex Rudenkoe92fe9d2023-01-30 13:12:23151 await click('.timeline-details.devtools-link');
Almothana Athamneh8d4391d2020-10-20 11:58:06152}
Guangyue Xuc3d32b22024-04-03 04:22:49153
154export async function navigateToSelectorStatsTab() {
155 await click(SELECTOR_STATS_SELECTOR);
156}
157
158export async function selectRecalculateStylesEvent() {
159 const {frontend} = getBrowserAndPages();
160
161 await waitForFunction(async () => {
162 await searchForComponent(frontend, RECALCULATE_STYLE_TITLE);
163 const title = await $('.timeline-details-chip-title');
164 if (!title) {
165 return false;
166 }
167 const titleText = await title.evaluate(x => x.textContent);
168 return titleText === RECALCULATE_STYLE_TITLE;
169 });
170}
171
172export async function enableCSSSelectorStats() {
173 const timelineSettingsPane = await waitFor(TIMELINE_SETTINGS_PANE);
174 if (await timelineSettingsPane.isHidden()) {
175 await openCaptureSettings(TIMELINE_SETTINGS_PANE);
176 }
177
178 // Wait for the checkbox to load
179 const toggle =
180 await waitForElementWithTextContent(CSS_SELECTOR_STATS_TITLE) as puppeteer.ElementHandle<HTMLInputElement>;
181 await waitForFunction(() => toggle.evaluate((e: HTMLInputElement) => {
182 if (e.disabled) {
183 return false;
184 }
185 if (!e.checked) {
186 e.click();
187 }
188 return true;
189 }));
190}
191
192export async function disableCSSSelectorStats() {
193 const timelineSettingsPane = await waitFor(TIMELINE_SETTINGS_PANE);
194 if (await timelineSettingsPane.isHidden()) {
195 await openCaptureSettings(TIMELINE_SETTINGS_PANE);
196 }
197
198 // Wait for the checkbox to load
199 const toggle =
200 await waitForElementWithTextContent(CSS_SELECTOR_STATS_TITLE) as puppeteer.ElementHandle<HTMLInputElement>;
201 await waitForFunction(() => toggle.evaluate((e: HTMLInputElement) => {
202 if (e.disabled) {
203 return false;
204 }
205 if (e.checked) {
206 e.click();
207 }
208 return true;
209 }));
210}
Danil Somsikov241e3c02024-07-01 13:57:15211
212export function veImpressionForPerformancePanel() {
213 return veImpression('Panel', 'timeline', [
214 veImpression(
215 'Toolbar', undefined,
216 [
217 veImpression('Toggle', 'timeline.toggle-recording'),
218 veImpression('Action', 'timeline.record-reload'),
219 veImpression('Action', 'timeline.load-from-file'),
220 veImpression('Action', 'timeline.save-to-file'),
221 veImpression('Action', 'components.collect-garbage'),
222 veImpression('Toggle', 'timeline-show-screenshots'),
223 veImpression('Toggle', 'timeline-show-memory'),
224 ]),
225 // veImpression('Pane', 'timeline-settings-pane', {optional: true}),
226 veImpression('Link', 'learn-more'),
227 veImpression('Toggle', 'timeline.toggle-recording'),
228 veImpression('Action', 'timeline.record-reload'),
229 ]);
230}