blob: c7947390a4614ef138a8e6a98b261b2c00df658b [file] [log] [blame]
// Copyright 2020 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 type * as puppeteer from 'puppeteer';
import {$, $$, click, getBrowserAndPages, goToResource, waitFor, waitForFunction} from '../../shared/helper.js';
export async function navigateToApplicationTab(target: puppeteer.Page, testName: string) {
await goToResource(`application/${testName}.html`);
await click('#tab-resources');
// Make sure the application navigation list is shown
await waitFor('.storage-group-list-item');
}
export async function navigateToServiceWorkers() {
const SERVICE_WORKER_ROW_SELECTOR = '[aria-label="Service Workers"]';
await click(SERVICE_WORKER_ROW_SELECTOR);
}
export async function navigateToManifestInApplicationTab(testName: string) {
const MANIFEST_SELECTOR = '[aria-label="Manifest"]';
const {target} = getBrowserAndPages();
await navigateToApplicationTab(target, testName);
await click(MANIFEST_SELECTOR);
}
export async function doubleClickSourceTreeItem(selector: string) {
const element = await waitFor(selector);
element.evaluate(el => el.scrollIntoView(true));
await click(selector, {clickOptions: {clickCount: 2}});
}
export async function getDataGridData(selector: string, columns: string[]) {
// Wait for Storage data-grid to show up
await waitFor(selector);
const dataGridNodes = await $$('.data-grid-data-grid-node:not(.creation-node)');
const dataGridRowValues = await Promise.all(dataGridNodes.map(node => node.evaluate((row: Element, columns) => {
const data: {[key: string]: string|null} = {};
for (const column of columns) {
const columnElement = row.querySelector(`.${column}-column`);
data[column] = columnElement ? columnElement.textContent : '';
}
return data;
}, columns)));
return dataGridRowValues;
}
export async function getTrimmedTextContent(selector: string) {
const elements = await $$(selector);
return Promise.all(elements.map(element => element.evaluate(e => {
return (e.textContent || '').trim().replace(/[ \n]{2,}/gm, ''); // remove multiple consecutive whitespaces
})));
}
export async function getFrameTreeTitles() {
const treeTitles = await $$('[aria-label="Resources Section"] ~ ol .tree-element-title');
return Promise.all(treeTitles.map(node => node.evaluate(e => e.textContent)));
}
export async function getStorageItemsData(columns: string[]) {
return getDataGridData('.storage-view table', columns);
}
export async function filterStorageItems(filter: string) {
const element = await $('.toolbar-input-prompt') as puppeteer.ElementHandle;
await element.type(filter);
}
export async function clearStorageItemsFilter() {
await click('.toolbar-input .toolbar-input-clear-button');
}
export async function clearStorageItems() {
await waitFor('#storage-items-delete-all');
await click('#storage-items-delete-all');
}
export async function selectStorageItemAtIndex(index: number) {
await waitForFunction(async () => {
try {
const dataGridNodes = await $$('.storage-view .data-grid-data-grid-node:not(.creation-node)');
await dataGridNodes[index].click();
} catch (error) {
if (error.message === 'Node is detached from document') {
return false;
}
throw error;
}
return true;
});
}
export async function deleteSelectedStorageItem() {
await waitFor('[aria-label="Delete Selected"]');
await click('[aria-label="Delete Selected"]');
}
export async function selectCookieByName(name: string) {
const {frontend} = getBrowserAndPages();
await waitFor('.cookies-table');
const cell = await waitForFunction(async () => {
const tmp = await frontend.evaluateHandle(name => {
const result = [...document.querySelectorAll('.cookies-table .name-column')]
.map(c => ({cell: c, textContent: c.textContent || ''}))
.find(({textContent}) => textContent.trim() === name);
return result ? result.cell : undefined;
}, name);
return tmp.asElement() as puppeteer.ElementHandle<HTMLElement>|| undefined;
});
await cell.click();
}
export async function waitForQuotaUsage(p: (quota: number) => boolean) {
await waitForFunction(async () => {
const usedQuota = await getQuotaUsage();
return p(usedQuota);
});
}
export async function getQuotaUsage() {
const storageRow = await waitFor('.quota-usage-row');
const quotaString = await storageRow.evaluate(el => el.textContent || '');
const [usedQuotaText, modifier] =
quotaString.replace(/^\D*([\d.]+)\D*(kM?)B.used.out.of\D*\d+\D*.?B.*$/, '$1 $2').split(' ');
let usedQuota = Number.parseInt(usedQuotaText, 10);
if (modifier === 'k') {
usedQuota *= 1000;
} else if (modifier === 'M') {
usedQuota *= 1000000;
}
return usedQuota;
}
export async function getPieChartLegendRows() {
const pieChartLegend = await waitFor('.pie-chart-legend');
const rows = await pieChartLegend.evaluate(legend => {
const rows = [];
for (const tableRow of legend.children) {
const row = [];
for (const cell of tableRow.children) {
row.push(cell.textContent);
}
rows.push(row);
}
return rows;
});
return rows;
}