New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve Appium support in Nightwatch #3519
Merged
Merged
Changes from 15 commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
0531906
Automatically start appium server in Nightwatch.
garg3133 e6846e9
Create separate startServer method in AppiumServer.
garg3133 752812a
Convert relative paths to absolute paths for Appium.
garg3133 124b46e
Remove appium_version, for now.
garg3133 f9d4c14
Use chromedriver npm package if path not explicitely passed.
garg3133 39eca9f
Add tests for appium session and service builder.
garg3133 f058e1f
Add more tests for changes.
garg3133 9d56c82
Fix testAppiumOptions tests.
garg3133 a8d2c11
Add backward compatibility for browserName=null.
garg3133 8916448
Skip Appium's createSessionOptions for BrowserStack.
garg3133 709fd41
Fix tests.
garg3133 7b40016
Fix client.click() test.
garg3133 c76e481
isAppium -> use_appium
garg3133 e6c85aa
Remove the logic for converting relative paths to absolute for Appium.
garg3133 e000786
Resolve BrowserStack related issues.
garg3133 1167538
Create separate classes for Automate and AppAutomate.
garg3133 d7a996e
Modify BrowserStack's folder structure.
garg3133 bf62d81
Fix appium server tests.
garg3133 48bb1b9
Fix import paths.
garg3133 273af20
Add browserstack transport and createSession tests.
garg3133 27ba564
Increase appium server startup timeout to 15sec.
garg3133 54587b1
Create a factory method to create service.
garg3133 0706064
AppiumMixin -> AppiumBaseServer.
garg3133 79bebbb
Pass udid using --deviceId flag.
garg3133 019b395
Fix failing tests.
garg3133 e7fac99
Remove unused function from testAppiumServer.
garg3133 File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
const path = require('path'); | ||
const {WebDriver} = require('selenium-webdriver'); | ||
const {Executor} = require('selenium-webdriver/http'); | ||
const TransportFactory = require('../factory'); | ||
const SeleniumServer = require('./selenium'); | ||
const AppiumServiceBuilder = require('./service-builders/appium'); | ||
const http = require('selenium-webdriver/http'); | ||
const {isObject} = require('../../utils'); | ||
|
||
|
||
module.exports = class AppiumServer extends SeleniumServer { | ||
static startServer(settings) { | ||
const Options = require('./options.js'); | ||
const opts = new Options({settings}); | ||
opts.updateWebdriverPath(); | ||
|
||
const appiumService = new AppiumServiceBuilder(settings); | ||
|
||
const outputFile = settings.webdriver.log_file_name || ''; | ||
appiumService.setOutputFile(outputFile); | ||
|
||
return appiumService; | ||
} | ||
|
||
get defaultBrowser() { | ||
return null; | ||
} | ||
|
||
get ServiceBuilder() { | ||
return AppiumServiceBuilder; | ||
} | ||
|
||
get defaultServerUrl() { | ||
return 'http://127.0.0.1:4723'; | ||
} | ||
|
||
get defaultPort() { | ||
return 4723; | ||
} | ||
|
||
get defaultPathPrefix() { | ||
return '/wd/hub'; | ||
} | ||
|
||
createSessionOptions(argv) { | ||
// break 'appium:options' to individual configs | ||
if (isObject(this.desiredCapabilities['appium:options'])) { | ||
const appiumOptions = this.desiredCapabilities['appium:options']; | ||
for (let key of Object.keys(appiumOptions)) { | ||
const value = appiumOptions[key]; | ||
|
||
if (!key.startsWith('appium:')) { | ||
key = `appium:${key}`; | ||
} | ||
this.desiredCapabilities[key] = value; | ||
} | ||
|
||
delete this.desiredCapabilities['appium:options']; | ||
} | ||
|
||
// if `appium:chromedriverExecutable` is present and left blank, | ||
// assign the path of binary from `chromedriver` NPM package to it. | ||
if (this.desiredCapabilities['appium:chromedriverExecutable'] === '') { | ||
const chromedriver = this.seleniumCapabilities.getChromedriverPath(); | ||
if (chromedriver) { | ||
this.desiredCapabilities['appium:chromedriverExecutable'] = chromedriver; | ||
} | ||
} | ||
|
||
return super.createSessionOptions(argv) || this.desiredCapabilities; | ||
} | ||
|
||
createDriver({options = this.desiredCapabilities} = {}) { | ||
// If creating a session with BrowserStack Automate, use Selenium's session builder. | ||
if (TransportFactory.usingBrowserstack(this.settings) && this.productNamespace === 'automate') { | ||
return super.createDriver({options}); | ||
} | ||
garg3133 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
const httpClient = new http.HttpClient(this.getServerUrl()); | ||
|
||
return WebDriver.createSession(new Executor(httpClient), options); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
98 changes: 98 additions & 0 deletions
98
lib/transport/selenium-webdriver/service-builders/appium.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
const {SeleniumServer, DriverService} = require('selenium-webdriver/remote'); | ||
const {getFreePort} = require('../../../utils'); | ||
const BaseService = require('./base-service.js'); | ||
|
||
class AppiumService extends DriverService { | ||
constructor(server_path, opt_options) { | ||
const options = opt_options || {}; | ||
const {args, default_path_prefix} = options; | ||
|
||
const port = options.port; | ||
if (port !== AppiumServiceBuilder.defaultPort && !args.includes('--port')) { | ||
args.unshift('--port', port); | ||
} | ||
|
||
let cmd = 'node'; | ||
if (server_path.startsWith('appium')) { | ||
cmd = server_path; | ||
} else { | ||
args.unshift(server_path); | ||
} | ||
|
||
super(cmd, { | ||
loopback: options.loopback, | ||
port, | ||
args, | ||
path: default_path_prefix, | ||
env: options.env, | ||
stdio: options.stdio | ||
}); | ||
} | ||
} | ||
|
||
class AppiumServiceBuilder extends BaseService { | ||
static get serviceName() { | ||
return 'Appium Server'; | ||
} | ||
|
||
static get defaultPort() { | ||
return 4723; | ||
} | ||
|
||
get npmPackageName() { | ||
return 'appium'; | ||
} | ||
|
||
get outputFile() { | ||
return this._outputFile + '_appium-server.log'; | ||
} | ||
|
||
get defaultPort() { | ||
return AppiumServiceBuilder.defaultPort; | ||
} | ||
|
||
get serviceName() { | ||
return 'Appium Server'; | ||
} | ||
|
||
get downloadMessage() { | ||
return 'install Appium globally with "npm i -g appium" command, \n and set ' + | ||
'"selenium.server_path" config option to "appium".'; | ||
} | ||
|
||
/** | ||
* @param {Capabilities} opts | ||
* @returns {Promise<void>} | ||
*/ | ||
async createService(opts = {}) { | ||
const {port} = this; | ||
const options = new SeleniumServer.Options(); | ||
options.port = port || await getFreePort(); | ||
const {server_path, default_path_prefix = '/wd/hub'} = this.settings.webdriver; | ||
|
||
const introMsg = `Starting Appium Server on port ${options.port}...`; | ||
|
||
if (opts.showSpinner) { | ||
opts.showSpinner(`${introMsg}\n\n`); | ||
} else { | ||
// eslint-disable-next-line | ||
console.info(introMsg); | ||
} | ||
|
||
// TODO: read the log_path and add it to cliArgs | ||
// above TODO is copied from ./selenium.js | ||
options.args = this.cliArgs; | ||
options.default_path_prefix = default_path_prefix; | ||
|
||
if (this.hasSinkSupport() && this.needsSinkProcess()) { | ||
this.createSinkProcess(); | ||
options.stdio = ['pipe', this.process.stdin, this.process.stdin]; | ||
} | ||
|
||
this.service = new AppiumService(server_path, options); | ||
|
||
return this.service.start(); | ||
} | ||
} | ||
|
||
module.exports = AppiumServiceBuilder; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should use a factory here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean
factory
as variable name or use aTransportFactory
class method to decide whether appium is being used or not?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use a factory to create the server
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please check 54587b1 if it is fine.