aboutsummaryrefslogtreecommitdiff
path: root/ui/src/test/ui_integrationtest.ts
diff options
context:
space:
mode:
Diffstat (limited to 'ui/src/test/ui_integrationtest.ts')
-rw-r--r--ui/src/test/ui_integrationtest.ts278
1 files changed, 278 insertions, 0 deletions
diff --git a/ui/src/test/ui_integrationtest.ts b/ui/src/test/ui_integrationtest.ts
new file mode 100644
index 000000000..f6a442fc5
--- /dev/null
+++ b/ui/src/test/ui_integrationtest.ts
@@ -0,0 +1,278 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import * as fs from 'fs';
+import * as path from 'path';
+import * as puppeteer from 'puppeteer';
+
+import {assertExists} from '../base/logging';
+
+import {
+ compareScreenshots,
+ failIfTraceProcessorHttpdIsActive,
+ getTestTracePath,
+ waitForPerfettoIdle
+} from './perfetto_ui_test_helper';
+
+declare var global: {__BROWSER__: puppeteer.Browser;};
+const browser = assertExists(global.__BROWSER__);
+const expectedScreenshotPath = path.join('test', 'data', 'ui-screenshots');
+
+async function getPage(): Promise<puppeteer.Page> {
+ const pages = (await browser.pages());
+ expect(pages.length).toBe(1);
+ return pages[pages.length - 1];
+}
+
+// Executed once at the beginning of the test. Navigates to the UI.
+beforeAll(async () => {
+ await failIfTraceProcessorHttpdIsActive();
+ jest.setTimeout(60000);
+ const page = await getPage();
+ await page.setViewport({width: 1920, height: 1080});
+});
+
+// After each test (regardless of nesting) capture a screenshot named after the
+// test('') name and compare the screenshot with the expected one in
+// /test/data/ui-screenshots.
+afterEach(async () => {
+ let testName = expect.getState().currentTestName;
+ testName = testName.replace(/[^a-z0-9-]/gmi, '_').toLowerCase();
+ const page = await getPage();
+
+ // cwd() is set to //out/ui when running tests, just create a subdir in there.
+ // The CI picks up this directory and uploads to GCS after every failed run.
+ const tmpDir = path.resolve('./ui-test-artifacts');
+ if (!fs.existsSync(tmpDir)) fs.mkdirSync(tmpDir);
+ const screenshotName = `ui-${testName}.png`;
+ const actualFilename = path.join(tmpDir, screenshotName);
+ const expectedFilename = path.join(expectedScreenshotPath, screenshotName);
+ await page.screenshot({path: actualFilename});
+ const rebaseline = process.env['PERFETTO_UI_TESTS_REBASELINE'] === '1';
+ if (rebaseline) {
+ console.log('Saving reference screenshot into', expectedFilename);
+ fs.copyFileSync(actualFilename, expectedFilename);
+ } else {
+ await compareScreenshots(actualFilename, expectedFilename);
+ }
+});
+
+describe('android_trace_30s', () => {
+ let page: puppeteer.Page;
+
+ beforeAll(async () => {
+ page = await getPage();
+ await page.goto('http://localhost:10000/?testing=1');
+ await waitForPerfettoIdle(page);
+ });
+
+ test('load', async () => {
+ const file = await page.waitForSelector('input.trace_file');
+ const tracePath = getTestTracePath('example_android_trace_30s.pb');
+ assertExists(file).uploadFile(tracePath);
+ await waitForPerfettoIdle(page);
+ });
+
+ test('expand_camera', async () => {
+ await page.click('.main-canvas');
+ await page.click('h1[title="com.google.android.GoogleCamera 5506"]');
+ await page.evaluate(() => {
+ document.querySelector('.scrolling-panel-container')!.scrollTo(0, 400);
+ });
+ await waitForPerfettoIdle(page);
+ });
+
+ // TODO(198431341): Test is flaky. We should de-flake and re-enable.
+ // test('search', async () => {
+ // const page = await getPage();
+ // const searchInput = '.omnibox input';
+ // await page.focus(searchInput);
+ // await page.keyboard.type('TrimMaps');
+ // await waitForPerfettoIdle(page);
+ // for (let i = 0; i < 10; i++) {
+ // await page.keyboard.type('\n');
+ // }
+ // await waitForPerfettoIdle(page);
+ //});
+});
+
+describe('chrome_rendering_desktop', () => {
+ let page: puppeteer.Page;
+
+ beforeAll(async () => {
+ page = await getPage();
+ await page.goto('http://localhost:10000/?testing=1');
+ await waitForPerfettoIdle(page);
+ });
+
+ test('load', async () => {
+ const page = await getPage();
+ const file = await page.waitForSelector('input.trace_file');
+ const tracePath = getTestTracePath('chrome_rendering_desktop.pftrace');
+ assertExists(file).uploadFile(tracePath);
+ await waitForPerfettoIdle(page);
+ });
+
+ test('expand_browser_proc', async () => {
+ const page = await getPage();
+ await page.click('.main-canvas');
+ await page.click('h1[title="Browser 12685"]');
+ await waitForPerfettoIdle(page);
+ });
+
+ test('select_slice_with_flows', async () => {
+ const page = await getPage();
+ const searchInput = '.omnibox input';
+ await page.focus(searchInput);
+ await page.keyboard.type('GenerateRenderPass');
+ await waitForPerfettoIdle(page);
+ for (let i = 0; i < 3; i++) {
+ await page.keyboard.type('\n');
+ }
+ await waitForPerfettoIdle(page);
+ await page.focus('canvas');
+ await page.keyboard.type('f'); // Zoom to selection
+ await waitForPerfettoIdle(page);
+ });
+});
+
+describe('routing', () => {
+ describe('open_two_traces_then_go_back', () => {
+ let page: puppeteer.Page;
+
+ beforeAll(async () => {
+ page = await getPage();
+ await page.goto('http://localhost:10000/?testing=1');
+ await waitForPerfettoIdle(page);
+ });
+
+ test('open_first_trace_from_url', async () => {
+ await page.goto(
+ 'http://localhost:10000/?testing=1/#!/?url=http://localhost:10000/test/data/chrome_memory_snapshot.pftrace');
+ await waitForPerfettoIdle(page);
+ });
+
+ test('open_second_trace_from_url', async () => {
+ await page.goto(
+ 'http://localhost:10000/?testing=1#!/?url=http://localhost:10000/test/data/chrome_scroll_without_vsync.pftrace');
+ await waitForPerfettoIdle(page);
+ });
+
+ test('access_subpage_then_go_back', async () => {
+ await waitForPerfettoIdle(page);
+ await page.goto(
+ 'http://localhost:10000/?testing=1/#!/metrics?local_cache_key=76c25a80-25dd-1eb7-2246-d7b3c7a10f91');
+ await page.goBack();
+ await waitForPerfettoIdle(page);
+ });
+ });
+
+ describe('start_from_no_trace', () => {
+ let page: puppeteer.Page;
+
+ beforeAll(async () => {
+ page = await getPage();
+ await page.goto('about:blank');
+ });
+
+ test('go_to_page_with_no_trace', async () => {
+ await page.goto('http://localhost:10000/?testing=1#!/info');
+ await waitForPerfettoIdle(page);
+ });
+
+ test('open_trace ', async () => {
+ await page.goto(
+ 'http://localhost:10000/?testing=1#!/viewer?local_cache_key=76c25a80-25dd-1eb7-2246-d7b3c7a10f91');
+ await waitForPerfettoIdle(page);
+ });
+
+ test('refresh', async () => {
+ await page.reload();
+ await waitForPerfettoIdle(page);
+ });
+
+ test('open_second_trace', async () => {
+ await page.goto(
+ 'http://localhost:10000/?testing=1#!/viewer?local_cache_key=00000000-0000-0000-e13c-bd7db4ff646f');
+ await waitForPerfettoIdle(page);
+
+ // click on the 'Continue' button in the interstitial
+ await page.click('[id="trace_id_open"]');
+ await waitForPerfettoIdle(page);
+ });
+
+ test('go_back_to_first_trace', async () => {
+ await page.goBack();
+ await waitForPerfettoIdle(page);
+ // click on the 'Continue' button in the interstitial
+ await page.click('[id="trace_id_open"]');
+ await waitForPerfettoIdle(page);
+ });
+
+ test('open_invalid_trace', async () => {
+ await page.goto(
+ 'http://localhost:10000/?testing=1#!/viewer?local_cache_key=invalid');
+ await waitForPerfettoIdle(page);
+ });
+ });
+
+ describe('navigate', () => {
+ let page: puppeteer.Page;
+
+ beforeAll(async () => {
+ page = await getPage();
+ await page.goto('http://localhost:10000/?testing=1');
+ await waitForPerfettoIdle(page);
+ });
+
+ test('open_trace_from_url', async () => {
+ await page.goto(
+ 'http://localhost:10000/?testing=1/#!/?url=http://localhost:10000/test/data/chrome_memory_snapshot.pftrace');
+ await waitForPerfettoIdle(page);
+ });
+
+ test('navigate_back_and_forward', async () => {
+ await page.click('[id="info_and_stats"]');
+ await waitForPerfettoIdle(page);
+ await page.click('[id="metrics"]');
+ await waitForPerfettoIdle(page);
+ await page.goBack();
+ await waitForPerfettoIdle(page);
+ await page.goBack();
+ await waitForPerfettoIdle(page);
+ await page.goForward();
+ await waitForPerfettoIdle(page);
+ await page.goForward();
+ await waitForPerfettoIdle(page);
+ });
+ });
+
+ test('open_trace_and_go_back_to_landing_page', async () => {
+ const page = await getPage();
+ await page.goto('http://localhost:10000/?testing=1');
+ await page.goto(
+ 'http://localhost:10000/?testing=1#!/viewer?local_cache_key=76c25a80-25dd-1eb7-2246-d7b3c7a10f91');
+ await waitForPerfettoIdle(page);
+ await page.goBack();
+ await waitForPerfettoIdle(page);
+ });
+
+ test('open_invalid_trace_from_blank_page', async () => {
+ const page = await getPage();
+ await page.goto('about:blank');
+ await page.goto(
+ 'http://localhost:10000/?testing=1#!/viewer?local_cache_key=invalid');
+ await waitForPerfettoIdle(page);
+ });
+});