• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17import {browser, by, element, ElementFinder} from 'protractor';
18import {E2eTestUtils} from './utils';
19
20describe('Cross-Tool Protocol', () => {
21  const TIMESTAMP_IN_BUGREPORT_MESSAGE = '1670509911000000000';
22  const TIMESTAMP_FROM_REMOTE_TOOL_TO_WINSCOPE = '1670509912000000000';
23  const TIMESTAMP_FROM_WINSCOPE_TO_REMOTE_TOOL = '1670509913000000000';
24
25  beforeAll(async () => {
26    jasmine.DEFAULT_TIMEOUT_INTERVAL = 15000;
27    await browser.manage().timeouts().implicitlyWait(15000);
28    await E2eTestUtils.checkServerIsUp('Remote tool mock', E2eTestUtils.REMOTE_TOOL_MOCK_URL);
29    await E2eTestUtils.checkServerIsUp('Winscope', E2eTestUtils.WINSCOPE_URL);
30  });
31
32  beforeEach(async () => {
33    await browser.get(E2eTestUtils.REMOTE_TOOL_MOCK_URL);
34  });
35
36  it('allows communication between remote tool and Winscope', async () => {
37    await openWinscopeTabFromRemoteTool();
38    await waitWinscopeTabIsOpen();
39
40    await sendBugreportToWinscope();
41    await checkWinscopeRendersUploadView();
42    await closeWinscopeSnackBarIfNeeded();
43
44    await clickWinscopeViewTracesButton();
45    await checkWinscopeRenderedSurfaceFlingerView();
46    await checkWinscopeRenderedAllViewTabs();
47    await checkWinscopeAppliedTimestampInBugreportMessage();
48
49    await sendTimestampToWinscope();
50    await checkWinscopeReceivedTimestamp();
51
52    await changeTimestampInWinscope();
53    await checkRemoteToolReceivedTimestamp();
54  });
55
56  const openWinscopeTabFromRemoteTool = async () => {
57    await browser.switchTo().window(await getWindowHandleRemoteToolMock());
58    const buttonElement = element(by.css('.button-open-winscope'));
59    await buttonElement.click();
60  };
61
62  const sendBugreportToWinscope = async () => {
63    await browser.switchTo().window(await getWindowHandleRemoteToolMock());
64    const inputFileElement = element(by.css('.button-upload-bugreport'));
65    await inputFileElement.sendKeys(
66      E2eTestUtils.getFixturePath('bugreports/bugreport_stripped.zip')
67    );
68  };
69
70  const checkWinscopeRendersUploadView = async () => {
71    await browser.switchTo().window(await getWindowHandleWinscope());
72    const isPresent = await element(by.css('.uploaded-files')).isPresent();
73    expect(isPresent).toBeTruthy();
74  };
75
76  const clickWinscopeViewTracesButton = async () => {
77    await browser.switchTo().window(await getWindowHandleWinscope());
78    await E2eTestUtils.clickViewTracesButton();
79  };
80
81  const closeWinscopeSnackBarIfNeeded = async () => {
82    await browser.switchTo().window(await getWindowHandleWinscope());
83    await E2eTestUtils.closeSnackBarIfNeeded();
84  };
85
86  const waitWinscopeTabIsOpen = async () => {
87    await browser.wait(
88      async () => {
89        const handles = await browser.getAllWindowHandles();
90        return handles.length >= 2;
91      },
92      20000,
93      'The Winscope tab did not open'
94    );
95  };
96
97  const checkWinscopeRenderedSurfaceFlingerView = async () => {
98    await browser.switchTo().window(await getWindowHandleWinscope());
99    const viewerPresent = await element(by.css('viewer-surface-flinger')).isPresent();
100    expect(viewerPresent).toBeTruthy();
101  };
102
103  const checkWinscopeRenderedAllViewTabs = async () => {
104    const tabParagraphs = await element.all(by.css('.tabs-navigation-bar a p'));
105
106    const actualTabParagraphs = await Promise.all(
107      (tabParagraphs as ElementFinder[]).map(async (paragraph) => await paragraph.getText())
108    );
109
110    const expectedTabParagraphs = [
111      'Input Method Clients',
112      'Input Method Manager Service',
113      'Input Method Service',
114      'ProtoLog',
115      'Surface Flinger',
116      'Transactions',
117      'Transitions',
118      'Window Manager',
119    ];
120
121    expect(actualTabParagraphs.sort()).toEqual(expectedTabParagraphs.sort());
122  };
123
124  const checkWinscopeAppliedTimestampInBugreportMessage = async () => {
125    await browser.switchTo().window(await getWindowHandleWinscope());
126    const inputElement = element(by.css('input[name="nsTimeInput"]'));
127    const valueWithNsSuffix = await inputElement.getAttribute('value');
128    expect(valueWithNsSuffix).toEqual(TIMESTAMP_IN_BUGREPORT_MESSAGE + ' ns');
129  };
130
131  const sendTimestampToWinscope = async () => {
132    await browser.switchTo().window(await getWindowHandleRemoteToolMock());
133    const inputElement = element(by.css('.input-timestamp'));
134    await inputElement.sendKeys(TIMESTAMP_FROM_REMOTE_TOOL_TO_WINSCOPE);
135    const buttonElement = element(by.css('.button-send-timestamp'));
136    await buttonElement.click();
137  };
138
139  const checkWinscopeReceivedTimestamp = async () => {
140    await browser.switchTo().window(await getWindowHandleWinscope());
141    const inputElement = element(by.css('input[name="nsTimeInput"]'));
142    const valueWithNsSuffix = await inputElement.getAttribute('value');
143    expect(valueWithNsSuffix).toEqual(TIMESTAMP_FROM_REMOTE_TOOL_TO_WINSCOPE + ' ns');
144  };
145
146  const changeTimestampInWinscope = async () => {
147    await browser.switchTo().window(await getWindowHandleWinscope());
148    const inputElement = element(by.css('input[name="nsTimeInput"]'));
149    const inputStringStep1 = TIMESTAMP_FROM_WINSCOPE_TO_REMOTE_TOOL.slice(0, -1);
150    const inputStringStep2 = TIMESTAMP_FROM_WINSCOPE_TO_REMOTE_TOOL.slice(-1) + '\r\n';
151    const script = `document.querySelector("input[name=\\"nsTimeInput\\"]").value = "${inputStringStep1}"`;
152    await browser.executeScript(script);
153    await inputElement.sendKeys(inputStringStep2);
154  };
155
156  const checkRemoteToolReceivedTimestamp = async () => {
157    await browser.switchTo().window(await getWindowHandleRemoteToolMock());
158    const paragraphElement = element(by.css('.paragraph-received-timestamp'));
159    const value = await paragraphElement.getText();
160    expect(value).toEqual(TIMESTAMP_FROM_WINSCOPE_TO_REMOTE_TOOL);
161  };
162
163  const getWindowHandleRemoteToolMock = async (): Promise<string> => {
164    const handles = await browser.getAllWindowHandles();
165    expect(handles.length).toBeGreaterThan(0);
166    return handles[0];
167  };
168
169  const getWindowHandleWinscope = async (): Promise<string> => {
170    const handles = await browser.getAllWindowHandles();
171    expect(handles.length).toEqual(2);
172    return handles[1];
173  };
174});
175