Skip to content

Commit 34a05a4

Browse files
Merge pull request #18 from BrowserStackCE/merge-app-automate-latency-finder
Merge app automate latency finder
2 parents 4f48679 + 982fcef commit 34a05a4

File tree

8 files changed

+733
-4
lines changed

8 files changed

+733
-4
lines changed

src/channelHandlers/browserstack-api.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { parseAutomateSeleniumLogs } from "../utils/latency-finder/selenium-logs
55
import { convertUTCToEpoch } from "../utils/latency-finder/helper"
66
import fs from 'fs'
77
import path from "path";
8+
import { parseAppAutomateAppiumLogs } from "../utils/latency-finder/appium-logs-parser"
89

910
const BASE_URL = 'https://api.browserstack.com'
1011

@@ -231,6 +232,26 @@ export const getAutomateParsedSeleniumLogs = async (session: AutomateSessionResp
231232
return result;
232233
};
233234

235+
export const getAppAutomateParsedAppiumLogs = async (session: AutomateSessionResponse) => {
236+
const appiumLogsUrl = session.automation_session.appium_logs_url
237+
const logs = await download(appiumLogsUrl);
238+
239+
// Convert created_at to epoch (UTC)
240+
const sessionCreatedAtUTC = convertUTCToEpoch(
241+
session.automation_session.created_at
242+
);
243+
// Extract just the date part from created_at
244+
const date = session.automation_session.created_at.split("T")[0]; // date = "2025-11-13"
245+
246+
const result = parseAppAutomateAppiumLogs(
247+
logs,
248+
date,
249+
sessionCreatedAtUTC
250+
);
251+
252+
return result;
253+
};
254+
234255
export const getSeleniumLogs = async (selenium_logs_url: string) => {
235256
if (!selenium_logs_url) {
236257
return 'No Selenium logs available for this session';

src/constants/ipc-channels.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ const CHANNELS = {
1919
ELECTRON_OPEN_APP_PICKER: 'ELECTRON_OPEN_APP_PICKER',
2020
GET_BROWSERSTACK_APP_AUTOMATE_CAPABILITIES: 'GET_BROWSERSTACK_APP_AUTOMATE_CAPABILITIES',
2121
GET_BROWSERSTACK_APP_AUTOMATE_NETWORK_LOGS: 'GET_BROWSERSTACK_APP_AUTOMATE_NETWORK_LOGS',
22-
GET_BROWSERSTACK_SCANNER_AUTOMATE_SESSION_IDS: 'GET_BROWSERSTACK_SCANNER_AUTOMATE_SESSION_IDS'
22+
GET_BROWSERSTACK_SCANNER_AUTOMATE_SESSION_IDS: 'GET_BROWSERSTACK_SCANNER_AUTOMATE_SESSION_IDS',
23+
GET_BROWSERSTACK_APP_AUTOMATE_PARSED_APPPIUM_LOGS: 'GET_BROWSERSTACK_APP_AUTOMATE_PARSED_APPPIUM_LOGS'
2324
}
2425

2526
export default CHANNELS

src/global.d.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ declare global {
2525
getAppAutomateNetworkLogs: (session: AppAutomateSessionResponse) => Promise<string>
2626
getAppAutomateSessionCapabilities: (session: AppAutomateSessionResponse) => Promise<{ capabilities: any[] }>
2727
getScannerSessionIds: (thBuildId: string) => Promise<any>
28+
getAppAutomateParsedAppiumLogs: (session: AppAutomateSessionResponse) => Promise<AppiumScanResult>
2829
}
2930

3031
type ElectronAPI = {
@@ -279,4 +280,61 @@ declare global {
279280
custom_id: string,
280281
shareable_id: string
281282
}
283+
interface AppiumRequest {
284+
created_at: number;
285+
line_number: number;
286+
http_type: string;
287+
action: string;
288+
params: any;
289+
out_time: number;
290+
}
291+
292+
interface AppiumResponse {
293+
created_at: number;
294+
line_number: number;
295+
status: string | null;
296+
timing: string;
297+
size: string;
298+
params: any;
299+
in_time: number;
300+
}
301+
302+
interface AppiumExchange {
303+
id: number;
304+
request: AppiumRequest;
305+
response?: AppiumResponse;
306+
}
307+
308+
interface AppiumSummary {
309+
total_requests: number;
310+
dialect: string;
311+
session_started_at: number | null;
312+
session_completed_at: number | null;
313+
driver_started_at: number | null;
314+
driver_init_time: number | null;
315+
session_duration: number | null;
316+
setup_time: number | null;
317+
execution_time: number;
318+
in_time: number;
319+
out_time: number;
320+
passed_requests: number;
321+
failed_requests: number;
322+
unknown_requests: number;
323+
log_length: number;
324+
setup_time_perc: number | null;
325+
in_time_perc: number | null;
326+
out_time_perc: number | null;
327+
average_cycle_time: number | null;
328+
average_serve_time: number | null;
329+
average_wait_time: number | null;
330+
passed_perc: number | null;
331+
failed_perc: number | null;
332+
unknown_perc: number | null;
333+
}
334+
335+
interface AppiumScanResult {
336+
summary: AppiumSummary;
337+
exchanges: AppiumExchange[];
338+
}
339+
282340
}

src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { getBrowserStackCredentials, setBrowserStackCredentials } from './channe
66
import CONFIG from './constants/config';
77

88
import { mkdirSync } from 'fs'
9-
import { executeCommand, getAutomateSessionDetails, getParsedAutomateTextLogs, startBrowserStackSession, stopBrowserStackSession, getAutomateParsedSeleniumLogs, getAutomateParsedSessionLogs, getSeleniumLogs, getHarLogs, getAppAutomateSessionDetails, getAppAutomateParsedTextLogs, getAllUploadedApps, uploadApp, getAppAutomateNetworkLogs, getAppAutomateSessionCapabilities, getScannerSessionIds } from './channelHandlers/browserstack-api';
9+
import { executeCommand, getAutomateSessionDetails, getParsedAutomateTextLogs, startBrowserStackSession, stopBrowserStackSession, getAutomateParsedSeleniumLogs, getAutomateParsedSessionLogs, getSeleniumLogs, getHarLogs, getAppAutomateSessionDetails, getAppAutomateParsedTextLogs, getAllUploadedApps, uploadApp, getAppAutomateNetworkLogs, getAppAutomateSessionCapabilities, getScannerSessionIds, getAppAutomateParsedAppiumLogs } from './channelHandlers/browserstack-api';
1010
import { openExternalUrl, openAppPicker } from './channelHandlers/electron-api';
1111

1212

@@ -105,6 +105,7 @@ app.whenReady().then(() => {
105105
ipcMain.handle(CHANNELS.GET_BROWSERSTACK_APP_AUTOMATE_NETWORK_LOGS, (_, session) => getAppAutomateNetworkLogs(session))
106106
ipcMain.handle(CHANNELS.GET_BROWSERSTACK_APP_AUTOMATE_CAPABILITIES, (_, session) => getAppAutomateSessionCapabilities(session))
107107
ipcMain.handle(CHANNELS.GET_BROWSERSTACK_SCANNER_AUTOMATE_SESSION_IDS, (_, thBuildId) => getScannerSessionIds(thBuildId));
108+
ipcMain.handle(CHANNELS.GET_BROWSERSTACK_APP_AUTOMATE_PARSED_APPPIUM_LOGS, (_, session) => getAppAutomateParsedAppiumLogs(session));
108109
});
109110
// In this file you can include the rest of your app's specific main process
110111
// code. You can also put them in separate files and import them here.

src/preload.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ const browserstackAPI: BrowserStackAPI = {
2323
uploadApp: (filePath: string) => ipcRenderer.invoke(CHANNELS.UPLOAD_APP, filePath),
2424
getAppAutomateNetworkLogs: (session) => ipcRenderer.invoke(CHANNELS.GET_BROWSERSTACK_APP_AUTOMATE_NETWORK_LOGS, session),
2525
getAppAutomateSessionCapabilities: (session) => ipcRenderer.invoke(CHANNELS.GET_BROWSERSTACK_APP_AUTOMATE_CAPABILITIES, session),
26-
getScannerSessionIds: (thBuildId: string) => ipcRenderer.invoke(CHANNELS.GET_BROWSERSTACK_SCANNER_AUTOMATE_SESSION_IDS, thBuildId)
26+
getScannerSessionIds: (thBuildId: string) => ipcRenderer.invoke(CHANNELS.GET_BROWSERSTACK_SCANNER_AUTOMATE_SESSION_IDS, thBuildId),
27+
getAppAutomateParsedAppiumLogs: (session: any) => ipcRenderer.invoke(CHANNELS.GET_BROWSERSTACK_APP_AUTOMATE_PARSED_APPPIUM_LOGS, session)
2728
}
2829

2930
const electronAPI: ElectronAPI = {

src/renderer/products.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import WebReplayTool from "./routes/automate/tools/replay-tool";
55
import AppAutomateSessionComparison from "./routes/app-automate/tools/session-comparison";
66
import SDKLogsDownloader from "./routes/test-reporting-and-analytics/tools/sdk-logs-downloader";
77
import SessionFinder from "./routes/website-scanner/tools/session-finder";
8+
import AppLatencyFinder from "./routes/app-automate/tools/latency-finder";
89

910
const Products: {
1011
name: string
@@ -54,7 +55,7 @@ const Products: {
5455
description:
5556
"Analyses time spend on different actions. Helpful to identify inside/outside time for a customer session.",
5657
path: "/app-automate/latency-analyser",
57-
component: null,
58+
component: AppLatencyFinder,
5859
},
5960
{
6061
title: "Session Comparison",

0 commit comments

Comments
 (0)