Skip to content

Commit

Permalink
Merge pull request #895 from licanhua/addjs
Browse files Browse the repository at this point in the history
Provide JavaScript examples: WinAppDriver + selenium-webdriver and WinAppDriver + WebDriverIO
  • Loading branch information
hassanuz committed Oct 8, 2019
2 parents c33c66b + ef7d2e6 commit 28cee06
Show file tree
Hide file tree
Showing 32 changed files with 9,728 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ obj/
# except build/, which is used as an MSBuild target.
!**/packages/build/

# except Javascript examples
!Samples/JavaScript/packages

# Visual Studio 2015/2017 cache/options directory
.vs/

3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "Xaml-Controls-Gallery"]
path = Xaml-Controls-Gallery
url = https://github.com/microsoft/Xaml-Controls-Gallery.git
103 changes: 103 additions & 0 deletions Samples/JavaScript/.ado/azure-pipelines.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
trigger: none # will disable CI builds entirely

pr:
- master

pool:
vmImage: 'windows-2019'

steps:
- checkout: self
clean: true
lfs: false
submodules: true
persistCredentials: false

- template: templates/buildTestApp.yml

- template: templates/deployTestApp.yml

- task: PowerShell@2
displayName: 'Remove WebDriverIO Workaround'
inputs:
targetType: 'inline'
script: '((Get-Content -path Samples/JavaScript/packages/webdriverio/package.json -Raw) -replace ".*webdriver.git.*","") | Set-Content -Path Samples/JavaScript/packages/webdriverio/package.json'

- task: CmdLine@2
displayName: yarn install
inputs:
script: yarn install
workingDirectory: Samples/JavaScript/

- task: PowerShell@2
displayName: 'Patch WebDriverIO'
inputs:
targetType: 'inline'
script: '((Get-Content -path Samples/JavaScript/node_modules/webdriver/build/utils.js -Raw) -replace "if \(!body .*","if (!body) {") | Set-Content -Path Samples/JavaScript/node_modules/webdriver/build/utils.js'


- task: WinAppDriver.winappdriver-pipelines-task.winappdriver-pipelines-task.Windows Application Driver@0
displayName: 'Start - WinAppDriver'
inputs:
WADArguments: 127.0.0.1 4723/wd/hub
AgentResolution: 1080p

- task: PowerShell@2
displayName: 'Start the App'
inputs:
targetType: 'inline'
script: 'start shell:AppsFolder\Microsoft.XAMLControlsGallery_8wekyb3d8bbwe!App'

# Wait for app to launch. A workaround to avoid WinAppDriver error: Failed to locate opened application window with appId
- task: PowerShell@2
displayName: Wait for app to launch
inputs:
targetType: inline # filePath | inline
script: |
Start-Sleep -Seconds 30
- task: PowerShell@2
displayName: 'Check TestApp'
inputs:
targetType: 'inline'
script: 'if ((Get-Process AppUIBasics) -eq $Null) { echo "TestApp is not running"; exit 1}'

- task: CmdLine@2
displayName: Run WebDriverIO test
inputs:
script: yarn run test
workingDirectory: Samples/JavaScript/packages/webdriverio
condition: succeededOrFailed()

- task: WinAppDriver.winappdriver-pipelines-task.winappdriver-pipelines-task.Windows Application Driver@0
displayName: 'Stop - WinAppDriver'
inputs:
OperationType: Stop
condition: succeededOrFailed()

- task: WinAppDriver.winappdriver-pipelines-task.winappdriver-pipelines-task.Windows Application Driver@0
displayName: 'Start - WinAppDriver'
inputs:
WADArguments: 127.0.0.1 4723/wd/hub
AgentResolution: 1080p
condition: succeededOrFailed()

- task: CmdLine@2
displayName: yarn install
inputs:
script: yarn install
workingDirectory: Samples/JavaScript/packages/selenium-webdriver
condition: succeededOrFailed()

- task: CmdLine@2
displayName: Run selenium-webdriver test
inputs:
script: yarn run jest
workingDirectory: Samples/JavaScript/packages/selenium-webdriver
condition: succeededOrFailed()

- task: WinAppDriver.winappdriver-pipelines-task.winappdriver-pipelines-task.Windows Application Driver@0
displayName: 'Stop - WinAppDriver'
inputs:
OperationType: Stop
condition: succeededOrFailed()
24 changes: 24 additions & 0 deletions Samples/JavaScript/.ado/templates/buildTestApp.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
steps:
- task: NuGetToolInstaller@0
displayName: 'Use NuGet 4.4.1'
inputs:
versionSpec: 4.4.1

- task: NuGetCommand@2
displayName: 'NuGet restore'
inputs:
restoreSolution: Xaml-Controls-Gallery/XamlControlsGallery/XamlControlsGallery.sln
- task: VSBuild@1
displayName: 'Build solution XamlControlsGallery/XamlControlsGallery.sln'
inputs:
solution: Xaml-Controls-Gallery/XamlControlsGallery/XamlControlsGallery.sln
msbuildArgs: '/p:Configuration=Deploy /p:AppxPackageDir="$(Build.ArtifactStagingDirectory)\\" /p:UapAppxPackageBuildMode=CI/p:AppxBundlePlatforms="x86" /p:AppxBundle=Always'
platform: x86
configuration: Release
- task: CopyFiles@2
displayName: 'Copy Files to: $(build.artifactstagingdirectory)'
inputs:
SourceFolder: '$(system.defaultworkingdirectory)'
Contents: '**\bin\$(BuildConfiguration)\**'
TargetFolder: '$(build.artifactstagingdirectory)'
condition: succeededOrFailed()
15 changes: 15 additions & 0 deletions Samples/JavaScript/.ado/templates/deployTestApp.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
steps:
- task: PowerShell@1
displayName: 'Install Xaml Controls Cert'
inputs:
scriptType: inlineScript
arguments: '-NonInteractive -Verb RunAs'
inlineScript: |
$file = ( Get-ChildItem -Path $(Build.ArtifactStagingDirectory)\XamlControlsGallery_$(PackageManifest)_Test\XamlControlsGallery_$(PackageManifest)_x86.cer )
$file | Import-Certificate -CertStoreLocation cert:\LocalMachine\Root
- task: PowerShell@1
displayName: 'Install XAML Appx Packages'
inputs:
scriptName: '$(Build.ArtifactStagingDirectory)\XamlControlsGallery_$(PackageManifest)_Test\Add-AppDevPackage.ps1'
arguments: '-NonInteractive -Force:$true -Verb RunAs'
5 changes: 5 additions & 0 deletions Samples/JavaScript/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
*/node_modules
# Reports section
packages/webdriverio/reports
.vscode
node_modules
53 changes: 53 additions & 0 deletions Samples/JavaScript/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# winappdriver-js-webdriver-example
There are two popular JavaScript WebDrivers which could be used for WinAppDriver testing: [selenium-webdriver](https://www.npmjs.com/package/selenium-webdriver) and [webdriverio](https://webdriver.io/).

This is used to demo UI automation testing with WinAppDriver which the test runner is JavaScript. It includes the examples and Azure Pipeline with selenium-webdirver and WebDriverIO.
1. Jest + selenium-webdriver + WinAppDriver
2. Jasmine + WebDriverIO + WinAppDriver


[WinAppDriver](https://github.com/Microsoft/WinAppDriver) is recommended to do E2E test for Windows apps.
Here I validate [Xaml-Controls-Gallery](https://github.com/Microsoft/Xaml-Controls-Gallery) application using JavaScript + WinAppDriver.

This test project highlights the following basic interactions to demonstrate how UI testing using Windows Application Driver work.
- Azure pipeline
- Finding element using 'accessibility id' and 'name'
- Sending click action to an element
- Retrieving element value
- WinAppDriver integration with WebDriverIO and selenium-webdriver

I prototyped and successfully made the two webdrivers to be happy with WinAppDriver. And you can use any of them on your project.

## Examples
I provided two examples which are using selenium-webdriver or webdriverio.

- [selenium-webdriver example](packages/selenium-webdriver/README.md) in packages/selenium-webdriver

selenium-webdriver is the offical WebDriver JavaScript binding from selenium project. Unfortunately selenium-webdriver doesn't support [Mobile JSON Wire Protocol Specification](https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol).
[selenium-appium](https://www.npmjs.com/package/selenium-appium) is selenium-webdriver extension to make selenium-webdriver to drive Appium to run automation.

- [webdriverio example](packages/webdriverio/README.md) in packages/webdriverio

WinAppDriver doesn't implement w3c WebDriver completely, so currently I workaround the problem by [WebDriver](https://github.com/react-native-windows/webdriver). In your project, you have to use private webdriver in package.json lke this:
```
"webdriverio": "^5.10.1",
"webdriver": "git+https://github.com/react-native-windows/webdriver.git",
```

## Azure pipeline for WinAppDriver
Please refer to [.ado](.ado) folder in this project.
For WinAppDriver, see [WinAppDriver in CI with Azure Pipelines](https://github.com/microsoft/WinAppDriver/blob/master/Docs/CI_AzureDevOps.md)

## Dependencies
* Install nodejs, make sure a recent version of [Node.js](https://nodejs.org) is installed.
[Chocolatey](https://chocolatey.org/) is the recommended installation method. But you can also install Node directly from [NodeJs](https://nodejs.org/en/download/). To use chocolately, from an elevated Command Prompt, run:
```
choco install nodejs
```
* Install [Yarn](https://yarnpkg.com/en/docs/install) (*optional* if you use npm command directly)

* Install 'xaml controls Gallery'
- Download and Install it from Microsoft Store.
- Or build and deploy Xaml-Controls-Gallery submodule

* Install the most recent stable [WinAppDriver](https://github.com/Microsoft/WinAppDriver/releases) on the test device
6 changes: 6 additions & 0 deletions Samples/JavaScript/lerna.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"packages": [
"packages/*"
],
"version": "0.0.0"
}
19 changes: 19 additions & 0 deletions Samples/JavaScript/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "winappdriver-js-webdriver-example-repo",
"version": "0.0.1",
"private": true,
"scripts": {
},
"repository": {
"type": "git",
"url": "[email protected]:Microsoft/WinAppDriver.git"
},
"license": "MIT",
"workspaces": {
"packages": [
"packages/*"
]
},
"devDependencies": {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/

import { PageObject, By2 } from "selenium-appium";

class BasicInputPage extends PageObject {
isPageLoaded() {
return this.checkBoxButton.isDisplayed();
}

private get checkBoxButton() { return By2.nativeName('CheckBox'); }
private get buttonButton() { return By2.nativeName('Button'); }

gotoButtonPage() {
return this.buttonButton.click();
}

gotoCheckboxPage() {
return this.checkBoxButton.click();
}
}

export default new BasicInputPage();
25 changes: 25 additions & 0 deletions Samples/JavaScript/packages/selenium-webdriver/Pages/ButtonPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/

import { PageObject, By2 } from "selenium-appium";

class ButtonPage extends PageObject {
isPageLoaded() {
return this.button1Button.isDisplayed();
}

private get button1Button() { return By2.nativeAccessibilityId('Button1'); }
private get control1Ooutput() { return By2.nativeAccessibilityId('Control1Output');}

clickButton1() {
return this.button1Button.click();
}

getControl1Output() {
return this.control1Ooutput.getText();
}
}

export default new ButtonPage();
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/

import { PageObject, By2 } from "selenium-appium";

class CheckBoxPage extends PageObject {
isPageLoaded() {
return this.checkbox1Button.isDisplayed();
}

private get checkbox1Button() { return By2.nativeName('Two-state CheckBox'); }
private get control1Ooutput() { return By2.nativeAccessibilityId('Control1Output');}

clickCheckbox1() {
return this.checkbox1Button.click();
}

getControl1Output() {
return this.control1Ooutput.getText();
}
}

export default new CheckBoxPage();
19 changes: 19 additions & 0 deletions Samples/JavaScript/packages/selenium-webdriver/Pages/HomePage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/

import { PageObject, By2 } from "selenium-appium";

class HomePage extends PageObject {
isPageLoaded() {
return this.basicInputButton.isDisplayed();
}
private get basicInputButton() { return By2.nativeName('Basic Input'); }

gotoBasicInputPage() {
return this.basicInputButton.click();
}
}

export default new HomePage();
17 changes: 17 additions & 0 deletions Samples/JavaScript/packages/selenium-webdriver/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
## Example with selenium-webdriver
Make sure [Dependencies](../../README.md)

1. goto selenium-webdriver project
2. start appium

`yarn run appium` or `npm run appium`

expect output
```
[Appium] Welcome to Appium v1.14.1
[Appium] Appium REST http interface listener started on 0.0.0.0:4723
```

3. run jest test

`yarn run jest` or `npm run jest`
Loading

0 comments on commit 28cee06

Please sign in to comment.