├── .editorconfig ├── .github ├── ISSUE_TEMPLATE │ ├── feature_request.md │ └── issue_template.md ├── PULL_REQUEST_TEMPLATE.md ├── dependabot.yml ├── labeler.yml ├── release-drafter.yml └── workflows │ ├── main.yml │ ├── release-drafter.yml │ └── release-nuget.yml ├── .gitignore ├── Appium.Net.sln ├── CHANGELOG.MD ├── CONTRIBUTING.md ├── LICENSE ├── NOTICE ├── README.md ├── RELEASE_NOTES.md ├── azure-pipelines.yml ├── src └── Appium.Net │ ├── Appium.Net.csproj │ ├── Appium.Net.licenseheader │ ├── Appium │ ├── Android │ │ ├── AndroidCommandExecutionHelper.cs │ │ ├── AndroidDriver.cs │ │ ├── AndroidStartScreenRecordingOptions.cs │ │ ├── AndroidStopScreenRecordingOptions.cs │ │ ├── Enums │ │ │ ├── AndroidKeyCode.cs │ │ │ ├── AndroidKeyMetastate.cs │ │ │ ├── AutomatorSetting.cs │ │ │ ├── ConnectionType.cs │ │ │ ├── ListDirection.cs │ │ │ └── PerformanceDataType.cs │ │ ├── Interfaces │ │ │ ├── IHasPerformanceData.cs │ │ │ ├── IHasSettings.cs │ │ │ ├── IPushesFiles.cs │ │ │ └── IStartsActivity.cs │ │ ├── KeyEvent.cs │ │ └── UiAutomator │ │ │ ├── AndroidUiScrollable.cs │ │ │ ├── AndroidUiSelector.cs │ │ │ └── TerminatedStatementBuilder.cs │ ├── AppiumCommand.cs │ ├── AppiumCommandExecutionHelper.cs │ ├── AppiumDriver.cs │ ├── AppiumDriverCommand.cs │ ├── AppiumElement.cs │ ├── AppiumElementFactory.cs │ ├── AppiumOptions.cs │ ├── CachedElementFactory.cs │ ├── Enums │ │ ├── AndroidMobileCapabilityType.cs │ │ ├── AppState.cs │ │ ├── AutomationName.cs │ │ ├── ClipboardContentType.cs │ │ ├── GsmCallActions.cs │ │ ├── GsmSignalStrength.cs │ │ ├── GsmVoiceState.cs │ │ ├── IOSMobileCapabilityType.cs │ │ ├── MobileBrowserType.cs │ │ ├── MobileCapabilityType.cs │ │ ├── MobilePlatform.cs │ │ └── MobileSelector.cs │ ├── GuardClauses.cs │ ├── ImageComparison │ │ ├── ComparisonMode.cs │ │ ├── ComparisonOptions.cs │ │ ├── ComparisonResult.cs │ │ ├── FeaturesMatchingOptions.cs │ │ ├── FeaturesMatchingResult.cs │ │ ├── OccurenceMatchingOptions.cs │ │ ├── OccurenceMatchingResult.cs │ │ ├── SimilarityMatchingOptions.cs │ │ └── SimilarityMatchingResult.cs │ ├── Interactions │ │ ├── InteractionInfo.cs │ │ └── PointerInputDevice.cs │ ├── Interfaces │ │ ├── Generic │ │ │ └── SearchContext │ │ │ │ ├── IGenericFindsByClassName.cs │ │ │ │ ├── IGenericFindsByCssSelector.cs │ │ │ │ ├── IGenericFindsById.cs │ │ │ │ ├── IGenericFindsByLinkText.cs │ │ │ │ ├── IGenericFindsByName.cs │ │ │ │ ├── IGenericFindsByPartialLinkText.cs │ │ │ │ ├── IGenericFindsByTagName.cs │ │ │ │ ├── IGenericFindsByXPath.cs │ │ │ │ └── IGenericSearchContext.cs │ │ ├── IContextAware.cs │ │ ├── IExecuteMethod.cs │ │ ├── IFindByAccessibilityId.cs │ │ ├── IFindByAndroidDataMatcher.cs │ │ ├── IFindByAndroidUIAutomator.cs │ │ ├── IFindByAndroidViewMatcher.cs │ │ ├── IFindByTizenUIAutomation.cs │ │ ├── IFindByWindowsUIAutomation.cs │ │ ├── IFindsByFluentSelector.cs │ │ ├── IFindsByIosClassChain.cs │ │ ├── IFindsByIosNSPredicate.cs │ │ ├── IFindsByimage.cs │ │ ├── IHasClipboard.cs │ │ ├── IHasLocation.cs │ │ ├── IHasSessionDetails.cs │ │ ├── IHidesKeyboard.cs │ │ ├── IHidesKeyboardWithKeyName.cs │ │ ├── IInteractsWithApps.cs │ │ ├── IInteractsWithFiles.cs │ │ ├── IMobileElement.cs │ │ ├── IMultiAction.cs │ │ ├── INetworkActions.cs │ │ ├── IScreenRecordingOptions.cs │ │ ├── ISendsKeyEvents.cs │ │ ├── ITouchAction.cs │ │ ├── IUiAutomatorStatementBuilder.cs │ │ └── IWebElementCached.cs │ ├── Location.cs │ ├── Mac │ │ └── MacDriver.cs │ ├── MobileBy.cs │ ├── ScreenOrientationExtensions.cs │ ├── ScreenRecording │ │ ├── BaseScreenRecordingOptions.cs │ │ ├── BaseStartScreenRecordingOptions.cs │ │ ├── BaseStopScreenRecordingOptions.cs │ │ └── ScreenRecordingUploadOptions.cs │ ├── Service │ │ ├── AppiumClientConfig.cs │ │ ├── AppiumCommandExecutor.cs │ │ ├── AppiumHttpCommandExecutor.cs │ │ ├── AppiumLocalService.cs │ │ ├── AppiumServiceBuilder.cs │ │ ├── AppiumServiceConstants.cs │ │ ├── DirectConnect.cs │ │ ├── Exceptions │ │ │ ├── AppiumServerHasNotBeenStartedLocallyException.cs │ │ │ ├── InvalidNodeJSInstanceException.cs │ │ │ └── InvalidServerInstanceException.cs │ │ └── Options │ │ │ ├── AndroidOptionList.cs │ │ │ ├── BaseOptionList.cs │ │ │ ├── GeneralOptionList.cs │ │ │ ├── IOSOptionList.cs │ │ │ └── OptionCollector.cs │ ├── Tizen │ │ ├── TizenCommandExecutionHelper.cs │ │ └── TizenDriver.cs │ ├── Windows │ │ ├── Enums │ │ │ └── WindowsKeyCodes.cs │ │ ├── WindowsDriver.cs │ │ └── WindowsDriverCommand.cs │ └── iOS │ │ ├── IOSCommandExecutionHelper.cs │ │ ├── IOSDriver.cs │ │ ├── IOSStartScreenRecordingOptions.cs │ │ ├── IOSStopScreenRecordingOptions.cs │ │ └── Interfaces │ │ ├── IHasSettings.cs │ │ ├── IPerformsTouchID.cs │ │ └── IShakesDevice.cs │ ├── LICENSE.txt │ ├── Properties │ ├── Resources.Designer.cs │ └── Resources.resx │ └── appium-icon.png └── test └── integration ├── Android ├── ActionsChainsTest.cs ├── ActivityTest.cs ├── AndroidUiScrollableTests.cs ├── AndroidUiSelectorTests.cs ├── AppStringsTest.cs ├── BiDiTests.cs ├── ClipboardTest.cs ├── ConnectionTest.cs ├── CurrentPackageTest.cs ├── Device │ ├── App │ │ └── AppTests.cs │ ├── AuthenticationTest.cs │ ├── BrowserTests.cs │ ├── Keys │ │ ├── KeyPressTest.cs │ │ └── KeyboardTests.cs │ ├── NetworkTests.cs │ ├── PerformanceDataTests.cs │ └── SystemTests.cs ├── ElementTest.cs ├── ElementTestEspresso.cs ├── EmulatorDeviceTime.cs ├── EventsTests.cs ├── FileInteractionTest.cs ├── FiltersTests.cs ├── LockDeviceTest.cs ├── OrientationTest.cs ├── ScreenRecordingTest.cs ├── SearchingTest.cs ├── Session │ ├── GeolocationTests.cs │ ├── LogTests.cs │ └── SessionTests.cs ├── SettingTest.cs └── WaitTests.cs ├── Appium.Net.Integration.Tests.csproj ├── IOS ├── AlertTests.cs ├── AppStringsTest.cs ├── ClipboardTest.cs ├── Device │ ├── AppTests.cs │ ├── KeyboardTests.cs │ └── SystemTests.cs ├── ElementTest.cs ├── LockDeviceTest.cs ├── OrientationTest.cs ├── ScreenRecordingTest.cs ├── ScrollingSearchingTest.cs ├── SearchingClassChainTest.cs ├── SearchingTest.cs ├── Session │ └── LogTests.cs ├── SettingTest.cs └── WebviewTest.cs ├── Mac └── AlertTest.cs ├── Options └── OptionsTest.cs ├── Properties ├── Resources.Designer.cs └── Resources.resx ├── README.md ├── ServerTests ├── AppiumClientConfigTest.cs ├── AppiumLocalServerLaunchingTest.cs ├── DirectConnectTest.cs ├── RelaxSslValidationTest.cs └── StartingAppLocallyTest.cs ├── Windows ├── ClickElementTest.cs ├── ImagesComparisonTest.cs ├── MultiSelectControlTest.cs ├── PentTest.cs └── StickyNotesTest.cs ├── apps ├── ApiDemos-debug.apk ├── IntentExample.apk └── archives │ ├── ApiDemos-debug.zip │ ├── IntentExample.zip │ ├── TestApp.app.zip │ ├── UICatalog.app.zip │ ├── WebViewApp.app.zip │ └── vodqa.zip ├── env.json.sample └── helpers ├── AppiumServers.cs ├── Apps.cs ├── Caps.cs ├── Env.cs ├── Filters.cs ├── Npm.cs ├── NpmNotFoundException.cs ├── NpmUnknownCommandException.cs └── Paths.cs /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [lib/**.js] 4 | indent_style = space 5 | indent_size = 4 6 | 7 | [*.cs] 8 | indent_style = space 9 | indent_size = 4 10 | 11 | # Set up additional disposal methods for a specific diagnostic rule 12 | dotnet_diagnostic.NUnit1032.additional_dispose_methods = Quit -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🚀 Feature request 3 | about: Suggest an idea for this project 4 | title: '[Feat]: ' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/issue_template.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🐞 Bug Report 3 | about: File a bug report 4 | title: '[Bug]: <title>' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Description 11 | 12 | Please describe the issue. It may be a bug description. So then please briefly describe the steps that you were trying to perform and what happened instead. 13 | If there is a feature you want to see added to the Appium .NET client so please describe the necessity of this feature and the way that it should work. 14 | 15 | ## Environment 16 | 17 | * .NET client build version or git revision if you use some snapshot: 18 | * Appium server version or git revision if you use some snapshot: 19 | * Desktop OS/version used to run Appium if necessary: 20 | * Node.js version (unless using Appium.app|exe) or Appium CLI or Appium.app|exe: 21 | * Mobile platform/version under test: 22 | * Real device or emulator/simulator: 23 | 24 | ## Details 25 | 26 | Please provide more details, if necessary. 27 | 28 | 29 | ## Code To Reproduce Issue [ Good To Have ] 30 | 31 | Please remember that, with sample code; it's easier to reproduce a bug and much faster to fix it. 32 | You can git clone https://github.com/appium/sample-code or https://github.com/appium/sample-code/tree/master/sample-code/apps and reproduce an issue using C# and sample apps. 33 | Also, you can create a [gist](https://gist.github.com) with pasted C# code sample or put it here using markdown. About markdown please read [Mastering markdown](https://guides.github.com/features/mastering-markdown/) and 34 | [Writing on GitHub](https://help.github.com/categories/writing-on-github/) 35 | 36 | ## Exception stack traces 37 | 38 | Please create a [gist](https://gist.github.com) with the pasted stack trace of exceptions thrown by .NET. 39 | 40 | ## Link to Appium logs 41 | 42 | Please create a [gist](https://gist.github.com) which is a paste of your _full_ Appium logs, and link them here. Do _not_ paste your full Appium logs here, as it will make this issue very long and hard to read! 43 | If you are reporting a bug, _always_ include Appium logs as linked gists! It helps to define the problem correctly and clearly. 44 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## List of changes 2 | 3 | Please provide a briefly described change list that you are going to propose. 4 | 5 | ## Types of changes 6 | 7 | What types of changes are you proposing/introducing to the .NET client? 8 | _Put an `x` in the boxes that apply_ 9 | 10 | - [ ] Bugfix (non-breaking change which fixes an issue) 11 | - [ ] New feature (non-breaking change that adds functionality or value) 12 | - [ ] Breaking change (fix or feature that would cause existing functionality not to work as expected) 13 | - [ ] **Test fix** (non-breaking change that improves test stability or correctness) 14 | 15 | ## Documentation 16 | - [ ] Have you proposed a file change/ PR with Appium to update documentation? 17 | #### This can be done by navigating to the documentation section on http://appium.io selecting the appropriate command/endpoint and clicking the 'Edit this doc' link to update the C# example 18 | 19 | ## Integration tests 20 | - [ ] Have you provided integration tests for your changes? (required for Bugfix, New feature, or Test fix) 21 | 22 | ## Details 23 | 24 | Please provide more details about changes if necessary. You can provide code samples showing how they work and possible use cases if there are new features. Also, you can create [gists](https://gist.github.com) with pasted C# code samples or put them here using markdown. 25 | About markdown please read [Mastering markdown](https://guides.github.com/features/mastering-markdown/) and [Writing on GitHub](https://docs.github.com/en/get-started/writing-on-github) 26 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "nuget" 4 | # Files stored in src/Appium.Net directory 5 | directory: "/src/Appium.Net" 6 | schedule: 7 | interval: "weekly" 8 | 9 | - package-ecosystem: "nuget" 10 | # Files stored in test/integration directory 11 | directory: "/test/integration" 12 | schedule: 13 | interval: "weekly" 14 | 15 | - package-ecosystem: "github-actions" 16 | # Workflow files stored in the 17 | # default location of `.github/workflows` 18 | directory: "/" 19 | schedule: 20 | # Check for updates to GitHub Actions every week 21 | interval: "weekly" 22 | commit-message: 23 | # Prefix all commit messages with "[github-actions] " 24 | prefix: "[github-actions] " 25 | -------------------------------------------------------------------------------- /.github/labeler.yml: -------------------------------------------------------------------------------- 1 | Enhancement: 2 | title: "^feat:.*" 3 | 4 | BugFix: 5 | title: "^fix:.*" 6 | 7 | Documentation: 8 | title: "^docs:.*" 9 | 10 | Build: 11 | title: "^build:.*" 12 | 13 | CI: 14 | title: "^ci:.*" 15 | 16 | Test: 17 | title: "^test:.*" 18 | 19 | Chore: 20 | title: "^chore:.*" 21 | 22 | GitHub: 23 | title: "^github:.*" 24 | 25 | WIP: 26 | title: "^WIP:.*" 27 | mergeable: false 28 | 29 | BreakingChange: 30 | title: "^.*BREAKING CHANGE:.*|.*!.*" 31 | mergeable: false 32 | 33 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name-template: 'v$RESOLVED_VERSION' 2 | tag-template: 'v$RESOLVED_VERSION' 3 | template: | 4 | # What's Changed 5 | 6 | $CHANGES 7 | 8 | ## 🚀 Contributors 9 | Thanks to the following contributors in this release: 10 | $CONTRIBUTORS 11 | 12 | categories: 13 | - title: '✨ Enhancements' 14 | label: 'Enhancement' 15 | - title: '🐛 Bug Fixes' 16 | labels: 17 | - 'BugFix' 18 | - title: '🔄 Refactor' 19 | label: 'Refactor' 20 | - title: '📦 Dependencies' 21 | labels: 22 | - 'Dependencies' 23 | - title: '🛠️ Pipeline' 24 | labels: 25 | - 'CI' 26 | - 'Build' 27 | - title: '🧰 Maintenance' 28 | label: 'Chore' 29 | - title: '🧪 Tests' 30 | label: 31 | - 'Test' 32 | - title: '📚 Documentation' 33 | labels: 34 | - 'Documentation' 35 | 36 | version-resolver: 37 | major: 38 | labels: 39 | - 'BreakingChange' 40 | minor: 41 | labels: 42 | - 'Enhancement' 43 | patch: 44 | labels: 45 | - 'BugFix' 46 | - 'Dependencies' 47 | - 'Hotfixes' 48 | default: patch 49 | 50 | prerelease: false 51 | prerelease-identifier: 'rc' 52 | contribution-template: '- $NAME contributed via $PULL_REQUEST' 53 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Label PRs 2 | 3 | on: 4 | - pull_request_target 5 | 6 | jobs: 7 | build: 8 | 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: srvaroa/labeler@master 13 | env: 14 | GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" 15 | -------------------------------------------------------------------------------- /.github/workflows/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name: Draft Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | build: 10 | 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | # Drafts your next Release notes as Pull Requests are merged into "main" 15 | - uses: release-drafter/release-drafter@v6 16 | env: 17 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 18 | -------------------------------------------------------------------------------- /.github/workflows/release-nuget.yml: -------------------------------------------------------------------------------- 1 | name: Build and deploy NuGet package 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | 9 | build: 10 | runs-on: windows-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v5 14 | 15 | - name: Setup .NET Core 16 | uses: actions/setup-dotnet@v4 17 | with: 18 | dotnet-version: 5.0.x 19 | 20 | - name: Install dependencies 21 | run: dotnet restore Appium.Net.sln 22 | 23 | - name: Build 24 | run: | 25 | if ("${{github.ref}}".trim() -notmatch '^refs\/tags\/v(((0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*))(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)$') { 26 | Write-Host "Failed to find a tag with a value compatible with Sementic Versioning.\nEnsure the Sementic Versioning regex above matches the tag created for the release!"; exit 1 27 | } 28 | else { 29 | $versionPrefix = $matches[2] 30 | $dotnetBuildCmd = "dotnet build Appium.Net.sln --configuration Release -p:VersionPrefix=${versionPrefix}" 31 | if ($matches.Count -eq 7) { 32 | $versionSuffix = $matches[6] 33 | $dotnetBuildCmd += " --version-suffix ${versionSuffix}" 34 | } 35 | } 36 | Write-Host $dotnetBuildCmd 37 | Invoke-Expression $dotnetBuildCmd 38 | 39 | - name: Deploy to nuget 40 | run: dotnet nuget push **/*.nupkg --api-key ${{ secrets.NUGET_DEPLOY_KEY }} --source https://api.nuget.org/v3/index.json 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | obj 3 | Obj 4 | TestResults 5 | test-results 6 | *.csproj.user 7 | *.suo 8 | *.cache 9 | *~ 10 | *.swp 11 | *.userprefs 12 | *.pidb 13 | packages 14 | *.nupkg 15 | .idea 16 | .vs/ 17 | env.json 18 | .vscode/ 19 | *.user 20 | *.log 21 | *.DS_Store 22 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to the Appium Dotnet Client 2 | 3 | Welcome to the Appium Dotnet Client repository! We're excited to have you contribute. Before you get started, please take a moment to review the following guidelines. 4 | 5 | ## How to Contribute 6 | 7 | ### Reporting Bugs 8 | 9 | If you encounter a bug while using the Appium Dotnet Client, please open an issue on GitHub. Be sure to include as much detail as possible, including steps to reproduce the bug and your environment. 10 | 11 | ### Suggesting Features 12 | 13 | Have an idea for a new feature or improvement? We'd love to hear it! Open an issue on GitHub and describe your suggestion in detail. 14 | 15 | ### Submitting Pull Requests 16 | 17 | We welcome pull requests from contributors. Before submitting a pull request, please make sure your code follows our coding standards and that all tests pass. 18 | 19 | ## Coding Standards 20 | 21 | - Follow the coding style used in the existing codebase. 22 | - Write clear, concise commit messages. 23 | - Include tests for any new functionality or bug fixes. 24 | 25 | ## Code Review Process 26 | 27 | All pull requests will be reviewed by one or more maintainers before being merged. We may request changes or suggest improvements to your code. 28 | 29 | ## Licensing 30 | 31 | By contributing to the Appium Dotnet Client, you agree to license your contributions under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). 32 | 33 | ## Contact 34 | 35 | If you have any questions, need assistance, or want to discuss contributions, feel free to reach out to the maintainer directly at [dblayzer@gmail.com](mailto:dblayzer@gmail.com). 36 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Copyright 2014-2023 Appium Contributors 2 | -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | # ASP.NET Core (.NET Framework) 2 | # Build and test ASP.NET Core projects targeting the full .NET Framework. 3 | # Add steps that publish symbols, save build artifacts, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/dotnet-core 5 | 6 | trigger: 7 | - main 8 | - release/* 9 | 10 | pool: 11 | vmImage: 'windows-latest' 12 | 13 | variables: 14 | solution: '**/*.sln' 15 | buildPlatform: 'Any CPU' 16 | buildConfiguration: 'Release' 17 | 18 | steps: 19 | - task: NuGetToolInstaller@0 20 | 21 | - task: NuGetCommand@2 22 | inputs: 23 | restoreSolution: '$(solution)' 24 | 25 | - task: VSBuild@1 26 | inputs: 27 | solution: '$(solution)' 28 | msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:DesktopBuildPackageLocation="$(build.artifactStagingDirectory)\WebApp.zip" /p:DeployIisAppPath="Default Web Site" /m' 29 | platform: '$(buildPlatform)' 30 | configuration: '$(buildConfiguration)' 31 | 32 | - powershell: 33 | npm install -g appium 34 | displayName: 'Install Appium' 35 | 36 | - task: DotNetCoreCLI@2 37 | displayName: 'Run .NET48 unit tests - $(buildConfiguration)' 38 | inputs: 39 | command: 'test' 40 | arguments: '--no-build --configuration $(buildConfiguration) --filter AppiumLocalServerLaunchingTest|DirectConnectTest|AppiumClientConfigTest --framework net48' 41 | publishTestResults: true 42 | projects: '**/*.Tests.csproj' 43 | 44 | - task: DotNetCoreCLI@2 45 | displayName: 'Run .NET 8 unit tests - $(buildConfiguration)' 46 | inputs: 47 | command: 'test' 48 | arguments: '--no-build --configuration $(buildConfiguration) --filter AppiumLocalServerLaunchingTest|DirectConnectTest|AppiumClientConfigTest --framework net8.0' 49 | publishTestResults: true 50 | projects: '**/*.Tests.csproj' 51 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium.Net.csproj: -------------------------------------------------------------------------------- 1 | <Project Sdk="Microsoft.NET.Sdk"> 2 | <PropertyGroup> 3 | <TargetFrameworks>netstandard2.0</TargetFrameworks> 4 | <RootNamespace>OpenQA.Selenium</RootNamespace> 5 | <LangVersion>latest</LangVersion> 6 | <Company>Appium Commiters</Company> 7 | <Product>Dotnet-Client</Product> 8 | <PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance> 9 | <GeneratePackageOnBuild>true</GeneratePackageOnBuild> 10 | <Copyright>Copyright © 2023</Copyright> 11 | <PackageProjectUrl>https://appium.io</PackageProjectUrl> 12 | <RepositoryUrl>https://github.com/appium/dotnet-client</RepositoryUrl> 13 | <RepositoryType>git</RepositoryType> 14 | <IncludeSymbols>true</IncludeSymbols> 15 | <SymbolPackageFormat>snupkg</SymbolPackageFormat> 16 | <PublishRepositoryUrl>true</PublishRepositoryUrl> 17 | <PackageId>Appium.WebDriver</PackageId> 18 | <Authors>Appium Commiters</Authors> 19 | <PackageIcon>appium-icon.png</PackageIcon> 20 | <Description>Selenium Webdriver extension for Appium.</Description> 21 | <PackageTags>Appium Webdriver device automation</PackageTags> 22 | <PackageLicenseFile>LICENSE.txt</PackageLicenseFile> 23 | <PackageReadmeFile>README.md</PackageReadmeFile> 24 | <GenerateDocumentationFile>true</GenerateDocumentationFile> 25 | </PropertyGroup> 26 | 27 | <PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|netstandard2.0|AnyCPU'"> 28 | <NoWarn>1701;1702;1591</NoWarn> 29 | </PropertyGroup> 30 | 31 | <PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|netstandard2.0|AnyCPU'"> 32 | <NoWarn>1701;1702;1591</NoWarn> 33 | </PropertyGroup> 34 | 35 | <ItemGroup> 36 | <None Include="LICENSE.txt" Pack="true" PackagePath="" /> 37 | <None Include="appium-icon.png" Pack="true" PackagePath="" /> 38 | <None Include="..\..\README.md" Pack="true" PackagePath="" /> 39 | </ItemGroup> 40 | 41 | <ItemGroup> 42 | <PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0"> 43 | <PrivateAssets>all</PrivateAssets> 44 | <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> 45 | </PackageReference> 46 | <PackageReference Include="Selenium.WebDriver" Version="4.36.0" /> 47 | <PackageReference Include="System.Drawing.Common" Version="8.0.10" /> 48 | </ItemGroup> 49 | </Project> 50 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium.Net.licenseheader: -------------------------------------------------------------------------------- 1 | extensions: .cs .cpp .h 2 | //Licensed under the Apache License, Version 2.0 (the "License"); 3 | //you may not use this file except in compliance with the License. 4 | //See the NOTICE file distributed with this work for additional 5 | //information regarding copyright ownership. 6 | //You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | //Unless required by applicable law or agreed to in writing, software 11 | //distributed under the License is distributed on an "AS IS" BASIS, 12 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | //See the License for the specific language governing permissions and 14 | //limitations under the License. 15 | extensions: .aspx .ascx 16 | <%-- 17 | Licensed under the Apache License, Version 2.0 (the "License"); 18 | you may not use this file except in compliance with the License. 19 | See the NOTICE file distributed with this work for additional 20 | information regarding copyright ownership. 21 | You may obtain a copy of the License at 22 | 23 | http://www.apache.org/licenses/LICENSE-2.0 24 | 25 | Unless required by applicable law or agreed to in writing, software 26 | distributed under the License is distributed on an "AS IS" BASIS, 27 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 28 | See the License for the specific language governing permissions and 29 | limitations under the License. 30 | --%> 31 | extensions: .vb 32 | 'Sample license text. 33 | extensions: .xml .config .xsd 34 | <!-- 35 | Licensed under the Apache License, Version 2.0 (the "License"); 36 | you may not use this file except in compliance with the License. 37 | See the NOTICE file distributed with this work for additional 38 | information regarding copyright ownership. 39 | You may obtain a copy of the License at 40 | 41 | http://www.apache.org/licenses/LICENSE-2.0 42 | 43 | Unless required by applicable law or agreed to in writing, software 44 | distributed under the License is distributed on an "AS IS" BASIS, 45 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 46 | See the License for the specific language governing permissions and 47 | limitations under the License. 48 | --> -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Android/AndroidStopScreenRecordingOptions.cs: -------------------------------------------------------------------------------- 1 | using OpenQA.Selenium.Appium.ScreenRecording; 2 | 3 | namespace OpenQA.Selenium.Appium.Android 4 | { 5 | public class AndroidStopScreenRecordingOptions : BaseStopScreenRecordingOptions<AndroidStopScreenRecordingOptions> 6 | { 7 | public static AndroidStopScreenRecordingOptions StopScreenRecordingOptions() 8 | { 9 | return new AndroidStopScreenRecordingOptions(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Android/Enums/AutomatorSetting.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | namespace OpenQA.Selenium.Appium.Android.Enums 16 | { 17 | public sealed class AutomatorSetting 18 | { 19 | public static readonly string IgnoreUnimportantViews = "ignoreUnimportantViews"; 20 | public static readonly string WaitForIDLETimeout = "waitForIdleTimeout"; 21 | public static readonly string WaitForSelectorTimeout = "waitForSelectorTimeout"; 22 | public static readonly string WaitScrollAcknowledgmentTimeout = "scrollAcknowledgmentTimeout"; 23 | public static readonly string WaitActionAcknowledgmentTimeout = "actionAcknowledgmentTimeout"; 24 | public static readonly string KeyInjectionDelay = "keyInjectionDelay"; 25 | } 26 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Android/Enums/ConnectionType.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | namespace OpenQA.Selenium.Appium.Android 15 | { 16 | /// <summary> 17 | /// Connection Type as described in the JSON Wire Protocol 18 | /// </summary> 19 | public enum ConnectionType 20 | { 21 | None = 0, 22 | AirplaneMode = 1, 23 | WifiOnly = 2, 24 | DataOnly = 4, 25 | AllNetworkOn = 6 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Android/Enums/ListDirection.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | namespace OpenQA.Selenium.Appium.Android.Enums 16 | { 17 | public enum ListDirection 18 | { 19 | Vertical, 20 | Horizontal 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Android/Enums/PerformanceDataType.cs: -------------------------------------------------------------------------------- 1 | namespace OpenQA.Selenium.Appium.Android.Enums 2 | { 3 | public struct PerformanceDataType 4 | { 5 | public static string CpuInfo = "cpuinfo"; 6 | public static string MemoryInfo = "memoryinfo"; 7 | public static string BatteryInfo = "batteryinfo"; 8 | public static string NetworkInfo = "networkinfo"; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Android/Interfaces/IPushesFiles.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using OpenQA.Selenium.Appium.Interfaces; 16 | using System.IO; 17 | 18 | namespace OpenQA.Selenium.Appium.Android.Interfaces 19 | { 20 | public interface IPushesFiles : IInteractsWithFiles 21 | { 22 | /// <summary> 23 | /// Saves a string as a file on the remote mobile device. 24 | /// </summary> 25 | /// <param name="pathOnDevice">Path to file to write data to on remote device</param> 26 | /// <param name="stringData">A string to write to remote device</param> 27 | void PushFile(string pathOnDevice, string stringData); 28 | 29 | /// <summary> 30 | /// Saves base64 encoded data as a file on the remote mobile device. 31 | /// </summary> 32 | /// <param name="pathOnDevice">Path to file to write data to on remote device</param> 33 | /// <param name="base64Data">Base64 encoded byte array of data to write to remote device</param> 34 | void PushFile(string pathOnDevice, byte[] base64Data); 35 | 36 | /// <summary> 37 | /// Saves given file as a file on the remote mobile device. 38 | /// </summary> 39 | /// <param name="pathOnDevice">Path to file to write data to on remote device</param> 40 | /// <param name="file">A file to write to remote device</param> 41 | void PushFile(string pathOnDevice, FileInfo file); 42 | } 43 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Android/Interfaces/IStartsActivity.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using OpenQA.Selenium.Appium.Interfaces; 16 | 17 | namespace OpenQA.Selenium.Appium.Android 18 | { 19 | public interface IStartsActivity : IExecuteMethod 20 | 21 | { 22 | /// <summary> 23 | /// Gets Current Device Activity. 24 | /// </summary> 25 | /// 26 | string CurrentActivity { get; } 27 | } 28 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Android/KeyEvent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using OpenQA.Selenium.Appium.Android.Enums; 4 | 5 | namespace OpenQA.Selenium.Appium.Android 6 | { 7 | public class KeyEvent 8 | { 9 | private int? _keyCode; 10 | private int? _metaState; 11 | private int? _flags; 12 | 13 | public KeyEvent() 14 | { 15 | } 16 | 17 | /// <summary> 18 | /// Creates a new key event 19 | /// </summary> 20 | /// <param name="keyCode">The key code. This is mandatory</param> 21 | /// <see cref="AndroidKeyCode"/> 22 | public KeyEvent(int keyCode) 23 | { 24 | _keyCode = keyCode; 25 | } 26 | 27 | /// <summary> 28 | /// Sets the key code. 29 | /// This is mandatory. 30 | /// </summary> 31 | /// <param name="keyCode">The key code</param> 32 | /// <see cref="AndroidKeyCode"/> 33 | /// <returns></returns> 34 | public KeyEvent WithKeyCode(int keyCode) 35 | { 36 | _keyCode = keyCode; 37 | return this; 38 | } 39 | 40 | /// <summary> 41 | /// Adds the meta key modifier 42 | /// Flags indicating which meta keys are currently pressed. 43 | /// Multiple meta key modifier flags can be combined into a single key event 44 | /// </summary> 45 | /// <param name="keyEventMetaModifier">The meta state</param> 46 | /// <see cref="AndroidKeyMetastate"/> 47 | /// <returns></returns> 48 | public KeyEvent WithMetaKeyModifier(int keyEventMetaModifier) 49 | { 50 | if (_metaState is null) _metaState = 0; 51 | _metaState |= keyEventMetaModifier; 52 | return this; 53 | } 54 | 55 | /// <summary> 56 | /// Adds the flag(s). 57 | /// Multiple flags can be combined into a single key event 58 | /// </summary> 59 | /// <param name="flag">The flag</param> 60 | /// <see cref="AndroidKeyCode"/> 61 | /// <returns></returns> 62 | public KeyEvent WithFlag(int flag) 63 | { 64 | if (_flags is null) _flags = 0; 65 | _flags |= flag; 66 | return this; 67 | } 68 | 69 | public Dictionary<string, object> Build() 70 | { 71 | var builder = new Dictionary<string, object>(); 72 | if (_keyCode is null) throw new InvalidOperationException("The key code must be set"); 73 | builder.Add("keycode", _keyCode); 74 | if (!(_metaState is null)) builder.Add("metastate", _metaState); 75 | if (!(_flags is null)) builder.Add("flags", _flags); 76 | 77 | return builder; 78 | } 79 | } 80 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Android/UiAutomator/TerminatedStatementBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using OpenQA.Selenium.Appium.Interfaces; 3 | 4 | namespace OpenQA.Selenium.Appium.Android.UiAutomator 5 | { 6 | public class TerminatedStatementBuilder : IUiAutomatorStatementBuilder 7 | { 8 | private readonly StringBuilder _builder; 9 | 10 | internal TerminatedStatementBuilder(StringBuilder builder) 11 | { 12 | _builder = builder; 13 | } 14 | 15 | public string Build() 16 | { 17 | return _builder.ToString(); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/AppiumElementFactory.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace OpenQA.Selenium.Appium 3 | { 4 | public class AppiumElementFactory : CachedElementFactory<AppiumElement> 5 | { 6 | public AppiumElementFactory(WebDriver parentDriver) : base(parentDriver) 7 | { 8 | } 9 | 10 | protected override AppiumElement CreateCachedElement(WebDriver parentDriver, string elementId) 11 | { 12 | return new AppiumElement(parentDriver, elementId); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/CachedElementFactory.cs: -------------------------------------------------------------------------------- 1 | using OpenQA.Selenium.Appium.Interfaces; 2 | using System; 3 | using System.Collections.Generic; 4 | 5 | namespace OpenQA.Selenium.Appium 6 | { 7 | public abstract class CachedElementFactory<T> : WebElementFactory where T : WebElement, IWebElementCached 8 | { 9 | public CachedElementFactory(WebDriver parentDriver) : base(parentDriver) 10 | { 11 | } 12 | 13 | protected abstract T CreateCachedElement(WebDriver parentDriver, string elementId); 14 | 15 | public virtual bool CacheElementAttributes 16 | { 17 | get 18 | { 19 | object compactResponses = ParentDriver.Capabilities.GetCapability("shouldUseCompactResponses"); 20 | return compactResponses != null && Convert.ToBoolean(compactResponses) == false; 21 | } 22 | } 23 | 24 | public override WebElement CreateElement(Dictionary<string, object> elementDictionary) 25 | { 26 | string elementId = GetElementId(elementDictionary); 27 | T cachedElement = CreateCachedElement(ParentDriver, elementId); 28 | if (CacheElementAttributes) 29 | { 30 | cachedElement.SetCacheValues(elementDictionary); 31 | } 32 | return cachedElement; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Enums/AppState.cs: -------------------------------------------------------------------------------- 1 | namespace OpenQA.Selenium.Appium.Enums 2 | { 3 | public enum AppState 4 | { 5 | NotInstalled, 6 | NotRunning, 7 | RunningInBackgroundOrSuspended, 8 | RunningInBackground, 9 | RunningInForeground 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Enums/AutomationName.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | namespace OpenQA.Selenium.Appium.Enums 16 | { 17 | public sealed class AutomationName 18 | { 19 | public static readonly string Appium = "Appium"; 20 | public static readonly string iOSXcuiTest = "XCuiTest"; 21 | public static readonly string AndroidUIAutomator2 = "UIAutomator2"; 22 | public static readonly string AndroidEspresso = "Espresso"; 23 | public static readonly string YouiEngine = "youiengine"; 24 | public static readonly string Mac2 = "mac2"; 25 | } 26 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Enums/ClipboardContentType.cs: -------------------------------------------------------------------------------- 1 | namespace OpenQA.Selenium.Appium.Enums 2 | { 3 | public enum ClipboardContentType 4 | { 5 | PlainText, 6 | Image, 7 | Url 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Enums/GsmCallActions.cs: -------------------------------------------------------------------------------- 1 | namespace OpenQA.Selenium.Appium.Enums 2 | { 3 | public enum GsmCallActions 4 | { 5 | Call, 6 | Accept, 7 | Cancel, 8 | Hold 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Enums/GsmSignalStrength.cs: -------------------------------------------------------------------------------- 1 | namespace OpenQA.Selenium.Appium.Enums 2 | { 3 | public enum GsmSignalStrength 4 | { 5 | NoneOrUnknown, 6 | Poor, 7 | Moderate, 8 | Good, 9 | Great 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Enums/GsmVoiceState.cs: -------------------------------------------------------------------------------- 1 | namespace OpenQA.Selenium.Appium.Enums 2 | { 3 | public enum GsmVoiceState 4 | { 5 | Unregistered, 6 | Home, 7 | Roaming, 8 | Searching, 9 | Denied, 10 | Off, 11 | On 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Enums/MobileBrowserType.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | namespace OpenQA.Selenium.Appium.Enums 16 | { 17 | public sealed class MobileBrowserType 18 | { 19 | /// <summary> 20 | /// It is native Android browser. 21 | /// </summary> 22 | public static readonly string Browser = "Browser"; 23 | 24 | public static readonly string Chrome = "Chrome"; 25 | 26 | public static readonly string Chromium = "Chromium"; 27 | 28 | public static readonly string Safari = "Safari"; 29 | } 30 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Enums/MobilePlatform.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | namespace OpenQA.Selenium.Appium.Enums 15 | { 16 | public sealed class MobilePlatform 17 | { 18 | public const string Android = "Android"; 19 | 20 | public const string IOS = "iOS"; 21 | 22 | public const string MacOS = "mac"; 23 | 24 | public const string Windows = "Windows"; 25 | 26 | public const string Tizen = "Tizen"; 27 | 28 | //FireFoxOS and WinPhone will be added when there will be the supporting of appropriate mobile OS. 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Enums/MobileSelector.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | namespace OpenQA.Selenium.Appium.Enums 16 | { 17 | public class MobileSelector 18 | { 19 | 20 | public static readonly string Id = "id"; 21 | public static readonly string ClassName = "class name"; 22 | public static readonly string Name = "name"; 23 | public static readonly string TagName = "tag name"; 24 | public static readonly string Image = "-image"; 25 | public static readonly string Accessibility = "accessibility id"; 26 | public static readonly string AndroidUIAutomator = "-android uiautomator"; 27 | public static readonly string AndroidDataMatcher = "-android datamatcher"; 28 | public static readonly string AndroidViewMatcher = "-android viewmatcher"; 29 | public static readonly string iOSAutomatoion = "-ios uiautomation"; 30 | public static readonly string iOSPredicateString = "-ios predicate string"; 31 | public static readonly string iOSClassChain = "-ios class chain"; 32 | public static readonly string WindowsUIAutomation = "-windows uiautomation"; 33 | public static readonly string TizenUIAutomation = "-tizen uiautomation"; 34 | } 35 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/GuardClauses.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace OpenQA.Selenium.Appium 4 | { 5 | public static class GuardClauses 6 | { 7 | /// <summary> 8 | /// The given value must not be null, otherwise an <see cref="ArgumentNullException"/> 9 | /// will be thrown. 10 | /// </summary> 11 | /// <typeparam name="T"></typeparam> 12 | /// <param name="value">The value to test</param> 13 | /// <param name="paramName"> 14 | /// The name of the parameter which is being checked. This is to help identify 15 | /// the parameter which did not meet the requirement. Use nameof() to ensure 16 | /// proper refactoring support. 17 | /// </param> 18 | public static T RequireNotNull<T>(this T value, string paramName) where T : class 19 | { 20 | return value ?? throw new ArgumentNullException(paramName); 21 | } 22 | 23 | /// <summary> 24 | /// The given value must be greater than or equal to 0 (zero), otherwise 25 | /// an <see cref="ArgumentOutOfRangeException"/> will be thrown. 26 | /// </summary> 27 | /// <param name="value">The value to test</param> 28 | /// <param name="paramName"> 29 | /// The name of the parameter which is being checked. This is to help identify 30 | /// the parameter which did not meet the requirement. Use nameof() to ensure 31 | /// proper refactoring support. 32 | /// </param> 33 | public static int RequireIsPositive(this int value, string paramName) 34 | { 35 | if (value >= 0) 36 | return value; 37 | 38 | throw new ArgumentOutOfRangeException(paramName, "Must be 0 (zero) or greater"); 39 | } 40 | 41 | /// <summary> 42 | /// The given value must be between 0 and 1, otherwise an <see cref="ArgumentOutOfRangeException"/> 43 | /// will be thrown. 44 | /// </summary> 45 | /// <param name="value">The value to test</param> 46 | /// <param name="paramName"> 47 | /// The name of the parameter which is being checked. This is to help identify 48 | /// the parameter which did not meet the requirement. Use nameof() to ensure 49 | /// proper refactoring support. 50 | /// </param> 51 | /// <returns></returns> 52 | public static double RequirePercentage(this double value, string paramName) 53 | { 54 | if (value > 0 && value < 1) 55 | return value; 56 | 57 | throw new ArgumentOutOfRangeException(paramName, "Must be a value between 0 and 1"); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/ImageComparison/ComparisonMode.cs: -------------------------------------------------------------------------------- 1 | namespace OpenQA.Selenium.Appium.ImageComparison 2 | { 3 | public static class ComparisonMode 4 | { 5 | public static string MatchFeatures = "matchFeatures"; 6 | public static string GetSimilarity = "getSimilarity"; 7 | public static string MatchTemplate = "matchTemplate"; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/ImageComparison/ComparisonOptions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace OpenQA.Selenium.Appium.ImageComparison 4 | { 5 | public abstract class ComparisonOptions 6 | { 7 | /// <summary> 8 | /// Makes the endpoint to return an image, 9 | /// which contains the visualized result of the corresponding 10 | /// picture matching operation. This option is disabled by default. 11 | /// </summary> 12 | public bool? Visualize { get; set; } 13 | 14 | public abstract Dictionary<string, object> GetParameters(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/ImageComparison/ComparisonResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.IO; 5 | 6 | namespace OpenQA.Selenium.Appium.ImageComparison 7 | { 8 | public abstract class ComparisonResult 9 | { 10 | /// <summary> 11 | /// The visualization of the matching result represented as base64-encoded PNG image. 12 | /// </summary> 13 | public string Visualization => Result["visualization"].ToString(); 14 | 15 | protected Dictionary<string, object> Result { get; } 16 | 17 | protected ComparisonResult(Dictionary<string, object> result) 18 | { 19 | Result = result; 20 | } 21 | 22 | public void SaveVisualizationAsFile(string fileName) 23 | { 24 | File.WriteAllBytes(fileName, Convert.FromBase64String(Visualization)); 25 | } 26 | 27 | protected Rectangle ConvertToRect(object value) 28 | { 29 | var rect = value as Dictionary<string, object>; 30 | return new Rectangle( 31 | Convert.ToInt32(rect["x"]), 32 | Convert.ToInt32(rect["y"]), 33 | Convert.ToInt32(rect["width"]), 34 | Convert.ToInt32(rect["height"]) 35 | ); 36 | } 37 | 38 | protected List<Point> ConvertToPoint(object value) 39 | { 40 | var points = value as object[]; 41 | var convertedPoints = new List<Point>(); 42 | foreach(var point in points) 43 | { 44 | var currentPoint = point as Dictionary<string, object>; 45 | convertedPoints.Add(new Point( 46 | Convert.ToInt32(currentPoint["x"]), 47 | Convert.ToInt32(currentPoint["y"]) 48 | )); 49 | } 50 | 51 | return convertedPoints; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/ImageComparison/FeaturesMatchingOptions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace OpenQA.Selenium.Appium.ImageComparison 4 | { 5 | public class FeaturesMatchingOptions : ComparisonOptions 6 | { 7 | /// <summary> 8 | /// Sets the detector name for features matching algorithm. 9 | /// Some of these detectors (FAST, AGAST, GFTT, FAST, SIFT and MSER) are not available 10 | /// in the default OpenCV installation and have to be enabled manually before 11 | /// library compilation. The default detector name is 'ORB'. 12 | /// </summary> 13 | public string DetectorName { get; set; } 14 | 15 | /// <summary> 16 | /// The name of the matching function. 17 | /// The default one is 'BruteForce'. 18 | /// </summary> 19 | public string MatchFunc { get; set; } 20 | 21 | /// <summary> 22 | /// The maximum count of "good" matches (e. g. with minimal distances). 23 | /// </summary> 24 | public int? GoodMatchesFactor { get; set; } 25 | 26 | public override Dictionary<string, object> GetParameters() 27 | { 28 | var parameters = new Dictionary<string, object>(); 29 | if (!string.IsNullOrEmpty(DetectorName)) 30 | { 31 | parameters.Add("detectorName", DetectorName); 32 | } 33 | 34 | if (!string.IsNullOrEmpty(MatchFunc)) 35 | { 36 | parameters.Add("matchFunc", MatchFunc); 37 | } 38 | 39 | if (GoodMatchesFactor != null) 40 | { 41 | parameters.Add("goodMatchesFactor", GoodMatchesFactor); 42 | } 43 | 44 | if (Visualize != null) 45 | { 46 | parameters.Add("visualize", Visualize); 47 | } 48 | 49 | return parameters; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/ImageComparison/FeaturesMatchingResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | 5 | namespace OpenQA.Selenium.Appium.ImageComparison 6 | { 7 | public class FeaturesMatchingResult : ComparisonResult 8 | { 9 | /// <summary> 10 | /// The count of matched edges on both images. 11 | /// The more matching edges there are no both images the more similar they are. 12 | /// </summary> 13 | public int Count => Convert.ToInt32(Result["count"]); 14 | 15 | /// <summary> 16 | /// The total count of matched edges on both images. 17 | /// It is equal to `count` if `goodMatchesFactor` does not limit the matches, 18 | /// otherwise it contains the total count of matches before `goodMatchesFactor` 19 | /// is applied. 20 | /// </summary> 21 | public int TotalCount => Convert.ToInt32(Result["totalCount"]); 22 | 23 | /// <summary> 24 | /// The list of matching points on the first image. 25 | /// </summary> 26 | public List<Point> Points1 => ConvertToPoint(Result["points1"]); 27 | 28 | /// <summary> 29 | /// The list of matching points on the second image. 30 | /// </summary> 31 | public List<Point> Points2 => ConvertToPoint(Result["points2"]); 32 | 33 | /// <summary> 34 | /// The bounding rect for the `points1` list or a zero rect if not enough matching points were found. 35 | /// </summary> 36 | public Rectangle Rect1 => ConvertToRect(Result["rect1"]); 37 | 38 | /// <summary> 39 | /// The bounding rect for the `points2` list or a zero rect if not enough matching points were found. 40 | /// </summary> 41 | public Rectangle Rect2 => ConvertToRect(Result["rect2"]); 42 | 43 | public FeaturesMatchingResult(Dictionary<string, object> result) : base(result) 44 | { 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/ImageComparison/OccurenceMatchingOptions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace OpenQA.Selenium.Appium.ImageComparison 4 | { 5 | public class OccurenceMatchingOptions : ComparisonOptions 6 | { 7 | /// <summary> 8 | /// At what normalized threshold to reject an occurrence. 9 | /// Value in range 0..1. 0.5 is the default value. 10 | /// </summary> 11 | public double? Threshold { get; set; } 12 | 13 | public override Dictionary<string, object> GetParameters() 14 | { 15 | var parameters = new Dictionary<string, object>(); 16 | 17 | if (Threshold != null) 18 | { 19 | parameters.Add("threshold", Threshold); 20 | } 21 | 22 | if (Visualize != null) 23 | { 24 | parameters.Add("visualize", Visualize); 25 | } 26 | 27 | return parameters; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/ImageComparison/OccurenceMatchingResult.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Drawing; 3 | 4 | namespace OpenQA.Selenium.Appium.ImageComparison 5 | { 6 | public class OccurenceMatchingResult : ComparisonResult 7 | { 8 | /// <summary> 9 | /// The region of the partial image occurence on the full image. 10 | /// </summary> 11 | public Rectangle Rect => ConvertToRect(Result["rect"]); 12 | 13 | public OccurenceMatchingResult(Dictionary<string, object> result) : base(result) 14 | { 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/ImageComparison/SimilarityMatchingOptions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace OpenQA.Selenium.Appium.ImageComparison 4 | { 5 | public class SimilarityMatchingOptions : ComparisonOptions 6 | { 7 | public override Dictionary<string, object> GetParameters() 8 | { 9 | var parameters = new Dictionary<string, object>(); 10 | 11 | if (Visualize != null) 12 | { 13 | parameters.Add("visualize", Visualize); 14 | } 15 | 16 | return parameters; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/ImageComparison/SimilarityMatchingResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace OpenQA.Selenium.Appium.ImageComparison 5 | { 6 | public class SimilarityMatchingResult : ComparisonResult 7 | { 8 | /// <summary> 9 | /// The similarity score as a float number in range [0.0, 1.0]. 10 | /// 1.0 is the highest score (means both images are totally equal). 11 | /// </summary> 12 | public double Score => Convert.ToDouble(Result["score"]); 13 | 14 | public SimilarityMatchingResult(Dictionary<string, object> result) : base(result) 15 | { 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/Generic/SearchContext/IGenericFindsByClassName.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using OpenQA.Selenium; 16 | using System.Collections.ObjectModel; 17 | 18 | namespace Appium.Interfaces.Generic.SearchContext 19 | { 20 | /// <summary> 21 | /// Defines the interface through which the user finds elements by their CSS class. 22 | /// </summary> 23 | public interface IGenericFindsByClassName<W> where W : IWebElement 24 | { 25 | /// <summary> 26 | /// Finds the first element matching the specified CSS class. 27 | /// </summary> 28 | /// <param name="className">The CSS class to match.</param> 29 | /// <returns>The first <see cref="IWebElement"/> matching the criteria.</returns> 30 | W FindElementByClassName(string className); 31 | 32 | /// <summary> 33 | /// Finds all elements matching the specified CSS class. 34 | /// </summary> 35 | /// <param name="className">The CSS class to match.</param> 36 | /// <returns>A <see cref="ReadOnlyCollection{T}"/> containing all 37 | /// <see cref="IWebElement">IWebElements</see> matching the criteria.</returns> 38 | ReadOnlyCollection<W> FindElementsByClassName(string className); 39 | } 40 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/Generic/SearchContext/IGenericFindsByCssSelector.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using System.Collections.ObjectModel; 16 | using OpenQA.Selenium; 17 | 18 | namespace Appium.Interfaces.Generic.SearchContext 19 | { 20 | /// <summary> 21 | /// Defines the interface through which the user finds elements by their cascading style sheet (CSS) selector. 22 | /// </summary> 23 | public interface IGenericFindsByCssSelector<W> where W : IWebElement 24 | { 25 | /// <summary> 26 | /// Finds the first element matching the specified CSS selector. 27 | /// </summary> 28 | /// <param name="cssSelector">The id to match.</param> 29 | /// <returns>The first <see cref="IWebElement"/> matching the criteria.</returns> 30 | W FindElementByCssSelector(string cssSelector); 31 | 32 | /// <summary> 33 | /// Finds all elements matching the specified CSS selector. 34 | /// </summary> 35 | /// <param name="cssSelector">The CSS selector to match.</param> 36 | /// <returns>A <see cref="ReadOnlyCollection{T}"/> containing all 37 | /// <see cref="IWebElement">IWebElements</see> matching the criteria.</returns> 38 | ReadOnlyCollection<W> FindElementsByCssSelector(string cssSelector); 39 | } 40 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/Generic/SearchContext/IGenericFindsById.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using OpenQA.Selenium; 16 | using System.Collections.ObjectModel; 17 | 18 | namespace Appium.Interfaces.Generic.SearchContext 19 | { 20 | /// <summary> 21 | /// Defines the interface through which the user finds elements by their ID. 22 | /// </summary> 23 | public interface IGenericFindsById<W> where W : IWebElement 24 | { 25 | /// <summary> 26 | /// Finds the first element matching the specified id. 27 | /// </summary> 28 | /// <param name="id">The id to match.</param> 29 | /// <returns>The first <see cref="IWebElement"/> matching the criteria.</returns> 30 | W FindElementById(string id); 31 | 32 | /// <summary> 33 | /// Finds all elements matching the specified id. 34 | /// </summary> 35 | /// <param name="id">The id to match.</param> 36 | /// <returns>A <see cref="ReadOnlyCollection{T}"/> containing all 37 | /// <see cref="IWebElement">IWebElements</see> matching the criteria.</returns> 38 | ReadOnlyCollection<W> FindElementsById(string id); 39 | } 40 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/Generic/SearchContext/IGenericFindsByLinkText.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using OpenQA.Selenium; 16 | using System.Collections.ObjectModel; 17 | 18 | namespace Appium.Interfaces.Generic.SearchContext 19 | { 20 | /// <summary> 21 | /// Defines the interface through which the user finds elements by their link text. 22 | /// </summary> 23 | public interface IGenericFindsByLinkText<W> where W : IWebElement 24 | { 25 | /// <summary> 26 | /// Finds the first element matching the specified link text. 27 | /// </summary> 28 | /// <param name="linkText">The link text to match.</param> 29 | /// <returns>The first <see cref="IWebElement"/> matching the criteria.</returns> 30 | W FindElementByLinkText(string linkText); 31 | 32 | /// <summary> 33 | /// Finds all elements matching the specified link text. 34 | /// </summary> 35 | /// <param name="linkText">The link text to match.</param> 36 | /// <returns>A <see cref="ReadOnlyCollection{T}"/> containing all 37 | /// <see cref="IWebElement">IWebElements</see> matching the criteria.</returns> 38 | ReadOnlyCollection<W> FindElementsByLinkText(string linkText); 39 | } 40 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/Generic/SearchContext/IGenericFindsByName.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using OpenQA.Selenium; 16 | using System.Collections.ObjectModel; 17 | 18 | namespace Appium.Interfaces.Generic.SearchContext 19 | { 20 | /// <summary> 21 | /// Defines the interface through which the user finds elements by their name. 22 | /// </summary> 23 | public interface IGenericFindsByName<W> where W : IWebElement 24 | { 25 | /// <summary> 26 | /// Finds the first element matching the specified name. 27 | /// </summary> 28 | /// <param name="name">The name to match.</param> 29 | /// <returns>The first <see cref="IWebElement"/> matching the criteria.</returns> 30 | W FindElementByName(string name); 31 | 32 | /// <summary> 33 | /// Finds all elements matching the specified name. 34 | /// </summary> 35 | /// <param name="name">The name to match.</param> 36 | /// <returns>A <see cref="ReadOnlyCollection{T}"/> containing all 37 | /// <see cref="IWebElement">IWebElements</see> matching the criteria.</returns> 38 | ReadOnlyCollection<W> FindElementsByName(string name); 39 | } 40 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/Generic/SearchContext/IGenericFindsByPartialLinkText.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using OpenQA.Selenium; 16 | using System.Collections.ObjectModel; 17 | 18 | namespace Appium.Interfaces.Generic.SearchContext 19 | { 20 | /// <summary> 21 | /// Defines the interface through which the user finds elements by a partial match on their link text. 22 | /// </summary> 23 | public interface IGenericFindsByPartialLinkText<W> where W : IWebElement 24 | { 25 | /// <summary> 26 | /// Finds the first element matching the specified partial link text. 27 | /// </summary> 28 | /// <param name="partialLinkText">The partial link text to match.</param> 29 | /// <returns>The first <see cref="IWebElement"/> matching the criteria.</returns> 30 | W FindElementByPartialLinkText(string partialLinkText); 31 | 32 | /// <summary> 33 | /// Finds all elements matching the specified partial link text. 34 | /// </summary> 35 | /// <param name="partialLinkText">The partial link text to match.</param> 36 | /// <returns>A <see cref="ReadOnlyCollection{T}"/> containing all 37 | /// <see cref="IWebElement">IWebElements</see> matching the criteria.</returns> 38 | ReadOnlyCollection<W> FindElementsByPartialLinkText(string partialLinkText); 39 | } 40 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/Generic/SearchContext/IGenericFindsByTagName.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using OpenQA.Selenium; 16 | using System.Collections.ObjectModel; 17 | 18 | namespace Appium.Interfaces.Generic.SearchContext 19 | { 20 | /// <summary> 21 | /// Defines the interface through which the user finds elements by their tag name. 22 | /// </summary> 23 | public interface IGenericFindsByTagName<W> where W : IWebElement 24 | { 25 | /// <summary> 26 | /// Finds the first element matching the specified tag name. 27 | /// </summary> 28 | /// <param name="tagName">The tag name to match.</param> 29 | /// <returns>The first <see cref="IWebElement"/> matching the criteria.</returns> 30 | W FindElementByTagName(string tagName); 31 | 32 | /// <summary> 33 | /// Finds all elements matching the specified tag name. 34 | /// </summary> 35 | /// <param name="tagName">The tag name to match.</param> 36 | /// <returns>A <see cref="ReadOnlyCollection{T}"/> containing all 37 | /// <see cref="IWebElement">IWebElements</see> matching the criteria.</returns> 38 | ReadOnlyCollection<W> FindElementsByTagName(string tagName); 39 | } 40 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/Generic/SearchContext/IGenericFindsByXPath.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using OpenQA.Selenium; 16 | using System.Collections.ObjectModel; 17 | 18 | namespace Appium.Interfaces.Generic.SearchContext 19 | { 20 | /// <summary> 21 | /// Defines the interface through which the user finds elements by XPath. 22 | /// </summary> 23 | public interface IGenericFindsByXPath<W> where W : IWebElement 24 | { 25 | /// <summary> 26 | /// Finds the first element matching the specified XPath query. 27 | /// </summary> 28 | /// <param name="xpath">The XPath query to match.</param> 29 | /// <returns>The first <see cref="IWebElement"/> matching the criteria.</returns> 30 | W FindElementByXPath(string xpath); 31 | 32 | /// <summary> 33 | /// Finds all elements matching the specified XPath query. 34 | /// </summary> 35 | /// <param name="xpath">The XPath query to match.</param> 36 | /// <returns>A <see cref="ReadOnlyCollection{T}"/> containing all 37 | /// <see cref="IWebElement">IWebElements</see> matching the criteria.</returns> 38 | ReadOnlyCollection<W> FindElementsByXPath(string xpath); 39 | } 40 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/Generic/SearchContext/IGenericSearchContext.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using OpenQA.Selenium; 16 | using System.Collections.ObjectModel; 17 | 18 | namespace Appium.Interfaces.Generic.SearchContext 19 | { 20 | /// <summary> 21 | /// Defines the interface used to search for elements. 22 | /// </summary> 23 | public interface IGenericSearchContext<W> where W : IWebElement 24 | { 25 | /// <summary> 26 | /// Finds the first <see cref="IWebElement"/> using the given method. 27 | /// </summary> 28 | /// <param name="by">The locating mechanism to use.</param> 29 | /// <returns>The first matching <see cref="IWebElement"/> on the current context.</returns> 30 | /// <exception cref="NoSuchElementException">If no element matches the criteria.</exception> 31 | W FindElement(By by); 32 | 33 | /// <summary> 34 | /// Finds all <see cref="IWebElement">IWebElements</see> within the current context 35 | /// using the given mechanism. 36 | /// </summary> 37 | /// <param name="by">The locating mechanism to use.</param> 38 | /// <returns>A <see cref="ReadOnlyCollection{T}"/> of all <see cref="IWebElement">WebElements</see> 39 | /// matching the current criteria, or an empty list if nothing matches.</returns> 40 | ReadOnlyCollection<W> FindElements(By by); 41 | } 42 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/IContextAware.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using System.Collections.ObjectModel; 16 | 17 | 18 | namespace OpenQA.Selenium.Appium.Interfaces 19 | { 20 | /// <summary> 21 | /// Some implementations of WebDriver, notably those that support native testing, need the ability 22 | /// to switch between the native and web-based contexts. This can be achieved by using this 23 | /// interface. 24 | /// </summary> 25 | public interface IContextAware 26 | { 27 | /// <summary> 28 | /// Switches the focus of future commands for this driver to the context with the given name 29 | /// AND 30 | /// returns an opaque handle to this context that uniquely identifies it within this driver 31 | /// instance. 32 | /// </summary> 33 | string Context { get; set; } 34 | 35 | /// <summary> 36 | /// Return a list of context handles which can be used to iterate over all contexts of this 37 | /// WebDriver instance 38 | /// </summary> 39 | ReadOnlyCollection<string> Contexts { get; } 40 | } 41 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/IExecuteMethod.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using System.Collections.Generic; 16 | 17 | namespace OpenQA.Selenium.Appium.Interfaces 18 | { 19 | public interface IExecuteMethod 20 | { 21 | /// <summary> 22 | /// Execute a command on the remote server. 23 | /// </summary> 24 | /// <param name="commandName">A remote command</param> 25 | /// <param name="parameters">Parameters to execute</param> 26 | /// <returns>The result</returns> 27 | Response Execute(string commandName, Dictionary<string, object> parameters); 28 | 29 | /// <summary> 30 | /// Execute a command on the remote server. 31 | /// </summary> 32 | /// <param name="driverCommand">A remote command</param> 33 | Response Execute(string driverCommand); 34 | } 35 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/IFindByAccessibilityId.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using System.Collections.Generic; 16 | 17 | namespace OpenQA.Selenium.Appium.Interfaces 18 | { 19 | public interface IFindByAccessibilityId<out W> : IFindsByFluentSelector<W> where W : IWebElement 20 | { 21 | /// <summary> 22 | /// Finds the first of elements that match the Accessibility Id selector supplied 23 | /// </summary> 24 | /// <param name="selector">an Accessibility Id selector</param> 25 | /// <returns>IWebElement object so that you can interact that object</returns> 26 | W FindElementByAccessibilityId(string selector); 27 | 28 | /// <summary> 29 | /// Finds a list of elements that match the Accessibility Id selector supplied 30 | /// </summary> 31 | /// <param name="selector">an Accessibility Id selector</param> 32 | /// <returns>IWebElement object so that you can interact that object</returns> 33 | IReadOnlyCollection<W> FindElementsByAccessibilityId(string selector); 34 | } 35 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/IFindByAndroidDataMatcher.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using System.Collections.Generic; 16 | 17 | namespace OpenQA.Selenium.Appium.Interfaces 18 | { 19 | public interface IFindByAndroidDataMatcher<out W> : IFindsByFluentSelector<W> where W : IWebElement 20 | { 21 | /// <summary> 22 | /// Finds the first element in the page that matches the Android Espresso's Data Matcher selector supplied 23 | /// </summary> 24 | /// <param name="selector">Selector for the element.</param> 25 | /// <returns>IWebElement object so that you can interact that object</returns> 26 | /// <example> 27 | /// <code> 28 | /// IWebDriver driver = new WebDriver(new DriverOptions()); 29 | /// IWebElement elem = driver.FindElementByAndroidDataMatcher('elements()')) 30 | /// </code> 31 | /// </example> 32 | W FindElementByAndroidDataMatcher(string selector); 33 | 34 | /// <summary> 35 | /// Finds a list of elements that match the Android Espresso's Data Matcher selector supplied 36 | /// </summary> 37 | /// <param name="selector">Selector for the elements.</param> 38 | /// <returns>ReadOnlyCollection of IWebElement object so that you can interact with those objects</returns> 39 | /// <example> 40 | /// <code> 41 | /// IWebDriver driver = new WebDriver(new FirefoxOptions()); 42 | /// ReadOnlyCollection<![CDATA[<IWebElement>]]> elem = driver.FindElementsByAndroidDataMatcher(elements()) 43 | /// </code> 44 | /// </example> 45 | IReadOnlyCollection<W> FindElementsByAndroidDataMatcher(string selector); 46 | } 47 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/IFindByAndroidViewMatcher.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using System.Collections.Generic; 16 | 17 | namespace OpenQA.Selenium.Appium.Interfaces 18 | { 19 | public interface IFindByAndroidViewMatcher<out W> : IFindsByFluentSelector<W> where W : IWebElement 20 | { 21 | /// <summary> 22 | /// Finds the first element in the page that matches the Android Espresso's View Matcher selector supplied 23 | /// </summary> 24 | /// <param name="selector">Selector for the element.</param> 25 | /// <returns>IWebElement object so that you can interact that object</returns> 26 | /// <example> 27 | /// <code> 28 | /// IWebDriver driver = new WebDriver(new DriverOptions()); 29 | /// IWebElement elem = driver.FindElementByAndroidViewMatcher('elements()')) 30 | /// </code> 31 | /// </example> 32 | W FindElementByAndroidViewMatcher(string selector); 33 | 34 | /// <summary> 35 | /// Finds a list of elements that match the Android Espresso's View Matcher selector supplied 36 | /// </summary> 37 | /// <param name="selector">Selector for the elements.</param> 38 | /// <returns>ReadOnlyCollection of IWebElement object so that you can interact with those objects</returns> 39 | /// <example> 40 | /// <code> 41 | /// IWebDriver driver = new WebDriver(new FirefoxOptions()); 42 | /// ReadOnlyCollection<![CDATA[<IWebElement>]]> elem = driver.FindElementsByAndroidViewMatcher(elements()) 43 | /// </code> 44 | /// </example> 45 | IReadOnlyCollection<W> FindElementsByAndroidViewMatcher(string selector); 46 | } 47 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/IFindByTizenUIAutomation.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using System.Collections.Generic; 16 | 17 | namespace OpenQA.Selenium.Appium.Interfaces 18 | { 19 | public interface IFindByTizenUIAutomation<out W> : IFindsByFluentSelector<W> where W : IWebElement 20 | { 21 | /// <summary> 22 | /// Finds the first of elements that match the Tizen UIAutomation selector supplied 23 | /// </summary> 24 | /// <param name="selector">a Tizen UIAutomation selector</param> 25 | /// <returns>IWebElement object so that you can interact that object</returns> 26 | W FindElementByTizenUIAutomation(string selector); 27 | 28 | /// <summary> 29 | /// Finds a list of elements that match the Tizen UIAutomation selector supplied 30 | /// </summary> 31 | /// <param name="selector">a Tizen UIAutomation selector</param> 32 | /// <returns>ReadOnlyCollection of IWebElement objects so that you can interact with those objects</returns> 33 | IReadOnlyCollection<W> FindElementsByTizenUIAutomation(string selector); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/IFindByWindowsUIAutomation.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using System.Collections.Generic; 16 | 17 | namespace OpenQA.Selenium.Appium.Interfaces 18 | { 19 | public interface IFindByWindowsUIAutomation<out W> : IFindsByFluentSelector<W> where W : IWebElement 20 | { 21 | /// <summary> 22 | /// Finds the first of elements that match the Windows UIAutomation selector supplied 23 | /// </summary> 24 | /// <param name="selector">a Windows UIAutomation selector</param> 25 | /// <returns>IWebElement object so that you can interact that object</returns> 26 | W FindElementByWindowsUIAutomation(string selector); 27 | 28 | /// <summary> 29 | /// Finds a list of elements that match the Windows UIAutomation selector supplied 30 | /// </summary> 31 | /// <param name="selector">a Windows UIAutomation selector</param> 32 | /// <returns>ReadOnlyCollection of IWebElement objects so that you can interact with those objects</returns> 33 | IReadOnlyCollection<W> FindElementsByWindowsUIAutomation(string selector); 34 | } 35 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/IFindsByFluentSelector.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using System.Collections.Generic; 16 | 17 | namespace OpenQA.Selenium.Appium.Interfaces 18 | { 19 | public interface IFindsByFluentSelector<out W> where W : IWebElement 20 | { 21 | /// <summary> 22 | /// Method performs the searching for a single element by some selector defined by string 23 | /// and value of the given selector 24 | /// </summary> 25 | /// <param name="by">is a string selector</param> 26 | /// <param name="value">is a value of the given selector</param> 27 | /// <returns>the first found element</returns> 28 | W FindElement(string by, string value); 29 | 30 | /// <summary> 31 | /// Method performs the searching for a list of elements by some selector defined by string 32 | /// and value of the given selector 33 | /// </summary> 34 | /// <param name="selector">is a string selector</param> 35 | /// <param name="value">is a value of the given selector</param> 36 | /// <returns>a list of elements</returns> 37 | IReadOnlyCollection<W> FindElements(string selector, string value); 38 | } 39 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/IFindsByIosClassChain.cs: -------------------------------------------------------------------------------- 1 | //you may not use this file except in compliance with the License. 2 | //See the NOTICE file distributed with this work for additional 3 | //information regarding copyright ownership. 4 | //You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | //Unless required by applicable law or agreed to in writing, software 9 | //distributed under the License is distributed on an "AS IS" BASIS, 10 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | //See the License for the specific language governing permissions and 12 | //limitations under the License. 13 | 14 | using System.Collections.Generic; 15 | 16 | namespace OpenQA.Selenium.Appium.Interfaces 17 | { 18 | public interface IFindsByIosClassChain<out W> : IFindsByFluentSelector<W> where W : IWebElement 19 | { 20 | /// <summary> 21 | /// Finds the first of elements that match the IosClassChain selector supplied 22 | /// </summary> 23 | /// <param name="selector">an IosClassChain selector</param> 24 | /// <returns>IWebElement object so that you can interact that object</returns> 25 | W FindElementByIosClassChain(string selector); 26 | 27 | /// <summary> 28 | /// Finds a list of elements that match the IosClassChain selector supplied 29 | /// </summary> 30 | /// <param name="selector">an IosClassChain selector</param> 31 | /// <returns>ReadOnlyCollection of IWebElement objects so that you can interact with those objects</returns> 32 | IReadOnlyCollection<W> FindElementsByIosClassChain(string selector); 33 | } 34 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/IFindsByIosNSPredicate.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using System.Collections.Generic; 16 | 17 | namespace OpenQA.Selenium.Appium.Interfaces 18 | { 19 | public interface IFindsByIosNSPredicate<out W> : IFindsByFluentSelector<W> where W : IWebElement 20 | { 21 | /// <summary> 22 | /// Finds the first of elements that match the IosNsPredicate selector supplied 23 | /// </summary> 24 | /// <param name="selector">an IosNsPredicate selector</param> 25 | /// <returns>IWebElement object so that you can interact that object</returns> 26 | W FindElementByIosNsPredicate(string selector); 27 | 28 | /// <summary> 29 | /// Finds a list of elements that match the IosNsPredicate selector supplied 30 | /// </summary> 31 | /// <param name="selector">an IosNsPredicate selector</param> 32 | /// <returns>ReadOnlyCollection of IWebElement objects so that you can interact with those objects</returns> 33 | IReadOnlyCollection<W> FindElementsByIosNsPredicate(string selector); 34 | } 35 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/IHasLocation.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * CHANGE LOG - keep only last 5 threads 3 | * 4 | * on-line resources 5 | */ 6 | namespace OpenQA.Selenium.Appium.Interfaces 7 | { 8 | /// <summary> 9 | /// Describes a contract by which you can get or set a GPS location on a mobile device. 10 | /// </summary> 11 | public interface IHasLocation 12 | { 13 | /// <summary> 14 | /// Gets or sets the GPS location of this mobile device. 15 | /// </summary> 16 | Location Location { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/IHasSessionDetails.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace OpenQA.Selenium.Appium.Interfaces 4 | { 5 | public interface IHasSessionDetails 6 | { 7 | /// <summary> 8 | /// a dictionary of values that hold session details. 9 | /// </summary> 10 | IDictionary<string, object> SessionDetails { get; } 11 | 12 | /// <summary> 13 | /// This property returns a certain session detail by it key 14 | /// or null if there is no such detail. 15 | /// </summary> 16 | /// <param name="detail"> is the detail key-name</param> 17 | /// <returns>an object of null if there is no such detail</returns> 18 | object GetSessionDetail(string detail); 19 | 20 | /// <summary> 21 | /// This property returns a name of the mobile plathorm of the current 22 | /// session. 23 | /// </summary> 24 | string PlatformName { get; } 25 | 26 | /// <summary> 27 | /// This property returns a name of the automation type of the current 28 | /// session. 29 | /// </summary> 30 | string AutomationName { get; } 31 | 32 | /// <summary> 33 | /// This property should return <code>true</code> when 34 | /// user's code is currently works on browser or web view. 35 | /// <code>false</code> should be returned otherwice. 36 | /// </summary> 37 | bool IsBrowser{ get; } 38 | } 39 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/IHidesKeyboard.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * See the NOTICE file distributed with this work for additional 5 | * information regarding copyright ownership. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | namespace OpenQA.Selenium.Appium.Interfaces 18 | { 19 | /// <summary> 20 | /// Represents an interface for interacting with device keyboards. 21 | /// </summary> 22 | public interface IHidesKeyboard 23 | { 24 | /// <summary> 25 | /// Hides the device keyboard. 26 | /// </summary> 27 | void HideKeyboard(); 28 | 29 | /// <summary> 30 | /// Hides the device keyboard. 31 | /// </summary> 32 | /// <param name="key">The button pressed by the mobile driver to attempt hiding the keyboard.</param> 33 | void HideKeyboard(string key); 34 | 35 | /// <summary> 36 | /// Determines whether the soft keyboard is currently shown. 37 | /// </summary> 38 | /// <returns>True if the keyboard is shown; otherwise, false.</returns> 39 | bool IsKeyboardShown(); 40 | } 41 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/IHidesKeyboardWithKeyName.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | namespace OpenQA.Selenium.Appium.Interfaces 16 | { 17 | /// <summary> 18 | /// Represents an interface for hiding the keyboard with a specific key name. 19 | /// </summary> 20 | public interface IHidesKeyboardWithKeyName : IHidesKeyboard 21 | { 22 | /// <summary> 23 | /// Hides the keyboard if it is showing. Hiding the keyboard often 24 | /// depends on the way an app is implemented. 25 | /// </summary> 26 | /// <param name="key">a String, representing the text displayed on the button of the 27 | /// keyboard you want to press. For example: "Done". 28 | /// </param> 29 | new void HideKeyboard(string key); 30 | } 31 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/IInteractsWithFiles.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | namespace OpenQA.Selenium.Appium.Interfaces 16 | { 17 | public interface IInteractsWithFiles : IExecuteMethod 18 | { 19 | /// <summary> 20 | /// Pulls a File. 21 | /// </summary> 22 | /// <param name="pathOnDevice">path on device to pull</param> 23 | byte[] PullFile(string pathOnDevice); 24 | 25 | /// <summary> 26 | /// Pulls a Folder 27 | /// </summary> 28 | /// <param name="remotePath">remote path to the folder to return</param> 29 | /// <returns>a base64 encoded string representing a zip file of the contents of the folder</returns> 30 | byte[] PullFolder(string remotePath); 31 | } 32 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/IMobileElement.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | namespace OpenQA.Selenium.Appium.Interfaces 16 | { 17 | /// <summary> 18 | /// This interface extends IWebElement and defines specific behavior 19 | /// for mobile. 20 | /// </summary> 21 | public interface IMobileElement : IWebElement, IExecuteMethod 22 | { 23 | } 24 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/IMultiAction.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using System.Collections.Generic; 16 | 17 | namespace OpenQA.Selenium.Appium.Interfaces 18 | { 19 | public interface IMultiAction 20 | { 21 | /// <summary> 22 | /// Add touch actions to be performed 23 | /// </summary> 24 | /// <param name="touchAction">An <see cref="ITouchAction"/> object that represents a single touch action.</param> 25 | IMultiAction Add(ITouchAction touchAction); 26 | 27 | /// <summary> 28 | /// Cancels the Multi Action 29 | /// </summary> 30 | void Cancel(); 31 | 32 | /// <summary> 33 | /// Performs the Multi Action 34 | /// </summary> 35 | void Perform(); 36 | 37 | /// <summary> 38 | /// Gets the actions parameter dictionary for this multi touch action 39 | /// </summary> 40 | /// <returns>empty dictionary if no actions found, else dictionary of actions</returns> 41 | Dictionary<string, object> GetParameters(); 42 | } 43 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/INetworkActions.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using OpenQA.Selenium.Appium.Enums; 16 | 17 | namespace OpenQA.Selenium.Appium.Interfaces 18 | { 19 | public interface INetworkActions 20 | { 21 | /// <summary> 22 | /// Switch the state of the location service 23 | /// </summary> 24 | void ToggleLocationServices(); 25 | 26 | /// <summary> 27 | /// Make GSM call (Emulator only) 28 | /// </summary> 29 | /// <param name="phoneNumber">The string that represents phone number.</param> 30 | /// <param name="gsmCallAction">The <see cref="GsmCallActions"/> GSM call action.</param> 31 | void MakeGsmCall(string phoneNumber, GsmCallActions gsmCallAction); 32 | 33 | /// <summary> 34 | /// Simulate an SMS message (Emulator only) 35 | /// </summary> 36 | /// <param name="phoneNumber">The string that represents phone number. </param> 37 | /// <param name="message">The string that represents message. </param> 38 | void SendSms(string phoneNumber, string message); 39 | 40 | /// <summary> 41 | /// Sets GSM signal strength (Emulator only) 42 | /// </summary> 43 | /// <param name="gsmSignalStrength">The <see cref="GsmSignalStrength"/> GSM signal strength to be set on the emulator.</param> 44 | void SetGsmSignalStrength(GsmSignalStrength gsmSignalStrength); 45 | 46 | /// <summary> 47 | /// Set GSM voice state (Emulator only) 48 | /// </summary> 49 | /// <param name="gsmVoiceState">The <see cref="GsmVoiceState"/> GSM voice state to be set on the emulator.</param> 50 | void SetGsmVoice(GsmVoiceState gsmVoiceState); 51 | } 52 | } 53 | 54 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/IScreenRecordingOptions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace OpenQA.Selenium.Appium.Interfaces 4 | { 5 | public interface IScreenRecordingOptions 6 | { 7 | Dictionary<string, object> GetParameters(); 8 | } 9 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/ISendsKeyEvents.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | 16 | using OpenQA.Selenium.Appium.Android; 17 | 18 | namespace OpenQA.Selenium.Appium.Interfaces 19 | { 20 | public interface ISendsKeyEvents : IExecuteMethod 21 | { 22 | /// <summary> 23 | /// Sends a device key event with meta state 24 | /// </summary> 25 | /// <param name="keyCode">Code for the long key pressed on the Android device</param> 26 | /// <param name="metastate">metastate for the long key press</param> 27 | void PressKeyCode(int keyCode, int metastate = 0); 28 | 29 | /// <summary> 30 | /// Sends a device long key event with meta state 31 | /// </summary> 32 | /// <param name="keyCode">Code for the long key pressed on the Android device</param> 33 | /// <param name="metastate">metastate for the long key press</param> 34 | void LongPressKeyCode(int keyCode, int metastate = 0); 35 | 36 | /// <summary> 37 | /// Sends a key event to the device under test 38 | /// </summary> 39 | /// <param name="keyEvent">The generated key event <see cref="KeyEvent"/></param> 40 | void PressKeyCode(KeyEvent keyEvent); 41 | 42 | /// <summary> 43 | /// Sends a long press key event to the device under test 44 | /// </summary> 45 | /// <param name="keyEvent">The generated key event <see cref="KeyEvent"/></param> 46 | void LongPressKeyCode(KeyEvent keyEvent); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/IUiAutomatorStatementBuilder.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | namespace OpenQA.Selenium.Appium.Interfaces 16 | { 17 | public interface IUiAutomatorStatementBuilder 18 | { 19 | string Build(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Interfaces/IWebElementCached.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using System.Collections.Generic; 16 | 17 | namespace OpenQA.Selenium.Appium.Interfaces 18 | { 19 | /// <summary> 20 | /// This interface extends IWebElement and adds caching support. 21 | /// To enable caching at the driver level, set the shouldUseCompactResponses capability: 22 | /// shouldUseCompactResponses: true 23 | /// To specify the attributes to be cached, set the elementResponseAttributes capability: 24 | /// elementResponseAttributes: "name,text,rect,attribute/name,attribute/value" 25 | /// Note: the cache uses W3C names for attributes. 26 | /// For TagName, use "name" 27 | /// For Size, Location use "rect" 28 | /// </summary> 29 | public interface IWebElementCached : IWebElement 30 | { 31 | /// <summary> 32 | /// Replace any existing values in the cache with the supplied values. 33 | /// The cache is enabled for this element. 34 | /// <param name="cacheValues">The new cache values</param> 35 | /// </summary> 36 | void SetCacheValues(Dictionary<string, object> cacheValues); 37 | 38 | /// <summary> 39 | /// Disable the cache for this element. 40 | /// </summary> 41 | void DisableCache(); 42 | 43 | /// <summary> 44 | /// Clear all values from the cache. 45 | /// </summary> 46 | void ClearCache(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Location.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using System.Collections.Generic; 16 | 17 | namespace OpenQA.Selenium.Appium 18 | { 19 | public class Location 20 | { 21 | public Location() 22 | { 23 | Latitude = 0.0; 24 | Longitude = 0.0; 25 | Altitude = 0.0; 26 | } 27 | 28 | public double Latitude { get; set; } 29 | 30 | public double Longitude { get; set; } 31 | 32 | public double Altitude { get; set; } 33 | 34 | public Dictionary<string, object> ToDictionary() 35 | { 36 | var parameters = new Dictionary<string, object>() 37 | { 38 | ["latitude"] = Latitude, 39 | ["longitude"] = Longitude, 40 | ["altitude"] = Altitude 41 | }; 42 | var location = new Dictionary<string, object>() 43 | {["location"] = parameters}; 44 | return location; 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/ScreenOrientationExtensions.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using System; 16 | 17 | namespace OpenQA.Selenium.Appium 18 | { 19 | /// <summary> 20 | /// Extension methods to convert to/from ScreenOrientation enum 21 | /// </summary> 22 | public static class ScreenOrientationExtensions 23 | { 24 | /// <summary> 25 | /// Converts the Screen Orientation to the string needed by the JSON Wire Protocol 26 | /// </summary> 27 | /// <param name="orientation">An <see cref="ScreenOrientation"/> object represents possible screen orientations.</param> 28 | /// <returns></returns> 29 | public static string JSONWireProtocolString(this ScreenOrientation orientation) => 30 | orientation.ToString().ToUpperInvariant(); 31 | 32 | /// <summary> 33 | /// Converts the string to a screen orientation if possible, else throws ArgumentOutOfRangeException 34 | /// </summary> 35 | /// <param name="orientation">A string that represents possible screen orientations.</param> 36 | /// <returns>Screen Orientation</returns> 37 | public static ScreenOrientation ConvertToScreenOrientation(this string orientation) 38 | { 39 | ScreenOrientation retVal = ScreenOrientation.Landscape; 40 | switch (orientation) 41 | { 42 | case "PORTRAIT": 43 | retVal = ScreenOrientation.Portrait; 44 | break; 45 | case "LANDSCAPE": 46 | retVal = ScreenOrientation.Landscape; 47 | break; 48 | default: 49 | throw new ArgumentOutOfRangeException("Unknown Orientation Type Passed in"); 50 | } 51 | return retVal; 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/ScreenRecording/BaseScreenRecordingOptions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using OpenQA.Selenium.Appium.Interfaces; 3 | 4 | namespace OpenQA.Selenium.Appium.ScreenRecording 5 | { 6 | public abstract class BaseScreenRecordingOptions<T> : IScreenRecordingOptions where T : BaseScreenRecordingOptions<T> 7 | { 8 | protected Dictionary<string, object> Parameters; 9 | 10 | protected BaseScreenRecordingOptions() 11 | { 12 | Parameters = new Dictionary<string, object>(); 13 | } 14 | 15 | /// <summary> 16 | /// Upload options set for the recorded screen capture. 17 | /// </summary> 18 | /// <param name="uploadOptions">Upload options</param> 19 | /// <returns></returns> 20 | public T WithUploadOptions(ScreenRecordingUploadOptions uploadOptions) 21 | { 22 | foreach (var parameter in uploadOptions.GetParameters()) 23 | { 24 | Parameters[parameter.Key] = parameter.Value; 25 | } 26 | 27 | return (T) this; 28 | } 29 | 30 | /// <summary> 31 | /// Get all setted parameters 32 | /// </summary> 33 | /// <returns></returns> 34 | public Dictionary<string, object> GetParameters() 35 | { 36 | return Parameters; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/ScreenRecording/BaseStartScreenRecordingOptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | 4 | namespace OpenQA.Selenium.Appium.ScreenRecording 5 | { 6 | public abstract class BaseStartScreenRecordingOptions<T> : BaseScreenRecordingOptions<T> 7 | where T : BaseStartScreenRecordingOptions<T> 8 | { 9 | /// <summary> 10 | /// The maximum recording time. 11 | /// </summary> 12 | /// <param name="timeLimit">The actual time limit of the recorded video.</param> 13 | /// <returns>self instance for chaining.</returns> 14 | public T WithTimeLimit(TimeSpan timeLimit) 15 | { 16 | Parameters["timeLimit"] = (int)timeLimit.TotalSeconds;; 17 | return (T) this; 18 | } 19 | 20 | /// <summary> 21 | /// Whether to ignore the result of previous capture and start a new recording 22 | /// immediately. By default the endpoint will try to catch and return the result of 23 | /// the previous capture if it's still available. 24 | /// </summary> 25 | /// <returns>self instance for chaining.</returns> 26 | public T EnableForcedRestart() 27 | { 28 | Parameters["forceRestart"] = true; 29 | return (T) this; 30 | } 31 | 32 | /// <summary> 33 | /// The remotePath upload option is the path to the remote location, 34 | /// where the resulting video should be uploaded. 35 | /// The following protocols are supported: http/https (multipart), ftp. 36 | /// 37 | /// Missing value (the default setting) means the content of the resulting 38 | /// file should be encoded as Base64 and passed as the endpoint response value, but 39 | /// an exception will be thrown if the generated media file is too big to 40 | /// fit into the available process memory. 41 | /// This option only has an effect if there is a screen recording session in progress 42 | /// and forced restart is not enabled (the default setting). 43 | /// </summary> 44 | /// <param name="uploadOptions">Upload options</param> 45 | /// <returns>self instance for chaining.</returns> 46 | public new T WithUploadOptions(ScreenRecordingUploadOptions uploadOptions) 47 | { 48 | return base.WithUploadOptions(uploadOptions); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/ScreenRecording/BaseStopScreenRecordingOptions.cs: -------------------------------------------------------------------------------- 1 | namespace OpenQA.Selenium.Appium.ScreenRecording 2 | { 3 | public abstract class BaseStopScreenRecordingOptions<T> : BaseScreenRecordingOptions<T> where T : BaseStopScreenRecordingOptions<T> 4 | { 5 | /// <summary> 6 | /// The remotePath upload option is the path to the remote location, 7 | /// where the resulting video should be uploaded. 8 | /// The following protocols are supported: http/https (multipart), ftp. 9 | /// Missing value (the default setting) means the content of resulting 10 | /// file should be encoded as Base64 and passed as the endpoint response value, but 11 | /// an exception will be thrown if the generated media file is too big to 12 | /// fit into the available process memory. 13 | /// </summary> 14 | /// <param name="uploadOptions">Upload options</param> 15 | /// <returns>self instance for chaining.</returns> 16 | public new T WithUploadOptions(ScreenRecordingUploadOptions uploadOptions) 17 | { 18 | return base.WithUploadOptions(uploadOptions); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/ScreenRecording/ScreenRecordingUploadOptions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace OpenQA.Selenium.Appium.ScreenRecording 4 | { 5 | public class ScreenRecordingUploadOptions 6 | { 7 | protected Dictionary<string, object> Parameters; 8 | 9 | /// <summary> 10 | /// The path to the remote location, where the resulting video should be uploaded. 11 | /// </summary> 12 | /// <param name="remotePath">The path to a writable remote location.</param> 13 | /// <returns>self instance for chaining.</returns> 14 | public ScreenRecordingUploadOptions WithRemotePath(string remotePath) 15 | { 16 | Parameters["remotePath"] = remotePath; 17 | return this; 18 | } 19 | 20 | /// <summary> 21 | /// Sets the credentials for remote ftp/http authentication (if needed). 22 | /// This option only has an effect if remotePath is provided. 23 | /// </summary> 24 | /// <param name="user">The name of the user for the remote authentication.</param> 25 | /// <param name="pass">The password for the remote authentication.</param> 26 | /// <returns>self instance for chaining.</returns> 27 | public ScreenRecordingUploadOptions WithAuthCredentials(string user, string pass) 28 | { 29 | Parameters["user"] = user; 30 | Parameters["pass"] = pass; 31 | return this; 32 | } 33 | 34 | public enum RequestMethod 35 | { 36 | POST, PUT 37 | } 38 | 39 | /// <summary> 40 | /// Sets the method name for http(s) upload. PUT is used by default. 41 | /// This option only has an effect if remotePath is provided. 42 | /// </summary> 43 | /// <param name="method">method The HTTP method name.</param> 44 | /// <returns>self instance for chaining.</returns> 45 | public ScreenRecordingUploadOptions WithHttpMethod(RequestMethod method) 46 | { 47 | Parameters["method"] = method.ToString(); 48 | return this; 49 | } 50 | 51 | /// <summary> 52 | /// Get all setted parameters 53 | /// </summary> 54 | /// <returns></returns> 55 | public Dictionary<string, object> GetParameters() 56 | { 57 | return Parameters; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Service/AppiumClientConfig.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | namespace OpenQA.Selenium.Appium.Service 16 | { 17 | 18 | public class AppiumClientConfig 19 | { 20 | /// <summary> 21 | /// Return the default Appium Client Config 22 | /// </summary> 23 | /// <returns>An AppiumClientConfig instance</returns> 24 | public static AppiumClientConfig DefaultConfig() 25 | { 26 | return new AppiumClientConfig(); 27 | } 28 | 29 | /// <summary> 30 | /// Gets or sets the directConnect feature availability. 31 | /// If this flag is true and the target server supports 32 | /// https://appiumpro.com/editions/86-connecting-directly-to-appium-hosts-in-distributed-environments, 33 | /// the AppiumCommandExecutor will follow the response directConnect direction. 34 | /// 35 | /// AppiumClientConfig clientConfig = AppiumClientConfig.DefaultConfig(); 36 | /// clientConfig.DirectConnect = true; 37 | /// 38 | /// </summary> 39 | public bool DirectConnect { get; set; } 40 | 41 | public bool RelaxSslValidation { get; set; } 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Service/AppiumHttpCommandExecutor.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using OpenQA.Selenium.Remote; 16 | using System; 17 | using System.Net.Http; 18 | 19 | namespace OpenQA.Selenium.Appium.Service 20 | { 21 | public class AppiumHttpCommandExecutor(Uri addressOfRemoteServer, TimeSpan timeout, AppiumClientConfig clientConfig) : HttpCommandExecutor(addressOfRemoteServer, timeout, enableKeepAlive: true) 22 | { 23 | private readonly AppiumClientConfig _clientConfig = clientConfig; 24 | 25 | protected override HttpClientHandler CreateHttpClientHandler() 26 | { 27 | var handler = base.CreateHttpClientHandler(); 28 | 29 | if (_clientConfig != null && _clientConfig.RelaxSslValidation) 30 | { 31 | handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true; 32 | } 33 | return handler; 34 | } 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Service/Exceptions/AppiumServerHasNotBeenStartedLocallyException.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using System; 16 | 17 | namespace OpenQA.Selenium.Appium.Service.Exceptions 18 | { 19 | public class AppiumServerHasNotBeenStartedLocallyException : Exception 20 | { 21 | public AppiumServerHasNotBeenStartedLocallyException(string messege, Exception cause) 22 | : base(messege, cause) 23 | { 24 | } 25 | 26 | public AppiumServerHasNotBeenStartedLocallyException(string messege) 27 | : base(messege) 28 | { 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Service/Exceptions/InvalidNodeJSInstanceException.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using System; 16 | 17 | namespace OpenQA.Selenium.Appium.Service.Exceptions 18 | { 19 | public class InvalidNodeJSInstanceException : Exception 20 | { 21 | public InvalidNodeJSInstanceException(string message, Exception cause) 22 | : base(message, cause) 23 | { 24 | } 25 | 26 | public InvalidNodeJSInstanceException(string message) 27 | : base(message) 28 | { 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Service/Exceptions/InvalidServerInstanceException.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using System; 16 | 17 | namespace OpenQA.Selenium.Appium.Service.Exceptions 18 | { 19 | public class InvalidServerInstanceException : Exception 20 | { 21 | private readonly static string Prefix = "Invalid server instance exception has occurred: "; 22 | 23 | public InvalidServerInstanceException(string message, Exception cause) 24 | : base($"{Prefix}{message}", cause) 25 | { 26 | } 27 | 28 | public InvalidServerInstanceException(string message) 29 | : base($"{Prefix}{message}") 30 | { 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Service/Options/AndroidOptionList.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | 16 | using System; 17 | using System.Collections.Generic; 18 | 19 | namespace OpenQA.Selenium.Appium.Service.Options 20 | { 21 | ///<summary> 22 | /// Here is the list of Android specific server arguments. 23 | /// All flags are optional, but some are required in conjunction with certain others. 24 | /// The full list is available here: http://appium.io/slate/en/master/?ruby#appium-server-arguments 25 | /// Android specific arguments are marked by (Android-only) 26 | /// </summary> 27 | public sealed class AndroidOptionList : BaseOptionList 28 | { 29 | ///<summary> 30 | /// Port to use on device to talk to Appium<br/> 31 | /// Sample:<br/> 32 | /// --bootstrap-port 4724 33 | ///</summary> 34 | public static KeyValuePair<string, string> BootstrapPort(string value) => 35 | GetKeyValuePairUsingDefaultValue("--bootstrap-port", value, "4724"); 36 | 37 | ///<summary> 38 | /// If set, prevents Appium from killing the adb server 39 | /// instance<br/> 40 | ///</summary> 41 | public static KeyValuePair<string, string> SuppressAdbKillServer() => 42 | new KeyValuePair<string, string>("--suppress-adb-kill-server", string.Empty); 43 | 44 | ///<summary> 45 | /// Port upon which ChromeDriver will run<br/> 46 | /// Sample:<br/> 47 | /// --chromedriver-port 9515 48 | ///</summary> 49 | public static KeyValuePair<string, string> ChromeDriverPort(string value) => 50 | GetKeyValuePairUsingDefaultValue("--chromedriver-port", value, "9515"); 51 | 52 | ///<summary> 53 | /// ChromeDriver executable full path 54 | ///</summary> 55 | public static KeyValuePair<string, string> ChromeDriverExecutable(string value) => 56 | GetKeyValuePair("--chromedriver-executable", value); 57 | } 58 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Service/Options/BaseOptionList.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using System; 16 | using System.Collections.Generic; 17 | 18 | 19 | namespace OpenQA.Selenium.Appium.Service.Options 20 | { 21 | public class BaseOptionList 22 | { 23 | protected static KeyValuePair<string, string> GetKeyValuePair(string argument, string value) 24 | { 25 | if (string.IsNullOrEmpty(value)) 26 | { 27 | throw new ArgumentException($"The argument {argument} requires not empty value"); 28 | } 29 | 30 | return new KeyValuePair<string, string>(argument, value); 31 | } 32 | 33 | protected static KeyValuePair<string, string> GetKeyValuePairUsingDefaultValue(string argument, string value, 34 | string defaultValue) 35 | { 36 | if (string.IsNullOrEmpty(value)) 37 | { 38 | return new KeyValuePair<string, string>(argument, defaultValue); 39 | } 40 | else 41 | { 42 | return new KeyValuePair<string, string>(argument, value); 43 | } 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Tizen/TizenCommandExecutionHelper.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using OpenQA.Selenium.Appium.Interfaces; 16 | using System; 17 | using System.Collections.Generic; 18 | 19 | namespace OpenQA.Selenium.Appium.Tizen 20 | { 21 | public sealed class TizenCommandExecutionHelper : AppiumCommandExecutionHelper 22 | { 23 | 24 | public static void SetAttribute(IExecuteMethod executeMethod, string elementId, string name, string value) 25 | { 26 | Dictionary<string, object> parameters = new Dictionary<string, object>(); 27 | string setAttributeScript = "this.setAttribute('" + name + "','" + value + "'," + elementId + " );"; 28 | parameters.Add("script", setAttributeScript); 29 | parameters.Add("args", elementId); 30 | executeMethod.Execute(DriverCommand.ExecuteScript, parameters); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Windows/Enums/WindowsKeyCodes.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | namespace OpenQA.Selenium.Appium.Windows.Enums 16 | { 17 | public sealed class WindowsKeyCode 18 | { 19 | public static readonly int Power = 0; 20 | public static readonly int Windows = 1; 21 | public static readonly int VolumeUp = 2; 22 | public static readonly int VolumeDown = 3; 23 | public static readonly int RotationLock = 4; 24 | public static readonly int CountMin = 5; 25 | public static readonly int Back = 5; 26 | public static readonly int Search = 6; 27 | public static readonly int CameraFocus = 7; 28 | public static readonly int CameraShutter = 8; 29 | public static readonly int RingerToggle = 9; 30 | public static readonly int Headset = 10; 31 | public static readonly int HwkbDploy = 11; 32 | public static readonly int CameraLens = 12; 33 | public static readonly int OemCustom = 13; 34 | public static readonly int OemCustom2 = 14; 35 | public static readonly int OemCustom3 = 15; 36 | public static readonly int Count = 16; 37 | } 38 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/Windows/WindowsDriverCommand.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | namespace OpenQA.Selenium.Appium 16 | { 17 | /// <summary> 18 | /// Provides command constants specific to Windows applications. 19 | /// </summary> 20 | public class WindowsDriverCommand 21 | { 22 | 23 | #region legacy app management 24 | 25 | /// <summary> 26 | /// Close App Command. 27 | /// </summary> 28 | public const string CloseApp = "closeApp"; 29 | 30 | /// <summary> 31 | /// Launch App Command. 32 | /// </summary> 33 | public const string LaunchApp = "launchApp"; 34 | 35 | #endregion legacy app management 36 | 37 | } 38 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/iOS/IOSStopScreenRecordingOptions.cs: -------------------------------------------------------------------------------- 1 | using OpenQA.Selenium.Appium.ScreenRecording; 2 | 3 | namespace OpenQA.Selenium.Appium.iOS 4 | { 5 | public class IOSStopScreenRecordingOptions : BaseStopScreenRecordingOptions<IOSStopScreenRecordingOptions> 6 | { 7 | public static IOSStopScreenRecordingOptions StopScreenRecordingOptions() 8 | { 9 | return new IOSStopScreenRecordingOptions(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Appium.Net/Appium/iOS/Interfaces/IHasSettings.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using OpenQA.Selenium.Appium.Interfaces; 16 | using System.Collections.Generic; 17 | 18 | namespace OpenQA.Selenium.Appium.iOS.Interfaces 19 | { 20 | public interface IHasSettings : IExecuteMethod 21 | { 22 | /// <summary> 23 | /// Set a setting for this test session It's probably better to use a 24 | /// convenience function, rather than use this function directly. Try finding 25 | /// the method for the specific setting you want to change. 26 | /// </summary> 27 | /// <param name="setting">Setting you wish to set.</param> 28 | /// <param name="value">value of the setting.</param> 29 | void SetSetting(string setting, object value); 30 | 31 | /// <summary> 32 | /// Gets/Sets settings stored for this test session. 33 | /// </summary> 34 | Dictionary<string, object> Settings { set; get; } 35 | } 36 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/iOS/Interfaces/IPerformsTouchID.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | namespace OpenQA.Selenium.Appium.iOS.Interfaces 16 | { 17 | public interface IPerformsTouchID 18 | { 19 | /// <summary> 20 | /// Simulate touchId event 21 | /// </summary> 22 | /// <param name="match">If true, simulates a successful fingerprint scan. 23 | /// If false, simulates a failed fingerprint scan.</param> 24 | void PerformTouchID(bool match); 25 | } 26 | } -------------------------------------------------------------------------------- /src/Appium.Net/Appium/iOS/Interfaces/IShakesDevice.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using OpenQA.Selenium.Appium.Interfaces; 16 | 17 | namespace OpenQA.Selenium.Appium.iOS.Interfaces 18 | { 19 | interface IShakesDevice : IExecuteMethod 20 | { 21 | /// <summary> 22 | /// Shakes the device. 23 | /// </summary> 24 | void ShakeDevice(); 25 | } 26 | } -------------------------------------------------------------------------------- /src/Appium.Net/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | 16 | namespace OpenQA.Selenium.Appium.Properties 17 | { 18 | 19 | [global::System.CodeDom.Compiler.GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 20 | [global::System.Diagnostics.DebuggerNonUserCode()] 21 | [global::System.Runtime.CompilerServices.CompilerGenerated()] 22 | internal class Resources 23 | { 24 | 25 | private static global::System.Resources.ResourceManager resourceMan; 26 | 27 | private static global::System.Globalization.CultureInfo resourceCulture; 28 | 29 | [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 30 | internal Resources() 31 | { 32 | } 33 | 34 | [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Advanced)] 35 | internal static global::System.Resources.ResourceManager ResourceManager 36 | { 37 | get 38 | { 39 | if (object.ReferenceEquals(resourceMan, null)) 40 | { 41 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("OpenQA.Selenium.Properties.Resources", typeof(Resources).Assembly); 42 | resourceMan = temp; 43 | } 44 | return resourceMan; 45 | } 46 | } 47 | 48 | [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Advanced)] 49 | internal static global::System.Globalization.CultureInfo Culture 50 | { 51 | get 52 | { 53 | return resourceCulture; 54 | } 55 | set 56 | { 57 | resourceCulture = value; 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/Appium.Net/appium-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium/dotnet-client/b3ebc07b50a63a5a06b3a0bf77f84d2609775747/src/Appium.Net/appium-icon.png -------------------------------------------------------------------------------- /test/integration/Android/ActivityTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Appium.Net.Integration.Tests.helpers; 4 | using NUnit.Framework; 5 | using OpenQA.Selenium.Appium.Android; 6 | using OpenQA.Selenium.Appium.Android.Enums; 7 | using OpenQA.Selenium.Support.UI; 8 | 9 | namespace Appium.Net.Integration.Tests.Android 10 | { 11 | [TestFixture] 12 | public class ActivityTest 13 | { 14 | private AndroidDriver _driver; 15 | private const string AppId = "io.appium.android.apis"; 16 | 17 | [OneTimeSetUp] 18 | public void BeforeAll() 19 | { 20 | var capabilities = Env.ServerIsRemote() 21 | ? Caps.GetAndroidUIAutomatorCaps(Apps.Get("androidApiDemos")) 22 | : Caps.GetAndroidUIAutomatorCaps(Apps.Get("androidApiDemos")); 23 | 24 | var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri; 25 | _driver = new AndroidDriver(serverUri, capabilities, Env.InitTimeoutSec); 26 | _driver.Manage().Timeouts().ImplicitWait = Env.ImplicitTimeoutSec; 27 | _driver.TerminateApp(AppId); 28 | } 29 | 30 | [SetUp] 31 | public void SetUp() 32 | { 33 | _driver?.ActivateApp(AppId); 34 | } 35 | 36 | [TearDown] 37 | public void TearDown() 38 | { 39 | _driver.TerminateApp(AppId); 40 | } 41 | 42 | [Test] 43 | public void CurrentActivityTest() 44 | { 45 | _driver.ExecuteScript( 46 | "mobile:startActivity", 47 | new object[] { 48 | new Dictionary<string, object>() { 49 | ["intent"] = "io.appium.android.apis/.ApiDemos", 50 | ["wait"] = true, 51 | } 52 | } 53 | ); 54 | var wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(5)); 55 | wait.Until(drv => { 56 | return ((AndroidDriver) drv).CurrentActivity == ".ApiDemos"; 57 | }); 58 | } 59 | 60 | [OneTimeTearDown] 61 | public void AfterAll() 62 | { 63 | _driver?.Quit(); 64 | if (!Env.ServerIsRemote()) AppiumServers.StopLocalService(); 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /test/integration/Android/AppStringsTest.cs: -------------------------------------------------------------------------------- 1 | using Appium.Net.Integration.Tests.helpers; 2 | using NUnit.Framework; 3 | using OpenQA.Selenium.Appium; 4 | using OpenQA.Selenium.Appium.Android; 5 | 6 | namespace Appium.Net.Integration.Tests.Android 7 | { 8 | [TestFixture] 9 | public class AppStringsTest 10 | { 11 | private AppiumDriver _driver; 12 | 13 | [OneTimeSetUp] 14 | public void BeforeAll() 15 | { 16 | var capabilities = Caps.GetAndroidUIAutomatorCaps(Apps.Get("androidApiDemos")); 17 | var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri; 18 | _driver = new AndroidDriver(serverUri, capabilities, Env.ImplicitTimeoutSec); 19 | _driver.Manage().Timeouts().ImplicitWait = Env.ImplicitTimeoutSec; 20 | } 21 | 22 | [OneTimeTearDown] 23 | public void AfterAll() 24 | { 25 | _driver?.Quit(); 26 | if (!Env.ServerIsRemote()) 27 | { 28 | AppiumServers.StopLocalService(); 29 | } 30 | } 31 | 32 | [Test] 33 | public void GetAppStrings() 34 | { 35 | Assert.That(_driver.GetAppStringDictionary(), Is.Not.Empty); 36 | } 37 | 38 | [Test] 39 | public void GetAppStringsUsingLang() 40 | { 41 | Assert.That(_driver.GetAppStringDictionary("ja"), Is.Not.Empty); 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /test/integration/Android/BiDiTests.cs: -------------------------------------------------------------------------------- 1 | using Appium.Net.Integration.Tests.helpers; 2 | using NUnit.Framework; 3 | using OpenQA.Selenium.Appium.Android; 4 | using OpenQA.Selenium.BiDi; 5 | using System.Threading.Tasks; 6 | 7 | namespace Appium.Net.Integration.Tests.Android 8 | { 9 | public class BiDiTests 10 | { 11 | private AndroidDriver _driver; 12 | 13 | private BiDi _bidi; 14 | 15 | [OneTimeSetUp] 16 | public void BeforeAll() 17 | { 18 | var capabilities = Caps.GetAndroidUIAutomatorCaps(); 19 | capabilities.UseWebSocketUrl = true; 20 | var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri; 21 | _driver = new AndroidDriver(serverUri, capabilities, Env.InitTimeoutSec); 22 | } 23 | 24 | [Test] 25 | public async Task RunBiDiScript() 26 | { 27 | _bidi = await _driver.AsBiDiAsync(); 28 | await _bidi.StatusAsync(); 29 | } 30 | 31 | [OneTimeTearDown] 32 | public async Task AfterAll() 33 | { 34 | if (_bidi != null) 35 | { 36 | try 37 | { 38 | await _bidi.DisposeAsync(); 39 | } 40 | catch { }; 41 | } 42 | _driver?.Quit(); 43 | if (!Env.ServerIsRemote()) 44 | { 45 | AppiumServers.StopLocalService(); 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /test/integration/Android/ConnectionTest.cs: -------------------------------------------------------------------------------- 1 | using Appium.Net.Integration.Tests.helpers; 2 | using NUnit.Framework; 3 | using OpenQA.Selenium.Appium; 4 | using OpenQA.Selenium.Appium.Android; 5 | 6 | namespace Appium.Net.Integration.Tests.Android 7 | { 8 | [TestFixture] 9 | class ConnectionTest 10 | { 11 | private AppiumDriver _driver; 12 | 13 | [OneTimeSetUp] 14 | public void BeforeAll() 15 | { 16 | var capabilities = Caps.GetAndroidUIAutomatorCaps(Apps.Get("androidApiDemos")); 17 | var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri; 18 | _driver = new AndroidDriver(serverUri, capabilities, Env.InitTimeoutSec); 19 | _driver.Manage().Timeouts().ImplicitWait = Env.ImplicitTimeoutSec; 20 | } 21 | 22 | [OneTimeTearDown] 23 | public void AfterAll() 24 | { 25 | _driver?.Quit(); 26 | if (!Env.ServerIsRemote()) 27 | { 28 | AppiumServers.StopLocalService(); 29 | } 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /test/integration/Android/CurrentPackageTest.cs: -------------------------------------------------------------------------------- 1 | using Appium.Net.Integration.Tests.helpers; 2 | using NUnit.Framework; 3 | using OpenQA.Selenium.Appium.Android; 4 | using OpenQA.Selenium.Support.UI; 5 | using System; 6 | 7 | namespace Appium.Net.Integration.Tests.Android 8 | { 9 | [TestFixture] 10 | public class CurrentPackageTest 11 | { 12 | private AndroidDriver _driver; 13 | private WebDriverWait _waitDriver; 14 | private readonly TimeSpan _driverTimeOut = TimeSpan.FromSeconds(5); 15 | 16 | private const string DemoAppPackage = "io.appium.android.apis"; 17 | 18 | [OneTimeSetUp] 19 | public void BeforeAll() 20 | { 21 | var capabilities = Caps.GetAndroidUIAutomatorCaps(Apps.Get("androidApiDemos")); 22 | 23 | var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri; 24 | _driver = new AndroidDriver(serverUri, capabilities, Env.InitTimeoutSec); 25 | _driver.Manage().Timeouts().ImplicitWait = Env.ImplicitTimeoutSec; 26 | _driver.TerminateApp(DemoAppPackage); 27 | } 28 | 29 | [SetUp] 30 | public void SetUp() 31 | { 32 | _driver?.ActivateApp(DemoAppPackage); 33 | } 34 | 35 | [OneTimeTearDown] 36 | public void TearDowwn() 37 | { 38 | _ = (_driver?.TerminateApp(DemoAppPackage)); 39 | _driver?.Quit(); 40 | } 41 | 42 | [Test] 43 | public void ReturnsCorrectNameForCurrentApp() 44 | { 45 | _waitDriver = new WebDriverWait(_driver, _driverTimeOut); 46 | _waitDriver.Until(driver => _driver.CurrentPackage == DemoAppPackage); 47 | Assert.That(_driver.CurrentPackage, Is.EqualTo(DemoAppPackage)); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /test/integration/Android/Device/AuthenticationTest.cs: -------------------------------------------------------------------------------- 1 | using Appium.Net.Integration.Tests.helpers; 2 | using NUnit.Framework; 3 | using OpenQA.Selenium.Appium.Android; 4 | using OpenQA.Selenium.Appium.Enums; 5 | 6 | namespace Appium.Net.Integration.Tests.Android.Device 7 | { 8 | public class AuthenticationTest 9 | { 10 | private AndroidDriver _driver; 11 | private readonly string appID = Apps.androidApiDemos; 12 | 13 | [OneTimeSetUp] 14 | public void BeforeAll() 15 | { 16 | 17 | var capabilities = Caps.GetAndroidUIAutomatorCaps(Apps.Get(appID)); 18 | capabilities.AddAdditionalAppiumOption(MobileCapabilityType.FullReset, true); 19 | var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri; 20 | _driver = new AndroidDriver(serverUri, capabilities, Env.InitTimeoutSec); 21 | _driver.Manage().Timeouts().ImplicitWait = Env.ImplicitTimeoutSec; 22 | } 23 | 24 | [SetUp] 25 | public void SetUp() 26 | { 27 | _driver?.ActivateApp(Apps.GetId(appID)); 28 | } 29 | 30 | [OneTimeTearDown] 31 | public void OneTimeTearDown() 32 | { 33 | _ = (_driver?.TerminateApp(Apps.GetId(appID))); 34 | _driver?.Quit(); 35 | } 36 | 37 | [Test] 38 | public void TestSendFingerprint() 39 | { 40 | // There's no way to verify sending fingerprint had an effect, 41 | // so just test that it's successfully called without an exception 42 | _driver.FingerPrint(1); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /test/integration/Android/Device/BrowserTests.cs: -------------------------------------------------------------------------------- 1 | using Appium.Net.Integration.Tests.helpers; 2 | using NUnit.Framework; 3 | using OpenQA.Selenium.Appium; 4 | using OpenQA.Selenium.Appium.Android; 5 | using System; 6 | 7 | namespace Appium.Net.Integration.Tests.Android.Device 8 | { 9 | internal class BrowserTests 10 | { 11 | private AppiumDriver _driver; 12 | private AppiumOptions _androidOptions; 13 | 14 | [OneTimeSetUp] 15 | public void SetUp() 16 | { 17 | _androidOptions = new AppiumOptions(); 18 | _androidOptions.BrowserName = "Chrome"; 19 | _androidOptions.AutomationName = "UiAutomator2"; 20 | 21 | _driver = new AndroidDriver( 22 | Env.ServerIsLocal() ? AppiumServers.LocalServiceUri : AppiumServers.RemoteServerUri, 23 | _androidOptions); 24 | _driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10); 25 | } 26 | 27 | [OneTimeTearDown] 28 | public void TearDown() 29 | { 30 | _driver?.Dispose(); 31 | } 32 | 33 | [Test] 34 | public void Browser() 35 | { 36 | _driver.Navigate().GoToUrl("https://github.com/appium"); 37 | Assert.That(_driver.PageSource, Is.Not.Empty); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /test/integration/Android/Device/SystemTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Appium.Net.Integration.Tests.helpers; 3 | using NUnit.Framework; 4 | using OpenQA.Selenium.Appium; 5 | using OpenQA.Selenium.Appium.Android; 6 | 7 | namespace Appium.Net.Integration.Tests.Android.Device 8 | { 9 | internal class SystemTests 10 | { 11 | private AppiumDriver _driver; 12 | private AppiumOptions _androidOptions; 13 | 14 | [OneTimeSetUp] 15 | public void SetUp() 16 | { 17 | _androidOptions = Caps.GetAndroidUIAutomatorCaps(Apps.Get(Apps.androidApiDemos)); 18 | _driver = new AndroidDriver( 19 | Env.ServerIsLocal() ? AppiumServers.LocalServiceUri : AppiumServers.RemoteServerUri, 20 | _androidOptions); 21 | _driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10); 22 | } 23 | 24 | [OneTimeTearDown] 25 | public void TearDown() 26 | { 27 | _driver.Dispose(); 28 | } 29 | 30 | [Test] 31 | public void CanGetSystemBarInfoTest() 32 | { 33 | var androidDriver = (AndroidDriver) _driver; 34 | Assert.That(androidDriver.GetSystemBars().Count, Is.EqualTo(2)); 35 | } 36 | 37 | [Test] 38 | public void CanGetDisplayDensityTest() 39 | { 40 | var androidDriver = (AndroidDriver) _driver; 41 | Assert.That(androidDriver.GetDisplayDensity(), Is.Not.EqualTo(0)); 42 | } 43 | 44 | [Test] 45 | public void CanOpenNotificationsTest() 46 | { 47 | var androidDriver = (AndroidDriver)_driver; 48 | androidDriver.OpenNotifications(); 49 | } 50 | 51 | [Test] 52 | public void CanGetSystemTimeTest() 53 | { 54 | var androidDriver = (AndroidDriver)_driver; 55 | var time = androidDriver.DeviceTime; 56 | Assert.That(time, Is.Not.Empty); 57 | Assert.That(DateTime.Parse(time), Is.Not.EqualTo(DateTime.Now.AddDays(3))); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /test/integration/Android/ElementTestEspresso.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Appium.Net.Integration.Tests.helpers; 3 | using NUnit.Framework; 4 | using OpenQA.Selenium; 5 | using OpenQA.Selenium.Appium; 6 | using OpenQA.Selenium.Appium.Android; 7 | 8 | namespace Appium.Net.Integration.Tests.Android 9 | { 10 | public class ElementTestEspresso 11 | { 12 | private AndroidDriver _driver; 13 | 14 | [OneTimeSetUp] 15 | public void BeforeAll() 16 | { 17 | var capabilities = Caps.GetAndroidEspressoCaps(Apps.Get("androidApiDemos")); 18 | var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri; 19 | _driver = new AndroidDriver(serverUri, capabilities, Env.InitTimeoutSec); 20 | _driver.Manage().Timeouts().ImplicitWait = Env.ImplicitTimeoutSec; 21 | } 22 | 23 | [Test] 24 | public void FindByAndroidDataMatcherTest() 25 | { 26 | const string selectorData = @"{ 27 | 'name':'hasEntry', 28 | 'args':['title','Graphics'] 29 | }"; 30 | 31 | By byAndroidDataMatcher = new ByAndroidDataMatcher(selectorData); 32 | 33 | Assert.Multiple(() => 34 | { 35 | Assert.That( 36 | Is.Not.EqualTo(_driver.FindElement(MobileBy.Id("android:id/list")).FindElement(byAndroidDataMatcher).Text), null); 37 | Assert.That( 38 | _driver.FindElement(MobileBy.Id("android:id/list")).FindElements(byAndroidDataMatcher), Is.Not.Empty); 39 | }); 40 | } 41 | 42 | [Test] 43 | public void FindByAndroidViewMatcherTest() 44 | { 45 | const string selectorData = @"{ 46 | 'name':'withText', 47 | 'args':[{ 48 | 'name':'containsString', 49 | 'args':['Preference'] 50 | } 51 | }]"; 52 | 53 | By byAndroidViewMatcher = new ByAndroidViewMatcher(selectorData); 54 | 55 | Assert.Multiple(() => 56 | { 57 | Assert.That( 58 | Is.Not.EqualTo(_driver.FindElement(MobileBy.Id("android:id/list")).FindElement(byAndroidViewMatcher).Text), null); 59 | Assert.That( 60 | _driver.FindElement(MobileBy.Id("android:id/list")).FindElements(byAndroidViewMatcher), Is.Not.Empty); 61 | }); 62 | } 63 | 64 | [OneTimeTearDown] 65 | public void AfterAll() 66 | { 67 | _driver?.Quit(); 68 | if (!Env.ServerIsRemote()) 69 | { 70 | AppiumServers.StopLocalService(); 71 | } 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /test/integration/Android/EmulatorDeviceTime.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Appium.Net.Integration.Tests.helpers; 3 | using NUnit.Framework; 4 | using OpenQA.Selenium.Appium; 5 | using OpenQA.Selenium.Appium.Android; 6 | using static System.String; 7 | 8 | namespace Appium.Net.Integration.Tests.Android 9 | { 10 | class EmulatorDeviceTime 11 | { 12 | private AppiumDriver _driver; 13 | 14 | [SetUp] 15 | public void BeforeAll() 16 | { 17 | var capabilities = Env.ServerIsRemote() 18 | ? Caps.GetAndroidUIAutomatorCaps(Apps.Get("androidApiDemos")) 19 | : Caps.GetAndroidUIAutomatorCaps(Apps.Get("androidApiDemos")); 20 | var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri; 21 | _driver = new AndroidDriver(serverUri, capabilities, Env.InitTimeoutSec); 22 | _driver.Manage().Timeouts().ImplicitWait = Env.ImplicitTimeoutSec; 23 | } 24 | 25 | [TearDown] 26 | public void AfterEach() 27 | { 28 | _driver?.Quit(); 29 | if (!Env.ServerIsRemote()) 30 | { 31 | AppiumServers.StopLocalService(); 32 | } 33 | } 34 | 35 | [Test] 36 | public void DeviceTimeTest() 37 | { 38 | var time = _driver.DeviceTime; 39 | Assert.Multiple(() => 40 | { 41 | Assert.That(time, Is.Not.Null); 42 | Assert.That(time, Is.Not.EqualTo(Empty)); 43 | Console.WriteLine(time); 44 | Assert.That(DateTime.Parse(time), Is.Not.EqualTo(DateTime.Now.AddDays(3))); 45 | }); 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /test/integration/Android/EventsTests.cs: -------------------------------------------------------------------------------- 1 | using Appium.Net.Integration.Tests.helpers; 2 | using NUnit.Framework; 3 | using OpenQA.Selenium.Appium.Android; 4 | using OpenQA.Selenium.Support.UI; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | 9 | namespace Appium.Net.Integration.Tests.Android 10 | { 11 | public class EventTests 12 | { 13 | private AndroidDriver _driver; 14 | 15 | private readonly string _appKey = "androidApiDemos"; 16 | 17 | [OneTimeSetUp] 18 | public void BeforeAll() 19 | { 20 | var capabilities = Env.ServerIsRemote() 21 | ? Caps.GetAndroidUIAutomatorCaps(Apps.Get(_appKey)) 22 | : Caps.GetAndroidUIAutomatorCaps(Apps.Get(_appKey)); 23 | var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri; 24 | _driver = new AndroidDriver(serverUri, capabilities, Env.InitTimeoutSec); 25 | } 26 | 27 | [Test] 28 | public void GetEventsTestCase() 29 | { 30 | object value; 31 | _driver.GetEvents().TryGetValue("commands", out value); 32 | Assert.That(value, Is.Not.Null); 33 | } 34 | 35 | [Test] 36 | public void LogEventTestCase() 37 | { 38 | object value; 39 | 40 | _driver.GetEvents().TryGetValue("appium:hello", out value); 41 | Assert.That(value, Is.Null); 42 | 43 | _driver.LogEvent("appium", "hello"); 44 | 45 | _driver.GetEvents().TryGetValue("appium:hello", out value); 46 | Assert.That(value, Is.Not.Null); 47 | } 48 | 49 | [OneTimeTearDown] 50 | public void AfterAll() 51 | { 52 | if (_driver != null) 53 | { 54 | _ = _driver.TerminateApp(Apps.GetId(_appKey)); 55 | _driver?.Quit(); 56 | } 57 | if (!Env.ServerIsRemote()) 58 | { 59 | AppiumServers.StopLocalService(); 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /test/integration/Android/FiltersTests.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | using System.Collections.Generic; 16 | using NUnit.Framework; 17 | using OpenQA.Selenium.Appium.Android; 18 | using OpenQA.Selenium.Appium; 19 | using Appium.Net.Integration.Tests.helpers; 20 | 21 | namespace Appium.Net.Integration.Tests.Android 22 | { 23 | [TestFixture] 24 | public class FiltersTests 25 | { 26 | private AndroidDriver _driver; 27 | 28 | [OneTimeSetUp] 29 | public void BeforeAll() 30 | { 31 | var capabilities = Caps.GetAndroidUIAutomatorCaps(Apps.Get("androidApiDemos")); 32 | var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri; 33 | _driver = new AndroidDriver(serverUri, capabilities, Env.InitTimeoutSec); 34 | _driver.Manage().Timeouts().ImplicitWait = Env.ImplicitTimeoutSec; 35 | } 36 | 37 | [Test] 38 | public void FirstWithName_ReturnsCorrectElement() 39 | { 40 | var viewsElement = _driver.FindElement(MobileBy.AccessibilityId("Views")); 41 | 42 | var textElement = _driver.FindElement(MobileBy.AccessibilityId("Text")); 43 | 44 | var elements = new List<AppiumElement> { viewsElement, textElement }; 45 | 46 | var result = Filters.FirstWithName(elements, "Text"); 47 | 48 | Assert.That(result, Is.EqualTo(textElement)); 49 | } 50 | 51 | [OneTimeTearDown] 52 | public void AfterAll() 53 | { 54 | _driver?.Quit(); 55 | if (!Env.ServerIsRemote()) 56 | { 57 | AppiumServers.StopLocalService(); 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /test/integration/Android/LockDeviceTest.cs: -------------------------------------------------------------------------------- 1 | using Appium.Net.Integration.Tests.helpers; 2 | using NUnit.Framework; 3 | using OpenQA.Selenium.Appium.Android; 4 | 5 | namespace Appium.Net.Integration.Tests.Android 6 | { 7 | class LockDeviceTest 8 | { 9 | private AndroidDriver _driver; 10 | 11 | [SetUp] 12 | public void BeforeAll() 13 | { 14 | var capabilities = Env.ServerIsRemote() 15 | ? Caps.GetAndroidUIAutomatorCaps(Apps.Get("androidApiDemos")) 16 | : Caps.GetAndroidUIAutomatorCaps(Apps.Get("androidApiDemos")); 17 | var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri; 18 | _driver = new AndroidDriver(serverUri, capabilities, Env.InitTimeoutSec); 19 | _driver.Manage().Timeouts().ImplicitWait = Env.ImplicitTimeoutSec; 20 | } 21 | 22 | [TearDown] 23 | public void AfterEach() 24 | { 25 | _driver?.Quit(); 26 | if (!Env.ServerIsRemote()) 27 | { 28 | AppiumServers.StopLocalService(); 29 | } 30 | } 31 | 32 | [Test] 33 | public void LockTest() 34 | { 35 | _driver.Lock(); 36 | Assert.That(_driver.IsLocked(), Is.EqualTo(true)); 37 | _driver.Unlock("12345","password"); 38 | Assert.That(_driver.IsLocked(), Is.EqualTo(false)); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /test/integration/Android/OrientationTest.cs: -------------------------------------------------------------------------------- 1 | using Appium.Net.Integration.Tests.helpers; 2 | using NUnit.Framework; 3 | using OpenQA.Selenium; 4 | using OpenQA.Selenium.Appium; 5 | using OpenQA.Selenium.Appium.Android; 6 | 7 | namespace Appium.Net.Integration.Tests.Android 8 | { 9 | [TestFixture] 10 | class OrientationTest 11 | { 12 | private AppiumDriver _driver; 13 | 14 | [OneTimeSetUp] 15 | public void BeforeAll() 16 | { 17 | var capabilities = Env.ServerIsRemote() 18 | ? Caps.GetAndroidUIAutomatorCaps(Apps.Get("androidApiDemos")) 19 | : Caps.GetAndroidUIAutomatorCaps(Apps.Get("androidApiDemos")); 20 | var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri; 21 | _driver = new AndroidDriver(serverUri, capabilities, Env.InitTimeoutSec); 22 | _driver.Manage().Timeouts().ImplicitWait = Env.ImplicitTimeoutSec; 23 | } 24 | 25 | [OneTimeTearDown] 26 | public void AfterAll() 27 | { 28 | _driver?.Quit(); 29 | if (!Env.ServerIsRemote()) 30 | { 31 | AppiumServers.StopLocalService(); 32 | } 33 | } 34 | 35 | [Test] 36 | public void DeviceOrientationTest() 37 | { 38 | IRotatable rotatable = _driver; 39 | rotatable.Orientation = ScreenOrientation.Portrait; 40 | Assert.That(rotatable.Orientation, Is.EqualTo(ScreenOrientation.Portrait)); 41 | } 42 | 43 | [Test] 44 | public void RotationTest() 45 | { 46 | _driver.Orientation = ScreenOrientation.Landscape; 47 | Assert.That(_driver.Orientation, Is.EqualTo(ScreenOrientation.Landscape)); 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /test/integration/Android/ScreenRecordingTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using Appium.Net.Integration.Tests.helpers; 4 | using NUnit.Framework; 5 | using OpenQA.Selenium.Appium; 6 | using OpenQA.Selenium.Appium.Android; 7 | 8 | namespace Appium.Net.Integration.Tests.Android 9 | { 10 | [TestFixture] 11 | class ScreenRecordingTest 12 | { 13 | private AppiumDriver _driver; 14 | 15 | [OneTimeSetUp] 16 | public void BeforeAll() 17 | { 18 | var capabilities = Caps.GetAndroidUIAutomatorCaps(Apps.Get("androidApiDemos")); 19 | var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri; 20 | _driver = new AndroidDriver(serverUri, capabilities, Env.InitTimeoutSec); 21 | _driver.Manage().Timeouts().ImplicitWait = Env.ImplicitTimeoutSec; 22 | } 23 | 24 | 25 | [OneTimeTearDown] 26 | public void AfterAll() 27 | { 28 | _driver?.Quit(); 29 | if (!Env.ServerIsRemote()) 30 | { 31 | AppiumServers.StopLocalService(); 32 | } 33 | } 34 | 35 | [Test] 36 | public void ScreenRecordTest() 37 | { 38 | _driver.StartRecordingScreen(); 39 | Thread.Sleep(1000); 40 | var result = _driver.StopRecordingScreen(); 41 | Assert.That(result, Is.Not.Empty); 42 | } 43 | 44 | [Test] 45 | public void ScreenRecordWithOptionsTest() 46 | { 47 | _driver.StartRecordingScreen( 48 | AndroidStartScreenRecordingOptions.GetAndroidStartScreenRecordingOptions() 49 | .WithTimeLimit(TimeSpan.FromSeconds(10)) 50 | .WithBitRate(500000) 51 | .WithVideoSize("720x1280")); 52 | Thread.Sleep(1000); 53 | var result = _driver.StopRecordingScreen(); 54 | Assert.That(result, Is.Not.Empty); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /test/integration/Android/Session/GeolocationTests.cs: -------------------------------------------------------------------------------- 1 | using Appium.Net.Integration.Tests.helpers; 2 | using NUnit.Framework; 3 | using OpenQA.Selenium.Appium; 4 | using OpenQA.Selenium.Appium.Android; 5 | 6 | namespace Appium.Net.Integration.Tests.Android.Session.Geolocation 7 | { 8 | [TestFixture] 9 | internal class GeolocationTests 10 | { 11 | private AppiumDriver _driver; 12 | 13 | [SetUp] 14 | public void BeforeAll() 15 | { 16 | var capabilities = Env.ServerIsRemote() 17 | ? Caps.GetAndroidUIAutomatorCaps(Apps.Get("androidApiDemos")) 18 | : Caps.GetAndroidUIAutomatorCaps(Apps.Get("androidApiDemos")); 19 | var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri; 20 | _driver = new AndroidDriver(serverUri, capabilities, Env.InitTimeoutSec); 21 | _driver.Manage().Timeouts().ImplicitWait = Env.ImplicitTimeoutSec; 22 | } 23 | 24 | [TearDown] 25 | public void AfterEach() 26 | { 27 | _driver?.Quit(); 28 | if (!Env.ServerIsRemote()) 29 | { 30 | AppiumServers.StopLocalService(); 31 | } 32 | } 33 | 34 | [Test] 35 | public void GetLocationTest() 36 | { 37 | Assert.Multiple(() => 38 | { 39 | Assert.That(() => _driver.Location, Is.Not.Null); 40 | Assert.DoesNotThrow(() => _driver.Location.ToDictionary()); 41 | Assert.That(_driver.Location.Altitude, Is.Not.EqualTo(0)); 42 | Assert.That(_driver.Location.Longitude, Is.Not.EqualTo(0)); 43 | Assert.That(_driver.Location.Latitude, Is.Not.EqualTo(0)); 44 | }); 45 | } 46 | 47 | [Test] 48 | public void SetLocationTest() 49 | { 50 | var testLocation = new Location 51 | { 52 | Altitude = 10, 53 | Longitude = 10, 54 | Latitude = 10, 55 | }; 56 | _driver.Location = testLocation; 57 | Assert.Multiple(() => 58 | { 59 | Assert.That(() => _driver.Location, Is.Not.Null); 60 | Assert.DoesNotThrow(() => _driver.Location.ToDictionary()); 61 | Assert.That(_driver.Location.Altitude, Is.Not.EqualTo(0)); 62 | Assert.That(_driver.Location.Longitude, Is.Not.EqualTo(0)); 63 | Assert.That(_driver.Location.Latitude, Is.Not.EqualTo(0)); 64 | }); 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /test/integration/Android/Session/SessionTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Appium.Net.Integration.Tests.helpers; 3 | using NUnit.Framework; 4 | using OpenQA.Selenium.Appium; 5 | using OpenQA.Selenium.Appium.Android; 6 | 7 | namespace Appium.Net.Integration.Tests.Android.Session 8 | { 9 | class SessionTests 10 | { 11 | private AppiumDriver _driver; 12 | 13 | [OneTimeSetUp] 14 | public void BeforeAll() 15 | { 16 | var capabilities = Env.ServerIsRemote() 17 | ? Caps.GetAndroidUIAutomatorCaps(Apps.Get("androidApiDemos")) 18 | : Caps.GetAndroidUIAutomatorCaps(Apps.Get("androidApiDemos")); 19 | capabilities.AddAdditionalAppiumOption("desired", capabilities.ToCapabilities()); 20 | var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri; 21 | _driver = new AndroidDriver(serverUri, capabilities, Env.InitTimeoutSec); 22 | _driver.Manage().Timeouts().ImplicitWait = Env.ImplicitTimeoutSec; 23 | } 24 | 25 | [OneTimeTearDown] 26 | public void AfterAll() 27 | { 28 | _driver?.Quit(); 29 | if (!Env.ServerIsRemote()) 30 | { 31 | AppiumServers.StopLocalService(); 32 | } 33 | } 34 | 35 | [Test] 36 | public void GetSessionDetailTest() 37 | { 38 | object deviceName = _driver.GetSessionDetail("deviceName"); 39 | Assert.That(deviceName, Is.Not.Null); 40 | } 41 | 42 | [Test] 43 | public void GetDeviceDictionaryData() 44 | { 45 | var dictionary = (Dictionary<string, object>)_driver.SessionDetails["desired"]; 46 | Assert.That(dictionary, Is.Not.Empty); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /test/integration/Appium.Net.Integration.Tests.csproj: -------------------------------------------------------------------------------- 1 | <Project Sdk="Microsoft.NET.Sdk"> 2 | <PropertyGroup> 3 | <TargetFrameworks>net48;net8.0</TargetFrameworks> 4 | <LangVersion>latest</LangVersion> 5 | </PropertyGroup> 6 | <ItemGroup> 7 | <Compile Remove="apps\**" /> 8 | <EmbeddedResource Remove="apps\**" /> 9 | <None Remove="apps\**" /> 10 | </ItemGroup> 11 | <ItemGroup> 12 | <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" /> 13 | <PackageReference Include="NUnit" Version="4.3.2" /> 14 | <PackageReference Include="NUnit.Analyzers" Version="4.7.0"> 15 | <PrivateAssets>all</PrivateAssets> 16 | <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> 17 | </PackageReference> 18 | <PackageReference Include="NUnit3TestAdapter" Version="4.6.0" /> 19 | <PackageReference Include="System.Text.Json" Version="9.0.0" /> 20 | </ItemGroup> 21 | <ItemGroup> 22 | <ProjectReference Include="..\..\src\Appium.Net\Appium.Net.csproj" /> 23 | </ItemGroup> 24 | <ItemGroup> 25 | <Compile Update="Properties\Resources.Designer.cs"> 26 | <DesignTime>True</DesignTime> 27 | <AutoGen>True</AutoGen> 28 | <DependentUpon>Resources.resx</DependentUpon> 29 | </Compile> 30 | </ItemGroup> 31 | <ItemGroup> 32 | <EmbeddedResource Update="Properties\Resources.resx"> 33 | <Generator>PublicResXFileCodeGenerator</Generator> 34 | <LastGenOutput>Resources.Designer.cs</LastGenOutput> 35 | </EmbeddedResource> 36 | </ItemGroup> 37 | <ItemGroup> 38 | <None Update="env.json" Condition="Exists('env.json')"> 39 | <CopyToOutputDirectory>Always</CopyToOutputDirectory> 40 | </None> 41 | </ItemGroup> 42 | <ItemGroup> 43 | <Folder Include="Mac\" /> 44 | </ItemGroup> 45 | </Project> -------------------------------------------------------------------------------- /test/integration/IOS/AlertTests.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using Appium.Net.Integration.Tests.helpers; 3 | using NUnit.Framework; 4 | using OpenQA.Selenium.Appium; 5 | using OpenQA.Selenium.Appium.iOS; 6 | 7 | namespace Appium.Net.Integration.Tests.IOS 8 | { 9 | public class AlertTests 10 | { 11 | private AppiumDriver _driver; 12 | 13 | [OneTimeSetUp] 14 | public void BeforeAll() 15 | { 16 | var capabilities = Caps.GetIosCaps(Apps.Get("iosTestApp")); 17 | var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri; 18 | _driver = new IOSDriver(serverUri, capabilities, Env.InitTimeoutSec); 19 | _driver.Manage().Timeouts().ImplicitWait = Env.ImplicitTimeoutSec; 20 | } 21 | 22 | [OneTimeTearDown] 23 | public void AfterEach() 24 | { 25 | _driver?.Quit(); 26 | if (!Env.ServerIsRemote()) 27 | { 28 | AppiumServers.StopLocalService(); 29 | } 30 | } 31 | 32 | [Test] 33 | public void AcceptAlertTest() 34 | { 35 | _driver.FindElement(MobileBy.IosNSPredicate("label == 'show alert'")).Click(); 36 | Thread.Sleep(5000); 37 | _driver.SwitchTo().Alert().Accept(); 38 | } 39 | 40 | [Test] 41 | public void DismissAlertTest() 42 | { 43 | _driver.FindElement(MobileBy.IosNSPredicate("label == 'show alert'")).Click(); 44 | Thread.Sleep(5000); 45 | _driver.SwitchTo().Alert().Dismiss(); 46 | } 47 | 48 | [Test] 49 | public void TextAlertTest() 50 | { 51 | _driver.FindElement(MobileBy.IosNSPredicate("label == 'show alert'")).Click(); 52 | Thread.Sleep(500); 53 | string alertText = _driver.SwitchTo().Alert().Text; 54 | Assert.That(alertText, Is.EqualTo("Cool title\nthis alert is so cool.")); 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /test/integration/IOS/AppStringsTest.cs: -------------------------------------------------------------------------------- 1 | using Appium.Net.Integration.Tests.helpers; 2 | using NUnit.Framework; 3 | using OpenQA.Selenium.Appium; 4 | using OpenQA.Selenium.Appium.iOS; 5 | 6 | namespace Appium.Net.Integration.Tests.IOS 7 | { 8 | public class AppStringsTest 9 | { 10 | private AppiumDriver _driver; 11 | 12 | [OneTimeSetUp] 13 | public void BeforeAll() 14 | { 15 | var capabilities = Caps.GetIosCaps(Apps.Get("iosTestApp")); 16 | var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri; 17 | _driver = new IOSDriver(serverUri, capabilities, Env.InitTimeoutSec); 18 | _driver.Manage().Timeouts().ImplicitWait = Env.ImplicitTimeoutSec; 19 | } 20 | 21 | [OneTimeTearDown] 22 | public void AfterEach() 23 | { 24 | _driver?.Quit(); 25 | if (!Env.ServerIsRemote()) 26 | { 27 | AppiumServers.StopLocalService(); 28 | } 29 | } 30 | 31 | [Test] 32 | public void GetAppStrings() 33 | { 34 | Assert.That(_driver.GetAppStringDictionary(), Is.Not.Empty); 35 | } 36 | 37 | [Test] 38 | public void GetAppStringsUsingLang() 39 | { 40 | Assert.That(_driver.GetAppStringDictionary("en"), Is.Not.Empty); 41 | } 42 | 43 | [Test] 44 | public void GetAppStringsUsingLangAndFileStrings() 45 | { 46 | Assert.That(_driver.GetAppStringDictionary("en", "Localizable.strings"), Is.Not.Empty); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /test/integration/IOS/Device/KeyboardTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using Appium.Net.Integration.Tests.helpers; 3 | using OpenQA.Selenium.Appium.Enums; 4 | using OpenQA.Selenium.Appium.iOS; 5 | using OpenQA.Selenium.Appium; 6 | using System; 7 | using OpenQA.Selenium.Support.UI; 8 | using System.Runtime.InteropServices; 9 | 10 | 11 | namespace Appium.Net.Integration.Tests.IOS.Device 12 | { 13 | [TestFixture] 14 | public class IOSKeyboardTests 15 | { 16 | private IOSDriver iosDriver; 17 | 18 | [OneTimeSetUp] 19 | public void SetUp() 20 | { 21 | var capabilities = Caps.GetIosCaps(Apps.Get("iosTestApp")); 22 | capabilities.AddAdditionalAppiumOption(MobileCapabilityType.FullReset, false); 23 | var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri; 24 | 25 | iosDriver = new IOSDriver(serverUri, capabilities, Env.InitTimeoutSec); 26 | iosDriver.Manage().Timeouts().ImplicitWait = Env.ImplicitTimeoutSec; 27 | } 28 | 29 | [Test] 30 | public void HideKeyboard_WithKeyOnly_ShouldInvokeHelperMethod() 31 | { 32 | TimeSpan _driverTimeOut = TimeSpan.FromSeconds(5); 33 | WebDriverWait _waitDriver = new WebDriverWait(iosDriver, _driverTimeOut); 34 | 35 | // Arrange 36 | var key = "Done"; 37 | iosDriver.FindElement(MobileBy.AccessibilityId("IntegerA")).Click(); 38 | // Act 39 | iosDriver.HideKeyboard(key); 40 | // Assert 41 | _waitDriver.Until(drv => 42 | { 43 | return iosDriver.IsKeyboardShown() == false; 44 | } 45 | ); 46 | } 47 | 48 | [Test] 49 | public void HideKeyboard_WithoutParameters_ShouldInvokeHelperMethod() 50 | { 51 | // Arrange 52 | iosDriver.FindElement(MobileBy.AccessibilityId("IntegerA")).Click(); 53 | // Act 54 | iosDriver.HideKeyboard(); 55 | // Assert 56 | var keyboard_shown = iosDriver.IsKeyboardShown(); 57 | Assert.That(keyboard_shown, Is.EqualTo(false)); 58 | } 59 | 60 | [OneTimeTearDown] 61 | public void TearDown() 62 | { 63 | if (iosDriver.IsLocked()) 64 | iosDriver.Unlock(); 65 | iosDriver?.Quit(); 66 | 67 | if (!Env.ServerIsRemote()) 68 | { 69 | AppiumServers.StopLocalService(); 70 | } 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /test/integration/IOS/Device/SystemTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Appium.Net.Integration.Tests.helpers; 3 | using NUnit.Framework; 4 | using OpenQA.Selenium.Appium.iOS; 5 | 6 | namespace Appium.Net.Integration.Tests.IOS.Device 7 | { 8 | internal class SystemTests 9 | { 10 | private IOSDriver iosDriver; 11 | 12 | [OneTimeSetUp] 13 | public void SetUp() 14 | { 15 | var capabilities = Caps.GetIosCaps(Apps.Get("iosUICatalogApp")); 16 | var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri; 17 | iosDriver = new IOSDriver(serverUri, capabilities, Env.InitTimeoutSec); 18 | iosDriver.Manage().Timeouts().ImplicitWait = Env.ImplicitTimeoutSec; 19 | } 20 | 21 | [OneTimeTearDown] 22 | public void TearDown() 23 | { 24 | iosDriver.Dispose(); 25 | } 26 | 27 | [Test] 28 | public void CanGetSystemTimeTest() 29 | { 30 | var time = iosDriver.DeviceTime; 31 | Assert.That(iosDriver.DeviceTime, Is.Not.Empty); 32 | Assert.That(DateTime.Parse(time), Is.Not.EqualTo(DateTime.Now.AddDays(3))); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /test/integration/IOS/ElementTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Appium.Net.Integration.Tests.helpers; 3 | using NUnit.Framework; 4 | using OpenQA.Selenium; 5 | using OpenQA.Selenium.Appium; 6 | using OpenQA.Selenium.Appium.iOS; 7 | using OpenQA.Selenium.Support.UI; 8 | 9 | namespace Appium.Net.Integration.Tests.IOS 10 | { 11 | class ElementTests 12 | { 13 | private AppiumDriver _driver; 14 | private WebDriverWait _driverWait; 15 | 16 | [OneTimeSetUp] 17 | public void BeforeAll() 18 | { 19 | var capabilities = Caps.GetIosCaps(Apps.Get("iosTestApp")); 20 | var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri; 21 | _driver = new IOSDriver(serverUri, capabilities, Env.InitTimeoutSec); 22 | _driver.Manage().Timeouts().ImplicitWait = Env.ImplicitTimeoutSec; 23 | _driverWait = new WebDriverWait(_driver, TimeSpan.FromSeconds(5)); 24 | } 25 | 26 | [OneTimeTearDown] 27 | public void AfterEach() 28 | { 29 | _driver?.Quit(); 30 | if (!Env.ServerIsRemote()) 31 | { 32 | AppiumServers.StopLocalService(); 33 | } 34 | } 35 | 36 | [Test] 37 | public void FindByAccessibilityIdTest() 38 | { 39 | By byAccessibilityId = new ByAccessibilityId("ComputeSumButton"); 40 | Assert.Multiple(() => 41 | { 42 | Assert.That(_driver.FindElement(MobileBy.ClassName("UIAWindow")).FindElement(byAccessibilityId).Text, Is.EqualTo("Compute Sum")); 43 | Assert.That(_driver.FindElement(MobileBy.ClassName("UIAWindow")).FindElements(byAccessibilityId), Is.Not.Empty); 44 | }); 45 | } 46 | 47 | [Test] 48 | public void FindElementsByClassNameTest() 49 | { 50 | By byClassName = new ByClassName("XCUIElementTypeTextField"); 51 | Assert.That(_driverWait.Until(_driver => _driver.FindElements(byClassName).Count == 2), Is.True); 52 | } 53 | 54 | [Test] 55 | public void FindElementMobileByClassNameTest() 56 | { 57 | try 58 | { 59 | var switchElement = _driver.FindElement(MobileBy.ClassName("XCUIElementTypeSwitch")); 60 | } 61 | catch (NoSuchElementException ex) 62 | { 63 | Assert.Fail("Element not found, exception: " + ex.Message); 64 | } 65 | } 66 | 67 | } 68 | } -------------------------------------------------------------------------------- /test/integration/IOS/LockDeviceTest.cs: -------------------------------------------------------------------------------- 1 | using Appium.Net.Integration.Tests.helpers; 2 | using NUnit.Framework; 3 | using OpenQA.Selenium.Appium.iOS; 4 | 5 | namespace Appium.Net.Integration.Tests.IOS 6 | { 7 | internal class LockDeviceTest 8 | { 9 | private IOSDriver _driver; 10 | 11 | [SetUp] 12 | public void TestSetup() 13 | { 14 | var capabilities = Caps.GetIosCaps(Apps.Get("iosWebviewApp")); 15 | var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri; 16 | _driver = new IOSDriver(serverUri, capabilities, Env.InitTimeoutSec); 17 | _driver.Manage().Timeouts().ImplicitWait = Env.ImplicitTimeoutSec; 18 | } 19 | 20 | [TearDown] 21 | public void Cleanup() 22 | { 23 | if (_driver.IsLocked()) 24 | _driver.Unlock(); 25 | _driver?.Quit(); 26 | if (!Env.ServerIsRemote()) 27 | { 28 | AppiumServers.StopLocalService(); 29 | } 30 | } 31 | 32 | [Test] 33 | public void IsLockedTest() 34 | { 35 | Assert.That(_driver.IsLocked(), Is.EqualTo(false)); 36 | } 37 | 38 | [Test] 39 | public void LockTest() 40 | { 41 | Assert.That(_driver.IsLocked(), Is.EqualTo(false)); 42 | _driver.Lock(); 43 | Assert.That(_driver.IsLocked(), Is.EqualTo(true)); 44 | } 45 | 46 | [Test] 47 | public void LockTestWithSeconds() 48 | { 49 | Assert.That(_driver.IsLocked(), Is.EqualTo(false)); 50 | _driver.Lock(5); 51 | Assert.That(_driver.IsLocked(), Is.EqualTo(false)); 52 | } 53 | 54 | [Test] 55 | public void UnlockTest() 56 | { 57 | Assert.That(_driver.IsLocked(), Is.EqualTo(false)); 58 | _driver.Lock(); 59 | Assert.That(_driver.IsLocked(), Is.EqualTo(true)); 60 | _driver.Unlock(); 61 | Assert.That(_driver.IsLocked(), Is.EqualTo(false)); 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /test/integration/IOS/OrientationTest.cs: -------------------------------------------------------------------------------- 1 | using Appium.Net.Integration.Tests.helpers; 2 | using NUnit.Framework; 3 | using OpenQA.Selenium; 4 | using OpenQA.Selenium.Appium.iOS; 5 | 6 | namespace Appium.Net.Integration.Tests.IOS 7 | { 8 | [TestFixture] 9 | public class OrientationTest 10 | { 11 | private IWebDriver _driver; 12 | 13 | [OneTimeSetUp] 14 | public void BeforeAll() 15 | { 16 | var capabilities = Caps.GetIosCaps(Apps.Get("iosTestApp")); 17 | var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri; 18 | _driver = new IOSDriver(serverUri, capabilities, Env.InitTimeoutSec); 19 | _driver.Manage().Timeouts().ImplicitWait = Env.ImplicitTimeoutSec; 20 | } 21 | 22 | [OneTimeTearDown] 23 | public void AfterAll() 24 | { 25 | _driver?.Quit(); 26 | if (Env.ServerIsRemote()) return; 27 | AppiumServers.StopLocalService(); 28 | } 29 | 30 | [TearDown] 31 | public void AfterEach() 32 | { 33 | var rotatable = (IRotatable)_driver; 34 | rotatable.Orientation = ScreenOrientation.Portrait; 35 | } 36 | 37 | [Test] 38 | public void DeviceOrientationTest() 39 | { 40 | var rotatable = (IRotatable) _driver; 41 | rotatable.Orientation = ScreenOrientation.Landscape; 42 | Assert.That(rotatable.Orientation, Is.EqualTo(ScreenOrientation.Landscape)); 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /test/integration/IOS/ScreenRecordingTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using Appium.Net.Integration.Tests.helpers; 4 | using NUnit.Framework; 5 | using OpenQA.Selenium.Appium; 6 | using OpenQA.Selenium.Appium.iOS; 7 | 8 | namespace Appium.Net.Integration.Tests.IOS 9 | { 10 | [TestFixture] 11 | class ScreenRecordingTest 12 | { 13 | private IOSDriver _driver; 14 | 15 | [OneTimeSetUp] 16 | public void BeforeAll() 17 | { 18 | var capabilities = Caps.GetIosCaps(Apps.Get("iosUICatalogApp")); 19 | var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri; 20 | _driver = new IOSDriver(serverUri, capabilities, Env.InitTimeoutSec); 21 | _driver.Manage().Timeouts().ImplicitWait = Env.ImplicitTimeoutSec; 22 | } 23 | 24 | [OneTimeTearDown] 25 | public void AfterEach() 26 | { 27 | _driver?.Quit(); 28 | if (!Env.ServerIsRemote()) 29 | { 30 | AppiumServers.StopLocalService(); 31 | } 32 | } 33 | 34 | [Test] 35 | public void ScreenRecordTest() 36 | { 37 | _driver.StartRecordingScreen(); 38 | Thread.Sleep(1000); 39 | var result = _driver.StopRecordingScreen(); 40 | Assert.That(result, Is.Not.Empty); 41 | } 42 | 43 | [Test] 44 | public void ScreenRecordWithOptionsTest() 45 | { 46 | _driver.StartRecordingScreen( 47 | IOSStartScreenRecordingOptions.GetIosStartScreenRecordingOptions() 48 | .WithTimeLimit(TimeSpan.FromSeconds(10)) 49 | .WithVideoType(IOSStartScreenRecordingOptions.VideoType.H264) 50 | .WithVideoFps("10") 51 | .WithVideoScale("320:240")); 52 | Thread.Sleep(1000); 53 | var result = _driver.StopRecordingScreen(); 54 | Assert.That(result, Is.Not.Empty); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /test/integration/IOS/ScrollingSearchingTest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Appium.Net.Integration.Tests.helpers; 3 | using NUnit.Framework; 4 | using OpenQA.Selenium.Appium; 5 | using OpenQA.Selenium.Appium.iOS; 6 | 7 | namespace Appium.Net.Integration.Tests.IOS 8 | { 9 | public class ScrollingSearchingTest 10 | { 11 | private IOSDriver _driver; 12 | 13 | [OneTimeSetUp] 14 | public void BeforeAll() 15 | { 16 | var capabilities = Caps.GetIosCaps(Apps.Get("iosUICatalogApp")); 17 | var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri; 18 | _driver = new IOSDriver(serverUri, capabilities, Env.InitTimeoutSec); 19 | _driver.Manage().Timeouts().ImplicitWait = Env.ImplicitTimeoutSec; 20 | } 21 | 22 | [OneTimeTearDown] 23 | public void AfterEach() 24 | { 25 | _driver?.Quit(); 26 | if (!Env.ServerIsRemote()) 27 | { 28 | AppiumServers.StopLocalService(); 29 | } 30 | } 31 | 32 | [Test] 33 | public void ScrollToToolbarsElementUsingToVisibleTrueTest() 34 | { 35 | var Toolbars = _driver.FindElement(new ByIosNSPredicate("name == 'Toolbars'")); 36 | _driver.ExecuteScript("mobile: scroll", new Dictionary<string, string> { { "element", Toolbars.Id }, { "toVisible", "true" } }); 37 | Assert.That(Toolbars.Displayed, Is.True, "The 'Toolbars' element should be visible after scrolling."); 38 | } 39 | 40 | [Test] 41 | public void ScrollToSwitchesElementUsingDirectionDownTest() 42 | { 43 | var table = _driver.FindElement(new ByIosNSPredicate("type == 'XCUIElementTypeTable'")); 44 | _driver.ExecuteScript("mobile: scroll", new Dictionary<string, string> { { "direction", "down" }, { "element", table.Id } }); 45 | var switches = table.FindElement(new ByIosNSPredicate("name CONTAINS 'Switches'")); 46 | Assert.That(switches.GetAttribute("visible"), Is.EqualTo("true")); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /test/integration/IOS/SearchingClassChainTest.cs: -------------------------------------------------------------------------------- 1 | using Appium.Net.Integration.Tests.helpers; 2 | using NUnit.Framework; 3 | using OpenQA.Selenium.Appium; 4 | using OpenQA.Selenium.Appium.iOS; 5 | 6 | namespace Appium.Net.Integration.Tests.IOS 7 | { 8 | public class SearchingClassChainTest 9 | { 10 | private IOSDriver _driver; 11 | 12 | [OneTimeSetUp] 13 | public void BeforeAll() 14 | { 15 | var capabilities = Caps.GetIosCaps(Apps.Get("iosUICatalogApp")); 16 | var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri; 17 | _driver = new IOSDriver(serverUri, capabilities, Env.InitTimeoutSec); 18 | _driver.Manage().Timeouts().ImplicitWait = Env.ImplicitTimeoutSec; 19 | } 20 | 21 | [OneTimeTearDown] 22 | public void AfterEach() 23 | { 24 | _driver?.Quit(); 25 | if (!Env.ServerIsRemote()) 26 | { 27 | AppiumServers.StopLocalService(); 28 | } 29 | } 30 | 31 | [Test] 32 | public void FindByClassChainTest() 33 | { 34 | var sliderCellStaticTextElements1 = _driver 35 | .FindElements( 36 | new ByIosClassChain("**/XCUIElementTypeCell/XCUIElementTypeStaticText[`name == 'Sliders'`]")); 37 | Assert.That(sliderCellStaticTextElements1.Count, Is.EqualTo(1)); 38 | var sliderCellStaticTextElements2 = _driver.FindElements(MobileBy.IosClassChain("**/XCUIElementTypeCell")); 39 | Assert.That(sliderCellStaticTextElements2.Count, Is.EqualTo(18)); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /test/integration/IOS/SearchingTest.cs: -------------------------------------------------------------------------------- 1 | using Appium.Net.Integration.Tests.helpers; 2 | using NUnit.Framework; 3 | using OpenQA.Selenium; 4 | using OpenQA.Selenium.Appium; 5 | using OpenQA.Selenium.Appium.iOS; 6 | 7 | namespace Appium.Net.Integration.Tests.IOS 8 | { 9 | class SearchingTest 10 | { 11 | private IOSDriver _driver; 12 | 13 | [OneTimeSetUp] 14 | public void BeforeAll() 15 | { 16 | var capabilities = Caps.GetIosCaps(Apps.Get("iosTestApp")); 17 | if (Env.ServerIsRemote()) 18 | { 19 | capabilities.AddAdditionalAppiumOption("username", Env.GetEnvVar("SAUCE_USERNAME")); 20 | capabilities.AddAdditionalAppiumOption("accessKey", Env.GetEnvVar("SAUCE_ACCESS_KEY")); 21 | capabilities.AddAdditionalAppiumOption("name", "ios - simple"); 22 | capabilities.AddAdditionalAppiumOption("tags", new[] {"sample"}); 23 | } 24 | var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri; 25 | _driver = new IOSDriver(serverUri, capabilities, Env.InitTimeoutSec); 26 | _driver.Manage().Timeouts().ImplicitWait = Env.ImplicitTimeoutSec; 27 | } 28 | 29 | [OneTimeTearDown] 30 | public void AfterAll() 31 | { 32 | _driver?.Quit(); 33 | if (!Env.ServerIsRemote()) 34 | { 35 | AppiumServers.StopLocalService(); 36 | } 37 | } 38 | 39 | [Test] 40 | public void FindByAccessibilityIdTest() 41 | { 42 | By byAccessibilityId = new ByAccessibilityId("ComputeSumButton"); 43 | Assert.Multiple(() => 44 | { 45 | Assert.That(string.IsNullOrEmpty(_driver.FindElement(byAccessibilityId).Text), Is.False); 46 | Assert.That(_driver.FindElements(byAccessibilityId), Is.Not.Empty); 47 | }); 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /test/integration/IOS/SettingTest.cs: -------------------------------------------------------------------------------- 1 | using Appium.Net.Integration.Tests.helpers; 2 | using NUnit.Framework; 3 | using OpenQA.Selenium.Appium.iOS; 4 | 5 | namespace Appium.Net.Integration.Tests.IOS 6 | { 7 | public class SettingTest 8 | { 9 | private IOSDriver _driver; 10 | 11 | [OneTimeSetUp] 12 | public void BeforeAll() 13 | { 14 | var capabilities = Caps.GetIosCaps(Apps.Get("iosUICatalogApp")); 15 | var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri; 16 | _driver = new IOSDriver(serverUri, capabilities, Env.InitTimeoutSec); 17 | _driver.Manage().Timeouts().ImplicitWait = Env.ImplicitTimeoutSec; 18 | } 19 | 20 | [OneTimeTearDown] 21 | public void AfterEach() 22 | { 23 | _driver?.Quit(); 24 | if (!Env.ServerIsRemote()) 25 | { 26 | AppiumServers.StopLocalService(); 27 | } 28 | } 29 | 30 | [Test] 31 | public void SettingsUpdateTest() 32 | { 33 | _driver.SetSetting( 34 | setting: "useJSONSource", 35 | value: true); 36 | 37 | Assert.That((bool)_driver.Settings["useJSONSource"]); 38 | 39 | _driver.SetSetting( 40 | setting: "useJSONSource", 41 | value: false); 42 | 43 | Assert.That((bool)_driver.Settings["useJSONSource"], Is.False); 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /test/integration/IOS/WebviewTest.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using Appium.Net.Integration.Tests.helpers; 3 | using NUnit.Framework; 4 | using OpenQA.Selenium; 5 | using OpenQA.Selenium.Appium; 6 | using OpenQA.Selenium.Appium.iOS; 7 | 8 | namespace Appium.Net.Integration.Tests.IOS 9 | { 10 | [TestFixture] 11 | public class WebviewTest 12 | { 13 | private AppiumDriver _driver; 14 | 15 | [OneTimeSetUp] 16 | public void BeforeAll() 17 | { 18 | var capabilities = Caps.GetIosCaps(Apps.Get("iosWebviewApp")); 19 | if (Env.ServerIsRemote()) 20 | { 21 | capabilities.AddAdditionalAppiumOption("username", Env.GetEnvVar("SAUCE_USERNAME")); 22 | capabilities.AddAdditionalAppiumOption("accessKey", Env.GetEnvVar("SAUCE_ACCESS_KEY")); 23 | capabilities.AddAdditionalAppiumOption("name", "ios - webview"); 24 | capabilities.AddAdditionalAppiumOption("tags", new[] {"sample"}); 25 | } 26 | var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri; 27 | _driver = new IOSDriver(serverUri, capabilities, Env.InitTimeoutSec); 28 | _driver.Manage().Timeouts().ImplicitWait = Env.ImplicitTimeoutSec; 29 | } 30 | 31 | [OneTimeTearDown] 32 | public void AfterAll() 33 | { 34 | _driver?.Quit(); 35 | if (!Env.ServerIsRemote()) 36 | { 37 | AppiumServers.StopLocalService(); 38 | } 39 | } 40 | 41 | [Test] 42 | public void GetPageTestCase() 43 | { 44 | _driver.FindElement(MobileBy.XPath("//UIATextField[@value='Enter URL']")) 45 | .SendKeys("www.google.com"); 46 | _driver.FindElement(MobileBy.ClassName("UIAButton")).Click(); 47 | _driver.FindElement(MobileBy.ClassName("UIAWebView")).Click(); // dismissing keyboard 48 | Thread.Sleep(10000); 49 | _driver.Context = "WEBVIEW"; 50 | Thread.Sleep(3000); 51 | var el = _driver.FindElement(MobileBy.ClassName("gsfi")); 52 | el.SendKeys("Appium"); 53 | el.SendKeys(Keys.Return); 54 | Thread.Sleep(1000); 55 | Assert.That(_driver.Title.Contains("Appium")); 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /test/integration/Mac/AlertTest.cs: -------------------------------------------------------------------------------- 1 | using Appium.Net.Integration.Tests.helpers; 2 | using NUnit.Framework; 3 | using OpenQA.Selenium.Appium; 4 | using OpenQA.Selenium.Appium.Enums; 5 | using OpenQA.Selenium.Appium.Mac; 6 | 7 | namespace Appium.Net.Integration.Tests.Mac 8 | { 9 | public class FindElementTest 10 | { 11 | private MacDriver _driver; 12 | 13 | [OneTimeSetUp] 14 | public void BeforeAll() 15 | { 16 | var capabilities = new AppiumOptions 17 | { 18 | AutomationName = AutomationName.Mac2, 19 | PlatformName = MobilePlatform.MacOS 20 | }; 21 | var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri; 22 | _driver = new MacDriver(serverUri, capabilities, Env.InitTimeoutSec); 23 | } 24 | 25 | [OneTimeTearDown] 26 | public void AfterAll() 27 | { 28 | _driver?.Quit(); 29 | if (!Env.ServerIsRemote()) 30 | { 31 | AppiumServers.StopLocalService(); 32 | } 33 | } 34 | 35 | [Test] 36 | public void ClickAboutThisMacTest() 37 | { 38 | _driver.FindElement(MobileBy.IosNSPredicate("elementType == 56 AND title = 'Apple'")).Click(); 39 | _driver.FindElement(MobileBy.AccessibilityId("_aboutThisMacRequested:")).Click(); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /test/integration/Options/OptionsTest.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | 16 | using Appium.Net.Integration.Tests.helpers; 17 | using NUnit.Framework; 18 | using OpenQA.Selenium.Appium; 19 | using OpenQA.Selenium.Appium.Enums; 20 | 21 | namespace Appium.Net.Integration.Tests.Options 22 | { 23 | public class OptionsTest 24 | { 25 | 26 | [Test] 27 | public void CheckToDictionaryContainsAppiumOptions() 28 | { 29 | var capabilities = new AppiumOptions(); 30 | capabilities.AddAdditionalAppiumOption(AndroidMobileCapabilityType.Avd, "Android_Emulator"); 31 | capabilities.AddAdditionalAppiumOption(AndroidMobileCapabilityType.AppPackage, Apps.GetId(Apps.androidApiDemos)); 32 | var capsDict = capabilities.ToDictionary(); 33 | Assert.That(capsDict, Is.Not.Empty); 34 | Assert.That(capsDict, Has.Count.GreaterThan(1)); 35 | } 36 | 37 | [Test] 38 | public void CheckToDictionaryContainsBothOptions() 39 | { 40 | var capabilities = new AppiumOptions 41 | { 42 | AutomationName = AutomationName.Appium, 43 | App = Apps.androidApiDemos, 44 | PlatformName = MobilePlatform.Android 45 | }; 46 | capabilities.AddAdditionalAppiumOption(AndroidMobileCapabilityType.Avd, "Android_Emulator"); 47 | capabilities.AddAdditionalAppiumOption(AndroidMobileCapabilityType.AppPackage, Apps.GetId(Apps.androidApiDemos)); 48 | var capsDict = capabilities.ToDictionary(); 49 | Assert.That(capsDict, Is.Not.Empty); 50 | Assert.That(capsDict, Has.Count.EqualTo(5)); 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /test/integration/README.md: -------------------------------------------------------------------------------- 1 | # Appium.Net Integration Tests 2 | 3 | ## Running tests locally (local service) 4 | 5 | - Ensure node.js is installed 6 | - Install appium server instance via npm 7 | - `cp env.json.sample env.json` 8 | - Update `env.json` set DEV=true 9 | - Run the tests in NUnit. 10 | 11 | ## Running tests on remote appium server 12 | 13 | - `cp env.json.sample env.json` 14 | - Update `env.json` set isRemoteServer=true 15 | - Ensure env.json file is build action is non 16 | - Update env.json 'Copy to Output Directory' property is either set to 'Copy always' or 'Copy if newer' 17 | - Set remoteAppiumServerUri i.e. remoteAppiumServerUri="http://10.200.1.2:4723/wd/hub" 18 | - Run the tests in NUnit. 19 | -------------------------------------------------------------------------------- /test/integration/ServerTests/AppiumClientConfigTest.cs: -------------------------------------------------------------------------------- 1 | //Licensed under the Apache License, Version 2.0 (the "License"); 2 | //you may not use this file except in compliance with the License. 3 | //See the NOTICE file distributed with this work for additional 4 | //information regarding copyright ownership. 5 | //You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | //Unless required by applicable law or agreed to in writing, software 10 | //distributed under the License is distributed on an "AS IS" BASIS, 11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | //See the License for the specific language governing permissions and 13 | //limitations under the License. 14 | 15 | 16 | using NUnit.Framework; 17 | using OpenQA.Selenium.Appium.Service; 18 | 19 | namespace Appium.Net.Integration.Tests.ServerTests 20 | { 21 | public class AppiumClientConfigTest 22 | { 23 | 24 | [Test] 25 | public void SetAndGetDirectConnect() 26 | { 27 | var clientConfig = AppiumClientConfig.DefaultConfig(); 28 | Assert.That(clientConfig.DirectConnect, Is.False); 29 | 30 | clientConfig.DirectConnect = true; 31 | Assert.That(clientConfig.DirectConnect); 32 | } 33 | 34 | [Test] 35 | public void SetAndGetRelaxSSLValidation() 36 | { 37 | var clientConfig = AppiumClientConfig.DefaultConfig(); 38 | Assert.That(clientConfig.RelaxSslValidation, Is.False); 39 | 40 | clientConfig.RelaxSslValidation = true; 41 | Assert.That(clientConfig.RelaxSslValidation); 42 | } 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /test/integration/apps/ApiDemos-debug.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium/dotnet-client/b3ebc07b50a63a5a06b3a0bf77f84d2609775747/test/integration/apps/ApiDemos-debug.apk -------------------------------------------------------------------------------- /test/integration/apps/IntentExample.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium/dotnet-client/b3ebc07b50a63a5a06b3a0bf77f84d2609775747/test/integration/apps/IntentExample.apk -------------------------------------------------------------------------------- /test/integration/apps/archives/ApiDemos-debug.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium/dotnet-client/b3ebc07b50a63a5a06b3a0bf77f84d2609775747/test/integration/apps/archives/ApiDemos-debug.zip -------------------------------------------------------------------------------- /test/integration/apps/archives/IntentExample.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium/dotnet-client/b3ebc07b50a63a5a06b3a0bf77f84d2609775747/test/integration/apps/archives/IntentExample.zip -------------------------------------------------------------------------------- /test/integration/apps/archives/TestApp.app.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium/dotnet-client/b3ebc07b50a63a5a06b3a0bf77f84d2609775747/test/integration/apps/archives/TestApp.app.zip -------------------------------------------------------------------------------- /test/integration/apps/archives/UICatalog.app.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium/dotnet-client/b3ebc07b50a63a5a06b3a0bf77f84d2609775747/test/integration/apps/archives/UICatalog.app.zip -------------------------------------------------------------------------------- /test/integration/apps/archives/WebViewApp.app.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium/dotnet-client/b3ebc07b50a63a5a06b3a0bf77f84d2609775747/test/integration/apps/archives/WebViewApp.app.zip -------------------------------------------------------------------------------- /test/integration/apps/archives/vodqa.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium/dotnet-client/b3ebc07b50a63a5a06b3a0bf77f84d2609775747/test/integration/apps/archives/vodqa.zip -------------------------------------------------------------------------------- /test/integration/env.json.sample: -------------------------------------------------------------------------------- 1 | { 2 | "DEV": false, 3 | "isRemoteAppiumServer": false, 4 | "remoteAppiumServerUri": "http://<remoteurl>:<port>/" 5 | } 6 | -------------------------------------------------------------------------------- /test/integration/helpers/AppiumServers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using OpenQA.Selenium.Appium.Service; 4 | 5 | namespace Appium.Net.Integration.Tests.helpers 6 | { 7 | public class AppiumServers 8 | { 9 | private static AppiumLocalService _localService; 10 | private static Uri _remoteAppiumServerUri; 11 | 12 | public static Uri LocalServiceUri 13 | { 14 | get 15 | { 16 | if (_localService == null) 17 | { 18 | var builder = 19 | new AppiumServiceBuilder() 20 | .WithLogFile(new FileInfo(Path.GetTempPath() + "Log.txt")); 21 | 22 | _localService = builder.Build(); 23 | } 24 | 25 | if (!_localService.IsRunning) 26 | { 27 | _localService.Start(); 28 | } 29 | 30 | return _localService.ServiceUrl; 31 | } 32 | } 33 | 34 | public static Uri RemoteServerUri 35 | { 36 | get 37 | { 38 | if (_remoteAppiumServerUri == null) 39 | { 40 | _remoteAppiumServerUri = new Uri(Env.GetEnvVar("remoteAppiumServerUri")); 41 | } 42 | else 43 | { 44 | return _remoteAppiumServerUri; 45 | } 46 | 47 | return _remoteAppiumServerUri; 48 | } 49 | } 50 | 51 | public static void StopLocalService() 52 | { 53 | if (_localService != null && _localService.IsRunning) 54 | { 55 | _localService.Dispose(); 56 | _localService = null; 57 | } 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /test/integration/helpers/Caps.cs: -------------------------------------------------------------------------------- 1 | using OpenQA.Selenium.Appium; 2 | using OpenQA.Selenium.Appium.Enums; 3 | 4 | namespace Appium.Net.Integration.Tests.helpers 5 | { 6 | public class Caps 7 | { 8 | public static AppiumOptions GetIosCaps(string app) 9 | { 10 | var capabilities = new AppiumOptions(); 11 | capabilities.AutomationName = AutomationName.iOSXcuiTest; 12 | capabilities.DeviceName = "iPhone 16 Plus"; 13 | capabilities.PlatformVersion = "18.4"; 14 | capabilities.App = app; 15 | capabilities.AddAdditionalAppiumOption(IOSMobileCapabilityType.LaunchTimeout, Env.InitTimeoutSec.TotalMilliseconds); 16 | 17 | return capabilities; 18 | } 19 | 20 | public static AppiumOptions GetAndroidUIAutomatorCaps(string app) 21 | { 22 | var capabilities = new AppiumOptions(); 23 | capabilities.AutomationName = AutomationName.AndroidUIAutomator2; 24 | capabilities.DeviceName = "Android Emulator"; 25 | capabilities.App = app; 26 | return capabilities; 27 | } 28 | 29 | public static AppiumOptions GetAndroidUIAutomatorCaps() 30 | { 31 | var capabilities = new AppiumOptions(); 32 | capabilities.AutomationName = AutomationName.AndroidUIAutomator2; 33 | capabilities.DeviceName = "Android Emulator"; 34 | return capabilities; 35 | } 36 | 37 | public static AppiumOptions GetAndroidEspressoCaps(string app) 38 | { 39 | var capabilities = new AppiumOptions(); 40 | capabilities.AutomationName = AutomationName.AndroidEspresso; 41 | capabilities.DeviceName = "Android Emulator"; 42 | capabilities.App = app; 43 | return capabilities; 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /test/integration/helpers/Filters.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using OpenQA.Selenium; 3 | 4 | namespace Appium.Net.Integration.Tests.helpers 5 | { 6 | public class Filters 7 | { 8 | public static IWebElement FirstWithName<TW>(IList<TW> els, string name) where TW : IWebElement 9 | { 10 | for (var i = 0; i < els.Count; i++) 11 | { 12 | if (els[i].GetAttribute("name") == name) 13 | { 14 | return (TW) els[i]; 15 | } 16 | } 17 | return null; 18 | } 19 | 20 | public static IList<IWebElement> FilterWithName<TW>(IList<TW> els, string name) where TW : IWebElement 21 | { 22 | var res = new List<IWebElement>(); 23 | for (var i = 0; i < els.Count; i++) 24 | { 25 | if (els[i].GetAttribute("name") == name) 26 | { 27 | res.Add(els[i]); 28 | } 29 | } 30 | return res; 31 | } 32 | 33 | public static IList<IWebElement> FilterDisplayed<TW>(IList<TW> els) where TW : IWebElement 34 | { 35 | var res = new List<IWebElement>(); 36 | for (var i = 0; i < els.Count; i++) 37 | { 38 | IWebElement el = els[i]; 39 | if (els[i].Displayed) 40 | { 41 | res.Add(els[i]); 42 | } 43 | } 44 | return res; 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /test/integration/helpers/NpmNotFoundException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Appium.Net.Integration.Tests.helpers 4 | { 5 | public class NpmNotFoundException : Exception 6 | { 7 | public NpmNotFoundException() 8 | : base("Node Package Manager (npm) cannot be found. Make sure Node.js is installed and present in PATH.") 9 | { 10 | } 11 | 12 | public NpmNotFoundException(string message) 13 | : base(message) 14 | { 15 | } 16 | 17 | public NpmNotFoundException(string message, Exception innerException) 18 | : base(message, innerException) 19 | { 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /test/integration/helpers/NpmUnknownCommandException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Appium.Net.Integration.Tests.helpers 4 | { 5 | public class NpmUnknownCommandException : Exception 6 | { 7 | public NpmUnknownCommandException() 8 | : base("Unknown npm command encountered. ") 9 | { 10 | } 11 | 12 | public NpmUnknownCommandException(string message) 13 | : base(message) 14 | { 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/integration/helpers/Paths.cs: -------------------------------------------------------------------------------- 1 | using Appium.Net.Integration.Tests.helpers; 2 | using System.IO; 3 | 4 | namespace Appium.Net.Integration.Tests.Helpers 5 | { 6 | internal class Paths 7 | { 8 | private string _pathToAppiumPackageIndex; 9 | 10 | public string PathToAppiumPackageIndex 11 | { 12 | get 13 | { 14 | if (_pathToAppiumPackageIndex == null) 15 | { 16 | InitAppiumPackageIndexPath(); 17 | } 18 | return _pathToAppiumPackageIndex; 19 | } 20 | } 21 | 22 | /// <summary> 23 | /// Initializes the Appium package index path by combining the components "appium" and "index.js" with the npm prefix path. 24 | /// </summary> 25 | /// <remarks> 26 | /// This method sets the _pathToAppiumPackageIndex variable by combining the specified components with the npm prefix path. 27 | /// </remarks> 28 | private void InitAppiumPackageIndexPath() 29 | { 30 | string[] appiumJsPathComponents = { "appium", "index.js" }; 31 | string npmPath = Npm.GetNpmPrefixPath(); 32 | 33 | _pathToAppiumPackageIndex = Path.Combine(npmPath, Path.Combine(appiumJsPathComponents)); 34 | } 35 | } 36 | } 37 | --------------------------------------------------------------------------------