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