{"id":27938597,"url":"https://github.com/willowtreeapps/conductor-mobile","last_synced_at":"2025-05-07T08:49:31.248Z","repository":{"id":57729636,"uuid":"68478320","full_name":"willowtreeapps/conductor-mobile","owner":"willowtreeapps","description":"Conductor Mobile is a port of the Conductor Web Framework for iOS and Android","archived":false,"fork":false,"pushed_at":"2020-03-19T03:45:00.000Z","size":584,"stargazers_count":6,"open_issues_count":4,"forks_count":5,"subscribers_count":121,"default_branch":"master","last_synced_at":"2024-04-14T23:17:09.585Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/willowtreeapps.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-09-17T21:07:11.000Z","updated_at":"2020-06-10T19:40:48.000Z","dependencies_parsed_at":"2022-09-26T22:00:55.794Z","dependency_job_id":null,"html_url":"https://github.com/willowtreeapps/conductor-mobile","commit_stats":null,"previous_names":[],"tags_count":52,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willowtreeapps%2Fconductor-mobile","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willowtreeapps%2Fconductor-mobile/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willowtreeapps%2Fconductor-mobile/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willowtreeapps%2Fconductor-mobile/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/willowtreeapps","download_url":"https://codeload.github.com/willowtreeapps/conductor-mobile/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252847292,"owners_count":21813440,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-05-07T08:49:30.702Z","updated_at":"2025-05-07T08:49:31.240Z","avatar_url":"https://github.com/willowtreeapps.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![CircleCI](https://circleci.com/gh/willowtreeapps/conductor-mobile.svg?style=svg)](https://circleci.com/gh/willowtreeapps/conductor-mobile)\n[![Maven Central](https://img.shields.io/maven-central/v/com.willowtreeapps/conductor-mobile.svg)](https://search.maven.org/search?q=a:conductor-mobile)\n\nConductor Mobile\n================\n\nConductor Mobile is a port of the [Conductor](https://github.com/conductor-framework/conductor) Web Framework for iOS and Android, instead of wrapping around [Selenium](http://www.seleniumhq.org/) it wraps the [Appium Framework](http://appium.io/). Thanks to [@ddavison]\n\n# Getting Started\n```xml\n\u003cdependencies\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003ecom.willowtreeapps\u003c/groupId\u003e\n        \u003cartifactId\u003econductor-mobile\u003c/artifactId\u003e\n        \u003cversion\u003e0.21.2\u003c/version\u003e\n    \u003c/dependency\u003e\n\u003c/dependencies\u003e\n```\nCreate a Java Class, and extend it from `com.joss.conductor.mobile.Locomotive`\n\n# Goals\nSame as the original conductor, the primary goals of this project are to...\n- Take advantage of method chaining, to create a fluent interface.\n- Abstract the programmer from bloated scripts resulting from using too many css selectors, and too much code.\n- Provide a quick and easy framework in Selenium 2 using Java, to get started writing scripts.\n- Provide a free to use framework for any starting enterprise, or individual programmer.\n- Automatic detection of connected iOS devices\n\n# Configuration\nConductor can be configured using a [yaml](https://en.wikipedia.org/wiki/YAML) file. By default, Conductor looks for a \"config.yaml\" at the root of embedded resources.\n\nThe file has 3 sections: `current configuration`, `defaults`, and `schemes`.\n\n## General Configuration\nThe general configuration only has two properties: `platformName` (which must be either IOS or ANDROID) and optionally `currentSchemes`, which will be discussed later\n\n## Defaults\nThe defaults section contains both general defaults and defaults per platform. It looks like this:\n```yaml\ndefaults:\n  implicitWaitTime: 3\n  appiumRequestTimeout: 10\n  screenshotOnFail: false\n  autoGrantPermissions: true\n\n  ios:\n    platformVersion: 13.0\n    deviceName: iPhone 11 Pro\n\n  android:\n    appiumRequestTimeout: 15\n    platformVersion: 10.0\n```\nPlatforms can override defaults just be re-specifying them in the platform section\n\n## Schemes\n\nSometimes it is useful to specify properties under specific circumstances, and this is what \"schemes\" are for.  Schemes override properties in the configuration *in the order they are specified in the `currentSchemes` section of the configuration file.*\n\nYou might, for example, have a scheme for running on a specific device or specific remote testing tool. It's a pain to have to re-specify these so, Conductor makes this easy with schemes. Some example schemes:\n\n```yaml\nios_sauce_labs:\n  hub: http://saucelabs-hub\n  appFile: sauce-storage:app.zip\n  automationName: XCUITest\n  platformVersion: 13.0\n  deviceName: iPhone 11 Pro\n\nshorter_timeouts:\n  appiumRequestTimeout: 1\n  implicitWaitTime: 2\n```\nYou can see a variety of example configuration files in the unit tests for conductor [here](src/test/resources/test_yaml)\n\n# Supported Properties\n## General (Common)\n- `platformName` = {string: ANDROID or IOS} (note all capps)\n- `deviceName` = {name of the device}\n- `appPackageName` = {android app package name or iOS bundle id}\n- `appFile` = {path to apk, ipa, or app}\n- `platformVersion` = {string: version iOS or Android}\n- `udid` = {string: iOS device's UDID or Android's device name from ADB, or auto to use the first connected device}\n- `noReset` = {boolean: true or false}\n- `fullReset` = {boolean: true or false}\n- `appiumRequestTimeout` = {int: default equals 5 seconds per call}\n- `implicitWaitTime` = {int: default equals 5}\n- `screenshotsOnFail` = {boolean: true or false}\n- `autoGrantPermissions` = {boolean: true or false}\n- `automationName` = {string: i.e. uiautomator2 or xcuitest}\n\n\n## General (less common, usually not required)\n- `language` = {string: }\n- `locale` = {string: }\n- `orientation` = {string: portrait or landscape}\n- `hub` = {string: url (local /cloud URL) - If local hub - value will be given in defaults section, if cloud specific then value given in scheme section'}\n\n## Android specific\n- `avd` = {string: the name of the avd to boot}\n- `avdArgs` = {string: arguments to pass in to specify behaviors of the emulator i.e. \"-no-window -no-boot-anim -no-snapshot -skin 480x800\".  See [Android Developer Docs](https://developer.android.com/studio/run/emulator-commandline#common) for more arguments.}\n- `appActivity` = {string: the name of the activity that starts the app}\n- `appWaitActivity` = {string: the name of the activity to wait for}\n- `intentCategory` = {string: i.e. android.intent.category.LEANBACK_LAUNCHER}\n\n## iOS specific\n- `xcodeSigningId` = {string: the signing id to use to load the app on a device, usually \"iPhone Developer\"}\n- `xcodeOrgId` = {string: the org id to use to sign the app}\n\n\n# Inline Actions\n- ```click(By)```\n- ```setText(By, text)```\n- ```getText(By)```\n- ```isPresent(By)```\n- ```isPresentWait(By)```\n- ```getAttribute(By, attribute)```\n- ```swipe(SwipeElementDirection, By)```\n- etc.\n\n# Inline validations\nThis is one of the most important features that I want to _*accentuate*_.\n- ```validateText```\n- ```validateTextNot```\n- ```validatePresent```\n- ```validateNotPresent```\n- ```validateTextPresent```\n- ```validateTextNotPresent```\n\nAll of these methods are able to be called in-line, and fluently without ever having to break your tests.\n\n# Platform Identifier Annotation\n\nInitiate in BasePage:\n\n    public BasePage(Locomotive driver) {\n        this.driver = driver;\n        PageFactory.initElements(new AppiumFieldDecorator(getDriver().getAppiumDriver()), this);\n    }\n    \nUse in Pages:    \n    \n    import io.appium.java_client.pagefactory.AndroidFindBy;\n    import io.appium.java_client.pagefactory.iOSXCUITFindBy;\n    \n        @iOSXCUITFindBy(id = \"accounts_tab\")\n        @AndroidFindBy(id = \"tab_accounts\")\n        private MobileElement ACCOUNT_TAB;\n\n# Pull requests\nTo contribute, fork our project on GitHub, then submit a pull request to our master branch. (If you're a collaborator, just branch off of master)\n\n# Release process\nWe follow [trunk-based development](https://trunkbaseddevelopment.com/).\n \n 1. Create a branch off of `master` and set the version # and remove `-SNAPSHOT`. This can be done in the feature-branch you are working on.\n 2. If approved merge branch into `master`. This will trigger the upload to Maven.\n 3. Tag the merge commit in the master branch. `git tag 0.20.0 cdd9fad`\n 4. Push Tag to Remote. `git push origin 0.20.0`\n 5. Create Release in Github and add Release Notes, select the pushed up tag.\n 6. Go to Sonatype, `Close` then `Release` the artifact.\n 7. Releasing will move the components into the release repository of OSSRH where it will be synced to the Central Repositories\n\n# Use with Sauce Labs\n*Note: it is recommended you create a scheme for sauce labs testing when possible*\n\n 1. get an API token for your sauce labs account\n 2. upload the .app file as a zip to temporary [sauce storage](https://wiki.saucelabs.com/display/DOCS/Uploading+Mobile+Applications+to+Sauce+Storage+for+Testing)\n 3. set the hub property to connect to saucelabs `https://\u003clogin-name\u003e:\u003cAPI-token\u003e@ondemand.saucelabs.com:443/wd/hub`\n 4. set the appFile property to `sauce-storage:\u003czip-filename\u003e.zip`\n 5. run the test with a scheme set\n \n ```\nsauce-android-mock:\n  hub: https://${SAUCE_USERNAME}:${SAUCE_ACCESS_KEY}@ondemand.saucelabs.com:443/wd/hub\n  sauceUserName: ${SAUCE_USERNAME}\n  sauceAccessKey: ${SAUCE_ACCESS_KEY}\n  appFile: sauce-storage:${APP_FILENAME}\n```\n\n # Dependency Updates\n \n We're using [Gradle Versions Plugin](https://github.com/ben-manes/gradle-versions-plugin) to help find out-of-date dependencies. \n  \n To use: `./gradlew dependencyUpdates` \n\nLicense\n-------\n\n    Copyright 2016 Jossay Jacobo\n\n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillowtreeapps%2Fconductor-mobile","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwillowtreeapps%2Fconductor-mobile","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillowtreeapps%2Fconductor-mobile/lists"}