Feature/appium support unlock by pin#4228
Conversation
WalkthroughThis update adds support for unlocking mobile devices using various unlock types (PIN, password, pattern, or none). It introduces new UI elements for selecting the unlock type, updates the core logic to handle each unlock method, and modifies method signatures to pass unlock information throughout the relevant components. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant UI (ActMobileDeviceEditPage)
participant ActMobileDevice
participant Driver (GenericAppiumDriver)
User->>UI (ActMobileDeviceEditPage): Selects "Unlock Device" action
UI (ActMobileDeviceEditPage)->>UI (ActMobileDeviceEditPage): Shows unlock type combo box
User->>UI (ActMobileDeviceEditPage): Chooses unlock type (PIN, password, pattern, none)
UI (ActMobileDeviceEditPage)->>ActMobileDevice: Sets unlock type and input value
UI (ActMobileDeviceEditPage)->>Driver (GenericAppiumDriver): Calls PerformLockButtonPress with ActMobileDevice
Driver (GenericAppiumDriver)->>Driver (GenericAppiumDriver): Unlocks device based on selected type
Suggested reviewers
Poem
✨ Finishing Touches
🧪 Generate Unit Tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 12
🔭 Outside diff range comments (1)
Ginger/GingerCoreNET/Drivers/CoreDrivers/Mobile/Appium/GenericAppiumDriver.cs (1)
1960-1967: 🛠️ Refactor suggestion
PerformLockButtonPresssignature change – add null-guard
actis optional (= null) but is eagerly dereferenced in the unlock path.
A simple null-guard (or making the parameter mandatory) avoids a futureNullReferenceExceptionif someone calls the method directly:public void PerformLockButtonPress(eLockOperation LockOperation, ActMobileDevice act = null) { + if (LockOperation == eLockOperation.UnLock && act == null) + throw new ArgumentNullException(nameof(act), + "The ActMobileDevice instance is required when performing an Unlock operation");
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (5)
Ginger/Ginger/Actions/ActionEditPages/ActMobileDeviceEditPage.xaml(1 hunks)Ginger/Ginger/Actions/ActionEditPages/ActMobileDeviceEditPage.xaml.cs(11 hunks)Ginger/GingerCoreNET/ActionsLib/UI/Mobile/ActMobileDevice.cs(2 hunks)Ginger/GingerCoreNET/Drivers/CoreDrivers/Mobile/Appium/GenericAppiumDriver.cs(5 hunks)Ginger/GingerCoreNET/Drivers/DriversWindow/IMobileDriverWindow.cs(2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
Ginger/GingerCoreNET/ActionsLib/UI/Mobile/ActMobileDevice.cs (1)
Ginger/GingerCoreCommon/Actions/Act.cs (1)
AddOrUpdateInputParamValue(825-848)
Ginger/GingerCoreNET/Drivers/DriversWindow/IMobileDriverWindow.cs (2)
Ginger/GingerCoreNET/Drivers/CoreDrivers/Mobile/Appium/GenericAppiumDriver.cs (2)
PerformLockButtonPress(1960-2083)ActMobileDevice(1858-1868)Ginger/GingerCoreNET/ActionsLib/UI/Mobile/ActMobileDevice.cs (1)
ActMobileDevice(30-692)
Ginger/Ginger/Actions/ActionEditPages/ActMobileDeviceEditPage.xaml.cs (1)
Ginger/GingerCoreNET/ActionsLib/UI/Mobile/ActMobileDevice.cs (1)
ActMobileDevice(30-692)
🔇 Additional comments (2)
Ginger/GingerCoreNET/Drivers/CoreDrivers/Mobile/Appium/GenericAppiumDriver.cs (2)
2048-2066: Log message exposes unlock method but not value – goodGood practice: you log the fact an unlock is happening without logging the secret itself. 👍
1198-1205:Details
❌ Incorrect review comment
Updated call-sites look good but lose compile-time safety
PerformLockButtonPressnow expects the currentActMobileDeviceinstance, and the two call-sites were updated accordingly.
No functional concerns here, just bear in mind that any external usages (tests, helpers, plugins) will now fail to compile.
A quickrg "PerformLockButtonPress("shows several additional call-sites in the repo – ensure they are updated as well.
🏁 Script executed:
#!/bin/bash # Detect other call-sites still using the old signature rg --line-number "PerformLockButtonPress(" --type csLength of output: 151
🏁 Script executed:
#!/bin/bash # Corrected search for all PerformLockButtonPress call-sites using fixed-string match rg --line-number -F "PerformLockButtonPress(" --type csLength of output: 1001
No further call-site changes needed—optional
ActMobileDevicepreserves backward compatibility
- The interface (
Ginger/GingerCoreNET/Drivers/DriversWindow/IMobileDriverWindow.cs:47) and implementation (Ginger/GingerCoreNET/Drivers/CoreDrivers/Mobile/Appium/GenericAppiumDriver.cs:1960) declare
void PerformLockButtonPress(eLockOperation lockOperation, ActMobileDevice act = null).- Updated calls in
GenericAppiumDriver.cs(lines 1199 & 1203) now pass theactparameter.- Existing calls in
MobileDriverWindow.xaml.cs(lines 1039 & 1044) omitactbut compile against the defaultact = null.No compile-time break will occur—there’s no need to update additional call-sites.
Likely an incorrect or invalid review comment.
There was a problem hiding this comment.
Actionable comments posted: 4
🔭 Outside diff range comments (2)
Ginger/Ginger/Drivers/DriversWindows/MobileDriverWindow.xaml.cs (1)
1034-1047:⚠️ Potential issue
PerformLockButtonPressis passednullfor Unlock – likely defeats the new “unlock by PIN / pattern / …” feature
IMobileDriverWindow.PerformLockButtonPress(eLockOperation.UnLock, act)now expects anActMobileDeviceinstance that encapsulates the chosen unlock type and credentials.
Calling it withnull:mDriver.PerformLockButtonPress(eLockOperation.UnLock, null);means:
- Any unlock method that requires credentials (PIN/password/pattern) will not work.
- If the concrete driver dereferences
actwithout a null-guard you’ll hit a run-time exception.Either supply a populated
ActMobileDevicewhenUnLockis requested or fall back to a dedicated overload for simple “wake” behaviour.- mDriver.PerformLockButtonPress(eLockOperation.UnLock,null); + // Example – unlock using the “None” type (adjust to UI selection): + var unlockAct = new ActMobileDevice + { + UnLockTypes = ActMobileDevice.eUnLockType.None + }; + mDriver.PerformLockButtonPress(eLockOperation.UnLock, unlockAct);Ginger/GingerCoreNET/Drivers/CoreDrivers/Mobile/Appium/GenericAppiumDriver.cs (1)
1961-1976:⚠️ Potential issueNull-reference risk when
actis not supplied
PerformLockButtonPressacceptsActMobileDevice act = null, yet the very first access (act.UnLockType) is unconditional.
IMobileDriverWindowcallers still invoke this method with null when context isn’t available, which will now throw.Add a short-circuit guard:
public void PerformLockButtonPress(eLockOperation LockOperation, ActMobileDevice act = null) { + // If no action context was supplied, fall back to a plain lock/unlock + if (act == null) + { + if (LockOperation == eLockOperation.Lock) + Driver.Lock(); + else + Driver.Unlock(); + return; + }
♻️ Duplicate comments (3)
Ginger/GingerCoreNET/Drivers/DriversWindow/IMobileDriverWindow.cs (1)
20-20: Broad namespace import was re-introduced – duplicates earlier feedback
Same concern as in the previous review: importing the wholeGingerCore.Actionsnamespace to reference a single DTO (ActMobileDevice) unnecessarily couples this low-level interface to action logic.Ginger/GingerCoreNET/ActionsLib/UI/Mobile/ActMobileDevice.cs (1)
105-117: Property name still breaks .NET casing conventionsThe public property is now singular (good) but the mixed-case “UnLockType” deviates from the project’s PascalCase rules (
UnlockType).
Keeping the unconventional casing propagates to XAML bindings and driver code and will keep tripping static-analysis rules.- public eUnlockType UnLockType + public eUnlockType UnlockType(remember to rename usages in XAML, code-behind and driver logic).
Ginger/Ginger/Actions/ActionEditPages/ActMobileDeviceEditPage.xaml.cs (1)
193-197: 🧹 Nitpick (assertive)Empty handler – same concern as before
UnlockTypeComboBox_SelectionChangedstill just callsSetControlsView()and adds no logic.
Either drop the handler (PropertyChanged already triggers view refresh) or add the intended validation/cleanup code.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (5)
Ginger/Ginger/Actions/ActionEditPages/ActMobileDeviceEditPage.xaml.cs(11 hunks)Ginger/Ginger/Drivers/DriversWindows/MobileDriverWindow.xaml.cs(2 hunks)Ginger/GingerCoreNET/ActionsLib/UI/Mobile/ActMobileDevice.cs(2 hunks)Ginger/GingerCoreNET/Drivers/CoreDrivers/Mobile/Appium/GenericAppiumDriver.cs(6 hunks)Ginger/GingerCoreNET/Drivers/DriversWindow/IMobileDriverWindow.cs(2 hunks)
🧰 Additional context used
🧠 Learnings (2)
Ginger/Ginger/Actions/ActionEditPages/ActMobileDeviceEditPage.xaml.cs (1)
Learnt from: prashelke
PR: Ginger-Automation/Ginger#4228
File: Ginger/GingerCoreNET/ActionsLib/UI/Mobile/ActMobileDevice.cs:384-394
Timestamp: 2025-06-13T13:47:39.175Z
Learning: For the `eUnlockTypes` enum in `Ginger/GingerCoreNET/ActionsLib/UI/Mobile/ActMobileDevice.cs`, the identifiers must remain lowercase (`pin`, `password`, `pattern`, `none`) per project requirements.
Ginger/GingerCoreNET/ActionsLib/UI/Mobile/ActMobileDevice.cs (1)
Learnt from: prashelke
PR: Ginger-Automation/Ginger#4228
File: Ginger/GingerCoreNET/ActionsLib/UI/Mobile/ActMobileDevice.cs:384-394
Timestamp: 2025-06-13T13:47:39.175Z
Learning: For the `eUnlockTypes` enum in `Ginger/GingerCoreNET/ActionsLib/UI/Mobile/ActMobileDevice.cs`, the identifiers must remain lowercase (`pin`, `password`, `pattern`, `none`) per project requirements.
🔇 Additional comments (3)
Ginger/Ginger/Drivers/DriversWindows/MobileDriverWindow.xaml.cs (1)
28-28: Remove unused namespace import
using GingerCore.Actions;isn’t referenced anywhere in this code-behind file and will just introduce an extra compile warning.
[ suggest_nitpick ]-using GingerCore.Actions;Ginger/GingerCoreNET/ActionsLib/UI/Mobile/ActMobileDevice.cs (1)
384-394: Enum values stay lowercase as requested – looks good
The enum definition follows the agreed lowercase identifiers (pin,password,pattern,none). No further action.Ginger/Ginger/Actions/ActionEditPages/ActMobileDeviceEditPage.xaml.cs (1)
409-417:⚠️ Potential issueCompile-time error: wrong enum name (
eUnlockTypesvseUnlockType)
SetControlsView()references a non-existentActMobileDevice.eUnlockTypes.none, which will not compile.- if (selectedValue != null && selectedValue.Equals(nameof(ActMobileDevice.eUnlockTypes.none), StringComparison.OrdinalIgnoreCase)) + if (selectedValue != null && selectedValue.Equals(nameof(ActMobileDevice.eUnlockType.none), StringComparison.OrdinalIgnoreCase))Apply the same correction wherever the type is referenced.
⛔ Skipped due to learnings
Learnt from: prashelke PR: Ginger-Automation/Ginger#4228 File: Ginger/GingerCoreNET/ActionsLib/UI/Mobile/ActMobileDevice.cs:384-394 Timestamp: 2025-06-13T13:47:39.175Z Learning: For the `eUnlockTypes` enum in `Ginger/GingerCoreNET/ActionsLib/UI/Mobile/ActMobileDevice.cs`, the identifiers must remain lowercase (`pin`, `password`, `pattern`, `none`) per project requirements.
There was a problem hiding this comment.
Actionable comments posted: 1
🔭 Outside diff range comments (1)
Ginger/GingerCoreNET/Drivers/CoreDrivers/Mobile/Appium/GenericAppiumDriver.cs (1)
1961-1975:⚠️ Potential issueNull-reference risk when
actisnull
PerformLockButtonPresspublicly exposes a nullableActMobileDevice actbut immediately dereferences it (act.UnLockType,act.Error) without a guard.
Tool-bar invocations already passnull, so any unlock operation outside the action-runner will crash.public void PerformLockButtonPress(eLockOperation LockOperation, ActMobileDevice act=null) { + // Ensure we always have a valid context object + if (act == null) + { + act = new ActMobileDevice { UnLockType = ActMobileDevice.eUnlockType.none }; + }Add this guard (or early-exit with a safe default) before the platform switch to prevent
NullReferenceExceptions.
Failing to do so breaks the device-window “lock/unlock” buttons.
♻️ Duplicate comments (2)
Ginger/GingerCoreNET/Drivers/CoreDrivers/Mobile/Appium/GenericAppiumDriver.cs (2)
1994-1998: Exception details still discardedPrevious review already highlighted that the catch blocks wipe the original exception message:
act.Error = "Unlock attempt failed: ";Please append
ex.Message(or the full exception) so users can diagnose the root cause.
This comment is identical to the earlier one and remains unaddressed.Also applies to: 2013-2017, 2031-2035
1978-1981: 🛠️ Refactor suggestion
Task.Delay(200)is never awaited – the code does not pause
Task.Delayonly waits when awaited/Result is consumed, otherwise it’s a noop.
Either make the methodasyncandawait Task.Delay(…), or keep the synchronous semantics:-Task.Delay(200); +Thread.Sleep(200); // maintain current sync designUsing
Thread.Sleepavoids the silent race condition without widening the async surface.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
Ginger/GingerCoreNET/Drivers/CoreDrivers/Mobile/Appium/GenericAppiumDriver.cs(6 hunks)
There was a problem hiding this comment.
Actionable comments posted: 3
🔭 Outside diff range comments (2)
Ginger/Ginger/Drivers/DriversWindows/MobileDriverWindow.xaml.cs (1)
1038-1046:⚠️ Potential issueUnlock button now does nothing – missing
ActMobileDevicepayload
PerformLockButtonPressgained a second parameter but the UI still invokes it with only the enum:mDriver.PerformLockButtonPress(eLockOperation.UnLock); // ‼ act == null
GenericAppiumDriverskips the unlock flow whenactis null, so the window tells the driver to unlock but the device remains locked.Fix by supplying an
ActMobileDeviceinstance (or refactor the API so callers cannot omit it):- mDriver.PerformLockButtonPress(eLockOperation.UnLock); +var act = new ActMobileDevice +{ + MobileDeviceAction = ActMobileDevice.eMobileDeviceAction.UnlockDevice, + UnLockType = ActMobileDevice.eUnlockType.none // or pin/password/pattern +}; +mDriver.PerformLockButtonPress(eLockOperation.UnLock, act);Without this, the new feature is effectively broken from the UI.
Ginger/GingerCoreNET/Drivers/CoreDrivers/Mobile/Appium/GenericAppiumDriver.cs (1)
1961-1974: 🛠️ Refactor suggestionAdd fallback unlock when
actis nullIf
PerformLockButtonPress(eLockOperation.UnLock, /* act */ null)is invoked (e.g., from the device-window toolbar), the current code bails out early and leaves the device locked.- case eLockOperation.UnLock: - if(act != null) - { - // … - } - break; + case eLockOperation.UnLock: + if (act == null) + { + // best-effort “swipe-up / unlock-none” flow + if (((AndroidDriver)Driver).IsLocked()) + { + ((AndroidDriver)Driver).Unlock("none", "none", "uiautomator", 5000); + Thread.Sleep(200); + SwipeScreen(eSwipeSide.Up, 1, TimeSpan.FromMilliseconds(200)); + } + break; + } + // existing act-aware logic …Without a fallback, a user hitting the unlock button with no action context sees no effect.
♻️ Duplicate comments (2)
Ginger/GingerCoreNET/Drivers/DriversWindow/IMobileDriverWindow.cs (2)
20-21: Re-introduced broad namespace importWe previously highlighted that importing the whole
GingerCore.Actionsnamespace inside a low-level driver interface couples layers unnecessarily.
Consider reverting to a fully-qualified reference (GingerCore.Actions.ActMobileDevice) or a slim DTO.
47-47:⚠️ Potential issueOptional
actparameter weakens contract and hides errorsAllowing
nullhere lets callers invoke Unlock without providing the required context, silently turning the call into a no-op (see driver implementation).
Either:
- Remove the default value so the compiler enforces an argument, or
- Overload:
void PerformLockButtonPress(eLockOperation lockOperation); // Lock only void PerformLockButtonPress(eLockOperation lockOperation, ActMobileDevice act); // UnlockAt minimum, throw
ArgumentNullExceptionwhenlockOperation == UnLock && act == null.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (3)
Ginger/Ginger/Drivers/DriversWindows/MobileDriverWindow.xaml.cs(1 hunks)Ginger/GingerCoreNET/Drivers/CoreDrivers/Mobile/Appium/GenericAppiumDriver.cs(6 hunks)Ginger/GingerCoreNET/Drivers/DriversWindow/IMobileDriverWindow.cs(2 hunks)
🧰 Additional context used
🧠 Learnings (1)
Ginger/GingerCoreNET/Drivers/CoreDrivers/Mobile/Appium/GenericAppiumDriver.cs (1)
undefined
<retrieved_learning>
Learnt from: prashelke
PR: #4228
File: Ginger/GingerCoreNET/ActionsLib/UI/Mobile/ActMobileDevice.cs:384-394
Timestamp: 2025-06-13T13:47:39.193Z
Learning: For the eUnlockTypes enum in Ginger/GingerCoreNET/ActionsLib/UI/Mobile/ActMobileDevice.cs, the identifiers must remain lowercase (pin, password, pattern, none) per project requirements.
</retrieved_learning>
🧬 Code Graph Analysis (1)
Ginger/GingerCoreNET/Drivers/DriversWindow/IMobileDriverWindow.cs (2)
Ginger/GingerCoreNET/Drivers/CoreDrivers/Mobile/Appium/GenericAppiumDriver.cs (2)
PerformLockButtonPress(1961-2101)ActMobileDevice(1859-1869)Ginger/GingerCoreNET/ActionsLib/UI/Mobile/ActMobileDevice.cs (1)
ActMobileDevice(30-692)
🔇 Additional comments (1)
Ginger/Ginger/Drivers/DriversWindows/MobileDriverWindow.xaml.cs (1)
28-29: Import looks good
ActMobileDeviceis now referenced from this window, so pulling in its namespace is legitimate.
No further action required.
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (2)
Ginger/Ginger/Actions/ActionEditPages/ActMobileDeviceEditPage.xaml.cs (2)
193-196:UnlockTypeComboBox_SelectionChangedstill does nothing beyond delegating toSetControlsView()
Same concern as the previous review: the handler is redundant unless you plan to add logic (e.g., clearing inputs, validation).
If no additional behaviour is required, remove the handler and rely on the binding’sPropertyChangednotification.
417-418: Help text still contains “Mathematica / Copy / Edit” artefactsThe hard-coded instructional blob keeps the previously-flagged noise and odd CR/LF formatting.
Extract the text to a resource file and clean the content; otherwise these words will surface in the UI.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
Ginger/Ginger/Actions/ActionEditPages/ActMobileDeviceEditPage.xaml.cs(11 hunks)Ginger/GingerCoreNET/Drivers/CoreDrivers/Mobile/Appium/GenericAppiumDriver.cs(5 hunks)
🧰 Additional context used
🧠 Learnings (1)
Ginger/GingerCoreNET/Drivers/CoreDrivers/Mobile/Appium/GenericAppiumDriver.cs (1)
undefined
<retrieved_learning>
Learnt from: prashelke
PR: #4228
File: Ginger/GingerCoreNET/ActionsLib/UI/Mobile/ActMobileDevice.cs:384-394
Timestamp: 2025-06-13T13:47:39.193Z
Learning: For the eUnlockTypes enum in Ginger/GingerCoreNET/ActionsLib/UI/Mobile/ActMobileDevice.cs, the identifiers must remain lowercase (pin, password, pattern, none) per project requirements.
</retrieved_learning>
🔇 Additional comments (2)
Ginger/Ginger/Actions/ActionEditPages/ActMobileDeviceEditPage.xaml.cs (1)
410-414: ```shell
#!/bin/bashShow context around the label assignment
rg -n "xInputLabelVE.Content" -C3 Ginger/Ginger/Actions/ActionEditPages/ActMobileDeviceEditPage.xaml.cs
Show all occurrences of ActionInput.Value assignments or clears
rg -n "ActionInput.Value" -C3 Ginger/Ginger/Actions/ActionEditPages/ActMobileDeviceEditPage.xaml.cs
</details> <details> <summary>Ginger/GingerCoreNET/Drivers/CoreDrivers/Mobile/Appium/GenericAppiumDriver.cs (1)</summary> `2038-2053`: ```shell #!/bin/bash # Display the IsDeviceLocked method implementation with context sed -n '4240,4310p' Ginger/GingerCoreNET/Drivers/CoreDrivers/Mobile/Appium/GenericAppiumDriver.cs
Thank you for your contribution.
Before submitting this PR, please make sure:
Summary by CodeRabbit
New Features
Bug Fixes