Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ Apps:
WinPath: C:\Users\user\AppData\Local\Programs\SomeApp\SomeApp.exe
UWPAppName: SOMEAPP.1234567890ABC_defghijklmnop!App
MacAppName: com.someapp
</pre>
</pre>

This will add all the necessary capabilities to run on iOS, MacOS, Windows and Android

Expand Down Expand Up @@ -167,6 +167,9 @@ Devices:
- role: localWindows
platform: Windows
</pre>
> [!NOTE]
> For Windows apps, you can set `WinPath` under the app config to `Root` in order to control all Windows screen elements.
If `WinPath` is not provided and `appiumUrl` is either absent or set to `localhost`, the framework will automatically attempt to search for the application window handle on the local machine. You can skip this behavior by setting `appiumUrl` to `127.0.0.1`, which will allow you to manually set the app or `hexMainWindowHandle` inside the role's `capabilities`.


## <a id="test_case"></a>Create Test Case
Expand Down
33 changes: 33 additions & 0 deletions examples/tests/cases/case_windows_tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
RemoteWindowsTestExample:
Roles:
- Role: remoteWindows
App: RootWindows
Actions:
- Type: case
Value: WindowsTestExample
Role: remoteWindows

LocalWindowsTestExample:
Roles:
- Role: localWindows
App: RootWindows
Actions:
- Type: case
Value: WindowsTestExample
Role: localWindows

WindowsTestExample:
Actions:
- Type: screenshot
Name: windows_home_screen
- Type: click
Strategy: xpath
Id: "//Text[@Name=\"Search\"]"
- Type: send_keys
Strategy: xpath
Id: "//Edit[@Name=\"Search box\"]"
Value: Settings
- Type: sleep
Time: 2
- Type: screenshot
Name: windows_search_done
8 changes: 8 additions & 0 deletions examples/tests/cases/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Apps:
Activity: com.android.vending.AssetBrowserActivity
Settings:
iOSBundle: com.apple.Preferences
RootWindows:
WinPath: Root # Controls everything on screen

chromeDriverPath: chromedriver

Expand All @@ -29,6 +31,12 @@ Devices:
# IOS
- role: localiOS
platform: iOS
# WINDOWS
- role: remoteWindows
platform: Windows
appiumUrl: http://IP:PORT # Windows device with running Appium server
- role: localWindows
platform: Windows

#VARS

Expand Down
3 changes: 2 additions & 1 deletion lib/core/appium_server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ def start
@port = @port + 2
opened = `netstat -anp tcp | #{grep_cmd} "#{@port}"`.include?("LISTEN")
end
log_debug("Executing: appium --base-path=/wd/hub -p #{@port} >> \"#{folder}/#{@udid}.log\" 2>&1")

spawn("appium --base-path=/wd/hub -p #{@port} >> #{folder}/#{@udid}.log 2>&1")
spawn("appium --base-path=/wd/hub -p #{@port} >> \"#{folder}/#{@udid}.log\" 2>&1")

opened = false
log_info("Role '#{@role}': Starting Appium server on port #{@port} ", no_date=false, _print=true)
Expand Down
43 changes: 29 additions & 14 deletions lib/core/device_drivers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,30 +69,45 @@ def build_mac_caps

# assemble basic capabilities for Windows
def build_windows_caps
process_check = execute_powershell("Get-Process #{@app}")
caps = {
"platformName" => "Windows",
"automationName" => "Windows",
"newCommandTimeout" => 2000 * 60,
}
if @app_details.key?("WinPath")
caps.merge!({ "app" => @app_details["WinPath"] })
return caps # No matter if localhost or remote, because Appium will determine window handle automatically
end

unless @url.include? "localhost"
# Either remote or no need to check for windows handle (127.0.0.1)
return caps
end

# Running on "localhost" with automatic path to app detection in home directory
if !OS.windows?
log_abort("Cannot run a local windows role on a non-windows operating system!")
end
process_check = execute_powershell("Get-Process \"#{@app}\"")
if process_check.include? "Exception"
if @app_details.key?("UWPAppName") # launch UWP app
spawn("start shell:AppsFolder\\#{@app_details["UWPAppName"]}")
else # launch Win32 app
spawn(execute_powershell("where.exe /r $HOME #{@app}.exe"))
app_path = execute_powershell("where.exe /r $HOME \"#{@app}.exe\"").strip
log_debug("Found app path: #{app_path}")
# Array syntax allows to handle any spaces in the filepath.
pid = spawn([app_path, app_path])
Process.detach(pid)
end
sleep(5)
end

processWindowHandles = execute_powershell("(Get-Process #{@app}).MainWindowHandle").split("\n")

# Note: Capabilities app and appTopLevelWindow cannot work together)
processWindowHandles = execute_powershell("(Get-Process \"#{@app}\").MainWindowHandle").split("\n")
appMainWindowHandleList = (processWindowHandles.select { |wh| wh.to_i != 0 })
hexMainWindowHandle = appMainWindowHandleList[-1].to_i.to_s(16)
caps.merge!({ "appTopLevelWindow" => "#{hexMainWindowHandle}" })

caps = {
"platformName" => "Windows",
"forceMjsonwp" => true,
"newCommandTimeout" => 2000 * 60,
}
if @app_details.key?("WinPath")
caps.merge!({ "app" => @app_details["WinPath"] })
else
caps.merge!({ "appTopLevelWindow" => "#{hexMainWindowHandle}" })
end
return caps
end

Expand Down