-
Notifications
You must be signed in to change notification settings - Fork 29
refactor: update device handling in Automate tools #178
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
10ace7e
ff9a638
da2cb9f
ada7046
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -9,7 +9,10 @@ import { maybeCompressBase64 } from "../lib/utils.js"; | |||||||||||||
| import { remote } from "webdriverio"; | ||||||||||||||
| import { AppTestPlatform } from "./appautomate-utils/native-execution/types.js"; | ||||||||||||||
| import { setupAppAutomateHandler } from "./appautomate-utils/appium-sdk/handler.js"; | ||||||||||||||
| import { validateAppAutomateDevices } from "./sdk-utils/common/device-validator.js"; | ||||||||||||||
| import { | ||||||||||||||
| validateAppAutomateDevices, | ||||||||||||||
| convertMobileDevicesToTuples, | ||||||||||||||
| } from "./sdk-utils/common/device-validator.js"; | ||||||||||||||
|
|
||||||||||||||
| import { | ||||||||||||||
| SETUP_APP_AUTOMATE_DESCRIPTION, | ||||||||||||||
|
|
@@ -378,7 +381,15 @@ export default function addAppAutomationTools( | |||||||||||||
| undefined, | ||||||||||||||
| config, | ||||||||||||||
| ); | ||||||||||||||
| return await runAppTestsOnBrowserStack(args, config); | ||||||||||||||
| // Convert device objects to tuples for the handler | ||||||||||||||
| const devices: Array<Array<string>> = | ||||||||||||||
| (args.devices || []).length === 0 | ||||||||||||||
| ? [["android", "Samsung Galaxy S24", "latest"]] | ||||||||||||||
| : convertMobileDevicesToTuples(args.devices || []); | ||||||||||||||
|
||||||||||||||
| (args.devices || []).length === 0 | |
| ? [["android", "Samsung Galaxy S24", "latest"]] | |
| : convertMobileDevicesToTuples(args.devices || []); | |
| args.devices.length === 0 | |
| ? [["android", "Samsung Galaxy S24", "latest"]] | |
| : convertMobileDevicesToTuples(args.devices); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,13 +22,44 @@ export async function runBstackSDKOnly( | |
| const authString = getBrowserStackAuth(config); | ||
| const [username, accessKey] = authString.split(":"); | ||
|
|
||
| // Validate devices against real BrowserStack device data | ||
| const tupleTargets = (input as any).devices as | ||
| | Array<Array<string>> | ||
| | undefined; | ||
| // Convert device objects to tuples for validator | ||
| const devices = input.devices || []; | ||
| const tupleTargets: Array<Array<string>> = devices.map((device) => { | ||
| if (device.platform === "windows") { | ||
| return [ | ||
| "windows", | ||
| device.osVersion, | ||
| device.browser, | ||
| device.browserVersion || "latest", | ||
| ]; | ||
| } else if (device.platform === "mac" || device.platform === "macos") { | ||
| return [ | ||
| "macos", | ||
| device.osVersion, | ||
| device.browser, | ||
| device.browserVersion || "latest", | ||
| ]; | ||
| } else if (device.platform === "android") { | ||
| return [ | ||
| "android", | ||
| device.deviceName, | ||
| device.osVersion, | ||
| device.browser || "chrome", | ||
| ]; | ||
| } else if (device.platform === "ios") { | ||
| return [ | ||
| "ios", | ||
| device.deviceName, | ||
| device.osVersion, | ||
| device.browser || "safari", | ||
| ]; | ||
| } else { | ||
| throw new Error(`Unsupported platform: ${device.platform}`); | ||
| } | ||
| }); | ||
|
Comment on lines
27
to
60
|
||
|
|
||
| const validatedEnvironments = await validateDevices( | ||
| tupleTargets || [], | ||
| tupleTargets, | ||
| input.detectedBrowserAutomationFramework, | ||
| ); | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -230,10 +230,19 @@ export async function validateDevices( | |||
| } | ||||
|
|
||||
| // Determine what data we need to fetch | ||||
| const needsDesktop = devices.some((env) => | ||||
| // Normalize "mac" to "macos" for consistency | ||||
| const normalizedDevices = devices.map((env) => { | ||||
| const platform = (env[0] || "").toLowerCase(); | ||||
| if (platform === "mac") { | ||||
| return ["macos", ...env.slice(1)]; | ||||
| } | ||||
| return env; | ||||
| }); | ||||
|
||||
|
|
||||
|
||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -48,67 +48,64 @@ export const SetUpPercyParamsShape = { | |||||
| ), | ||||||
| }; | ||||||
|
|
||||||
| // Shared mobile device schema for App Automate (no browser field) | ||||||
| export const MobileDeviceSchema = z.discriminatedUnion("platform", [ | ||||||
| z.object({ | ||||||
| platform: z.literal("android"), | ||||||
| deviceName: z.string().describe("Device name, e.g. 'Samsung Galaxy S24', 'Google Pixel 8'"), | ||||||
| osVersion: z.string().describe("Android version, e.g. '14', '16', 'latest'"), | ||||||
| }), | ||||||
| z.object({ | ||||||
| platform: z.literal("ios"), | ||||||
| deviceName: z.string().describe("Device name, e.g. 'iPhone 15', 'iPhone 14 Pro'"), | ||||||
| osVersion: z.string().describe("iOS version, e.g. '17', '16', 'latest'"), | ||||||
| }), | ||||||
| ]); | ||||||
|
|
||||||
| const DeviceSchema = z.discriminatedUnion("platform", [ | ||||||
| z.object({ | ||||||
| platform: z.literal("windows"), | ||||||
| osVersion: z.string().describe("Windows version, e.g. '10', '11'"), | ||||||
| browser: z.string().describe("Browser name, e.g. 'chrome', 'firefox', 'edge'"), | ||||||
| browserVersion: z.string().describe("Browser version, e.g. '132', 'latest', 'oldest'"), | ||||||
|
||||||
| }), | ||||||
| z.object({ | ||||||
| platform: z.literal("android"), | ||||||
| deviceName: z.string().describe("Device name, e.g. 'Samsung Galaxy S24'"), | ||||||
|
||||||
| deviceName: z.string().describe("Device name, e.g. 'Samsung Galaxy S24'"), | |
| deviceName: z.string().describe("Device name, e.g. 'Samsung Galaxy S24', 'Google Pixel 8'"), |
Outdated
Copilot
AI
Nov 9, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The browser field is required in the Android schema, but the conversion logic in sdkHandler.ts (line 47) treats it as optional with a default value (device.browser || "chrome"). This inconsistency could cause runtime errors when devices without a browser field are validated. Consider making browser optional in the schema using .optional() to match the conversion behavior.
| browser: z.string().describe("Browser name, e.g. 'chrome', 'samsung browser'"), | |
| browser: z.string().describe("Browser name, e.g. 'chrome', 'samsung browser'").optional(), |
Outdated
Copilot
AI
Nov 9, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The iOS device name example in DeviceSchema uses 'iPhone 12 Pro', while the MobileDeviceSchema uses 'iPhone 15', 'iPhone 14 Pro' (line 60). For consistency and to reflect more current devices, consider updating this to match the examples in MobileDeviceSchema.
| deviceName: z.string().describe("Device name, e.g. 'iPhone 12 Pro'"), | |
| deviceName: z.string().describe("Device name, e.g. 'iPhone 15', 'iPhone 14 Pro'"), |
Outdated
Copilot
AI
Nov 9, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The browser field is required in the iOS schema, but the conversion logic in sdkHandler.ts (line 54) treats it as optional with a default value (device.browser || "safari"). This inconsistency could cause runtime errors when devices without a browser field are validated. Consider making browser optional in the schema using .optional() to match the conversion behavior.
| browser: z.string().describe("Browser name, typically 'safari'"), | |
| browser: z.string().describe("Browser name, typically 'safari'").optional(), |
Outdated
Copilot
AI
Nov 9, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The browserVersion field is required in the macOS schema but is treated as optional in the conversion logic (line 40 in sdkHandler.ts uses device.browserVersion || "latest"). This inconsistency could cause runtime errors when devices are validated against the schema. Consider making browserVersion optional in the schema using .optional() to match the conversion behavior.
| browserVersion: z.string().describe("Browser version, e.g. 'latest'"), | |
| browserVersion: z.string().describe("Browser version, e.g. 'latest'").optional(), |
Outdated
Copilot
AI
Nov 9, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extra blank line detected. Remove one of the consecutive empty lines for consistent code formatting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default device
[['android', 'Samsung Galaxy S24', 'latest']]is duplicated in bothappautomate.ts(line 387) andappium-sdk/handler.ts(line 54). Consider defining this as a constant (e.g.,DEFAULT_MOBILE_DEVICE) in a shared location to ensure consistency and ease maintenance.