* Update contributing docs

* Fix some links and examples

* Address comments
This commit is contained in:
Isaac A. Murchie 2018-02-12 07:58:15 -05:00 коммит произвёл GitHub
Родитель 77fe650dd6
Коммит be2acb207c
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
13 изменённых файлов: 246 добавлений и 535 удалений

Просмотреть файл

@ -8,7 +8,7 @@ Note that no matter how you contribute, your participation is governed by our
### Make changes to the Appium code or docs
Fork the project, make a change, and send a pull request! Please have a look at
our [Style Guide](/docs/en/contributing-to-appium/style-guide-2.0.md) before
our [Style Guide](/docs/en/contributing-to-appium/style-guide.md) before
getting to work. Please make sure the unit and functional tests pass before
sending a pull request; for more information on how to run tests, keep reading!

Просмотреть файл

@ -2,7 +2,7 @@
你想从源码运行Appium并帮助修复BUG和添加功能吗
真棒只需要fork工程添加一个修改然后发送pull请求即可
在开始之前请阅读我们的代码风格指南([Style Guide](style-guide-2.0.md)。
在开始之前请阅读我们的代码风格指南([Style Guide](style-guide.md)。
在发送pull请求前请确保通过单元和功能测试关于如何运行测试等更多信息请继续阅读
首先确保你阅读README文件且按照设置说明走。

Просмотреть файл

@ -63,7 +63,7 @@ node.js的原生支持Appium代码是_被移植_到ES5JS更为广泛支持
### 排查和代码风格
对于所有Appium的JS而言代码外观和使用感觉同样重要。这包括样式常规编码模式以及我们解决各种问题时使用的
库。你应该熟悉我们新的[ES2015 风格指南](/docs/cn/contributing-to-appium/style-guide-2.0.md)。
库。你应该熟悉我们新的[ES2015 风格指南](/docs/cn/contributing-to-appium/style-guide.md)。
当转化时Appium包将自动运行JSHint或其他lint工具并在代码不符合我们规范的时候提供警告或错误反馈。
这些工具不一定能顾全我们关心的种种风格问题所以我们在review代码的时候也应该注意代码规范问题。这不是
吹毛求疵,而是为了有一个整洁,一致并且可读的代码库。
@ -102,7 +102,7 @@ _FORCE_LOGS=1 <command> # 显示测试运行期间的模块日志输出
任何非Appium主包的发布流程都是非常简洁明了的请注意如果你想要发布它你需要成为一个NPM的所有者。
所有权由Appium提交者管理 如果你对所有者有任何疑问,请联系@jlipps 或者 @imurchie)。
0. `rm -rf node_modules && npm install` 并运行测试以确保全新安装正常工作
0. `rm -rf node_modules && rm -rf package-lock.json && npm install` 并运行测试以确保全新安装正常工作
0. 根据[SemVer](http://semver.org/) 规则决定我们是否需要发布一个补丁(漏洞修复),微调(功能)或者是主要(迭代)(请参考 [how SemVer works with NPM](https://docs.npmjs.com/getting-started/semantic-versioning).
0. 通过任何适当的更改和提交来更新CHANGELOG以README文件。大多数子包没有CHANGELOG。
0. 通过适当的版本类型运行 `npm version <version-type>`
@ -121,8 +121,8 @@ _FORCE_LOGS=1 <command> # 显示测试运行期间的模块日志输出
因此有必要在发布过程中手动管理它。 它需要与对`package.json`的更改一起提交到GitHub。
0. 如果 NPM shrinkwrap JSON 文件存在,请移除.
0. `rm -rf node_modules && npm install` 并运行测试以确保全新安装正常工作
0. `rm -rf node_modules && npm install --production` 以获取仅production部分.
0. `rm -rf node_modules && rm -rf package-lock.json && npm install` 并运行测试以确保全新安装正常工作
0. `rm -rf node_modules && rm -rf package-lock.json && npm install --production` 以获取仅production部分.
0. `npm shrinkwrap` 来编写新的 NPM shrinkwrap JSON 文件.
0. 根据SemVer来决定我们是否需要发布一个补丁漏洞修复微调功能或者是主要迭代
0. 用合适的新版本信息来更新`package.json`

Просмотреть файл

@ -2,11 +2,20 @@
So you want to run Appium from source and help fix bugs and add features?
Great! Just fork the project, make a change, and send a pull request! Please
have a look at our [Style Guide](style-guide-2.0.md) before getting to work.
have a look at our [Style Guide](style-guide.md) before getting to work.
Please make sure the unit and functional tests pass before sending a pull
request; for more information on how to run tests, keep reading!
Make sure you read and follow the setup instructions in the README first.
### Node.js
Appium is written in JavaScript, and run with the [Node.js](https://nodejs.org/) engine. Currently
version 6+ is supported. While Node.js can be installed globally on the system,
a version manager is _highly_ recommended.
* NVM - [https://github.com/creationix/nvm](https://github.com/creationix/nvm)
* N - [https://github.com/tj/n](https://github.com/tj/n)
Your Node.js installation will include the [NPM](https://www.npmjs.com/) package manager, which Appium
will need in order to manage dependencies. Appiums supports NPM version 3+.
### Setting up Appium from Source
@ -17,57 +26,43 @@ instance of an Appium server, and then run your test.
The quick way to get started:
```center
```
git clone https://github.com/appium/appium.git
cd appium
npm install
gulp transpile # requires gulp, see below
npm install -g authorize-ios # for ios only
authorize-ios # for ios only
npm run build
node .
```
### Hacking on Appium
Make sure you have `ant`, `maven`, `adb` installed and added to system `PATH`, also you
would need the android-16 sdk (for Selendroid) and android-19 sdk installed.
From your local repo's command prompt, install the following packages using the
following commands (if you didn't install `node` using Homebrew, you might have
to run `npm` with sudo privileges):
```center
npm install -g mocha
npm install -g gulp
npm install -g gulp-cli
npm install -g appium-doctor && appium-doctor --dev
npm install
gulp transpile
Install the [appium-doctor](https://github.com/appium/appium-doctor) tool, and run it to verify all of the
dependencies are set up correctly (since dependencies for building Appium
are different from those for simply running it):
```
npm install -g appium-doctor
appium-doctor --dev
```
Install the Node.js dependencies:
```
npm install
```
The first two commands install test and build tools (`sudo` may not be
necessary if you installed node.js via Homebrew). The third command verifies
that all of the dependencies are set up correctly (since dependencies for
building Appium are different from those for simply running Appium) and fourth
command installs all app dependencies and builds supporting binaries and test
apps. The final command transpiles all the code so that `node` can run it.
When pulling new code from GitHub, if there are changes to `package.json` it
is necessary to remove the old dependencies and re-run `npm install`:
```center
rm -rf node_modules
npm install
gulp transpile
```
rm -rf node_modules && rm -rf package-lock.json && npm install
```
At this point, you will be able to start the Appium server:
```center
```
node .
```
See [the server documentation](/docs/en/writing-running-appium/server-args.md)
for a full list of arguments.
for a full list of command line arguments that can be used.
#### Hacking with Appium for iOS
@ -80,36 +75,37 @@ have to modify your `/etc/authorization` file in one of two ways:
2. Run the following command which automatically modifies your
`/etc/authorization` file for you:
```center
```
npm install -g authorize-ios
sudo authorize-ios
```
At this point, run:
```center
rm -rf node-modules
npm install
gulp transpile
```
rm -rf node_modules && rm -rf package-lock.json && npm install
```
Now your Appium instance is ready to go. Run `node .` to kick up the Appium server.
#### Hacking with Appium for Android
To work on Android, make sure you have `ant`, `maven`, and `adb` installed
and added to system `PATH` environment variable. Also you would need the
android-16 sdk (for `Selendroid`) and android-19+ sdk installed.
From your local repo's command prompt, install/run the following:
Set up Appium by running:
```center
rm -rf node-modules
npm install
gulp transpile
```
rm -rf node_modules && rm -rf package-lock.json && npm install
```
Make sure you have one and only one Android emulator or device running, e.g.,
by running this command in another process (assuming the `emulator` command is
on your path):
```center
```
emulator -avd <MyAvdName>
```
@ -123,11 +119,43 @@ update everything necessary. You will also need to do this when Appium bumps
its version up. Prior to running `npm install` it is recommended to remove
all the old dependencies in the `node_modules` directory:
```center
rm -rf node-modules
npm install
gulp transpile
```
rm -rf node_modules && rm -rf package-lock.json && npm install
```
### Different packages
Appium is made up of a number of different packages. While it is often possible
to work in a single package, it is also often the case that work, whether fixing
a bug or adding a new feature, requires working on multiple packages simultaneously.
Unfortunately the dependencies installed when running `npm install` are those that
have already been published, so some work is needed to link together local development
versions of the packages that are being worked on.
In the case where one package, `A`, depends on another package, `B`, the following steps
are necessary to link the two:
1. In one terminal, enter into package `B`
```
cd B
```
2. Use [NPM link](https://docs.npmjs.com/cli/link) to create symbolic link to this package
```
npm link
```
3. In another terminal, enter into package `A`
```
cd A
```
4. Use [NPM link](https://docs.npmjs.com/cli/link) to link the dependent package `B` to the development version
```
npm link B
```
Now the version of `B` that `A` uses will be your local version. Remember, however, that
changes made to the JavaScript will only be available when they have been transpiled, so
when you are going to test from package `A`, run `npm run build` in the directory for
package `B`.
### Running Tests
@ -138,16 +166,23 @@ system is set up properly for the platforms you desire to test on.
Once your system is set up and your code is up to date, you can run unit tests
with:
```center
gulp once
```
npm run test
```
You can run functional tests for all supported platforms (after ensuring that
Appium is running in another window with `node .`) with:
```center
gulp e2e-test
```
npm run e2e-test
```
Before committing code, please run `gulp once` to execute some basic tests and
check your changes against code quality standards.
### Committing code
Each Appium package installs a pre-commit hook which will run the [linter](https://eslint.org/) and
the unit tests before the commit is made. Any error in either of these will stop
the commit from occurring.
Once code is committed and a [pull request](https://help.github.com/articles/about-pull-requests/)
is made to the correct Appium respository on [GitHub](https://github.com/), Appium build system
will run all of the functional tests.

Просмотреть файл

@ -0,0 +1,16 @@
## Appium development commands
Each Appium package has a number of NPM scripts that are used to automate
development tasks:
| Task | Description |
|------------------|--------------------------------------------------------|
| npm run build | Transpile code into the `build` directory |
| npm run lint | Runs ESLint |
| npm run test | Cleans, lints, transpiles, and runs unit tests |
| npm run e2e-test | Tranpiles and runs functional tests |
| npm run watch | Automatically runs `test` command when code is changed |
| npm run mocha | Gives access to `mocha` test runner |
In addition, the main Appium package has a task `npm generate-docs` which generates
the command documentation.

Просмотреть файл

@ -93,7 +93,7 @@ Most Appium packages have this as the default behavior when running `gulp`.
It's important for all of Appium's JS to look and feel the same. This includes
style conventions as well as coding patterns and which libraries we use to
solve various problems. You should get familiar with our new [ES2015 Style
Guide](/docs/en/contributing-to-appium/style-guide-2.0.md). When transpiling,
Guide](/docs/en/contributing-to-appium/style-guide.md). When transpiling,
Appium packages will automatically run ESLint or other lint tools and provide
warning or error feedback if the code doesn't conform to our style. These tools
are not necessarily exhaustive of the kinds of style issues we care about, so
@ -147,12 +147,12 @@ package if you want to publish it. Ownership is managed by the Appium
committers; talk to @jlipps or @imurchie if you believe you should be an owner
and are not):
0. `rm -rf node_modules && npm install` and run tests to make sure a clean install works.
0. Determine whether we have a patch (bugfix), minor (feature), or major (breaking) release according to the principles of [SemVer](http://semver.org/) (see also this explanation of [how SemVer works with NPM](https://docs.npmjs.com/getting-started/semantic-versioning)).
0. Update the `CHANGELOG` and/or `README` with any appropriate changes and commit. Most subpackages don't have a `CHANGELOG`.
0. Run `npm version <version-type>` with the appropriate version type.
0. Push the appropriate branch to GitHub, and don't forget to include the `--tags` flag to include the tag just created by `npm version`.
0. Run `npm publish` (with `--tag beta` if this isn't an official release).
1. `rm -rf node_modules && rm -rf package-lock.json && npm install` and run tests to make sure a clean install works.
1. Determine whether we have a patch (bugfix), minor (feature), or major (breaking) release according to the principles of [SemVer](http://semver.org/) (see also this explanation of [how SemVer works with NPM](https://docs.npmjs.com/getting-started/semantic-versioning)).
1. Update the `CHANGELOG` and/or `README` with any appropriate changes and commit. Most subpackages don't have a `CHANGELOG`.
1. Run `npm version <version-type>` with the appropriate version type.
1. Push the appropriate branch to GitHub, and don't forget to include the `--tags` flag to include the tag just created by `npm version`.
1. Run `npm publish` (with `--tag beta` if this isn't an official release).
For the main Appium packages, all the above steps must be taken, but with
several changes. One reason is that for the main package we use NPM shrinkwrap
@ -175,20 +175,20 @@ checked in to GitHub along with changes to `package.json`. With npm 5+ there is
also a `package-lock.json` file produced. During the shrinkwrap process this is
converted into the `npm-shrinkwrap.json` file.
0. Remove the NPM shrinkwrap and package-lock JSON files if they exists.
0. `rm -rf node_modules && npm install` and run tests to make sure a clean install works.
0. Determine whether we have a `patch` (bugfix), `minor` (feature), or `major` (breaking) release according to the principles of SemVer.
0. Update `package.json` with the appropriate new version.
0. Update the CHANGELOG/README with appropriate changes and submit for review as a PR, along with shrinkwrap and `package.json` changes. Wait for it to be merged, then pull it into the release branch.
0. `rm -rf node_modules && npm install --production` to get just the production dependencies.
0. `npm shrinkwrap` to write the new NPM shrinkwrap JSON file, and commit this file.
0. Create a tag of the form `v<version>` on the release branch (usually a minor branch like `1.5` or `1.4`), with: `git tag -a v<version>`, e.g., `git tag -a v1.5.0`. This is not necessary for beta versions.
0. Push the tag to upstream: `git push --tags <remote> <branch>`
0. Install dev dependencies (or at least `gulp` and `appium-gulp-plugins`), and undo the changes to the NPM shrinkwrap JSON file (e.g., `git checkout -- npm-shrinkwrap.json`).
0. Run `npm publish` (with `--tag beta` if this isn't an official release).
0. Remove the NPM shrinkwrap JSON file from Git and push the changes
0. Update the docs at appium.io. Check out the appium.io repo from github, check out the `gh-pages` branch and pull latest. Run `rake publish`.
0. Create a new release on GitHub: go to `https://github.com/appium/appium/releases/tag/v<VERSION>` and hit "Edit Tag". Make the release name `<VERSION>` (e.g., `2.0.5`), then paste in the changelog (but not the changelog header for this version). If it's a beta release, mark as pre-release.
0. Create a new post on discuss.appium.io announcing the release. Post it in the "News" category. Paste in the changelog and any choice comments. Pin it and unpin the previous release post.
0. Begin process of releasing `appium-desktop`.
0. Notify @jlipps to so he can tweet a link to the discuss post.
1. Remove the NPM shrinkwrap and package-lock JSON files if they exists.
1. `rm -rf node_modules && npm install` and run tests to make sure a clean install works.
1. Determine whether we have a `patch` (bugfix), `minor` (feature), or `major` (breaking) release according to the principles of SemVer.
1. Update `package.json` with the appropriate new version.
1. Update the CHANGELOG/README with appropriate changes and submit for review as a PR, along with shrinkwrap and `package.json` changes. Wait for it to be merged, then pull it into the release branch.
1. `rm -rf node_modules && npm install --production` to get just the production dependencies.
1. `npm shrinkwrap` to write the new NPM shrinkwrap JSON file, and commit this file.
1. Create a tag of the form `v<version>` on the release branch (usually a minor branch like `1.5` or `1.4`), with: `git tag -a v<version>`, e.g., `git tag -a v1.5.0`. This is not necessary for beta versions.
1. Push the tag to upstream: `git push --tags <remote> <branch>`
1. Install dev dependencies (or at least `gulp` and `appium-gulp-plugins`), and undo the changes to the NPM shrinkwrap JSON file (e.g., `git checkout -- npm-shrinkwrap.json`).
1. Run `npm publish` (with `--tag beta` if this isn't an official release).
1. Remove the NPM shrinkwrap JSON file from Git and push the changes
1. Update the docs at appium.io. Check out the appium.io repo from github, check out the `gh-pages` branch and pull latest. Run `rake publish`.
1. Create a new release on GitHub: go to `https://github.com/appium/appium/releases/tag/v<VERSION>` and hit "Edit Tag". Make the release name `<VERSION>` (e.g., `2.0.5`), then paste in the changelog (but not the changelog header for this version). If it's a beta release, mark as pre-release.
1. Create a new post on discuss.appium.io announcing the release. Post it in the "News" category. Paste in the changelog and any choice comments. Pin it and unpin the previous release post.
1. Begin process of releasing `appium-desktop`.
1. Notify @jlipps to so he can tweet a link to the discuss post.

Просмотреть файл

@ -1,15 +0,0 @@
## Appium gulp commands
[Gulp](http://gulpjs.com) is like `make` for Node.js! We use it to automate all
kinds of appium dev tasks. Here's what you can do:
|Task|Description|
|----|-----------|
|gulp once|Cleans, lints, transpiles and runs unit tests|
|gulp watch|Automatically runs `gulp once` when code changes|
|gulp lint|Runs JSLint|
|gulp jshint|Runs JSHint|
|gulp transpile|Transpiles our ES7/ES2015 code to ES5, generates `/build` directory + contents|
|gulp unit-test|Runs unit tests|
|gulp e2e-test|Runs e2e tests|
|gulp docs|Generates docs/en/writing-running-appium/server-args.md doc|

Просмотреть файл

@ -44,10 +44,10 @@ files in `docs/en/commands` and then they need to be committed and pushed.
### Adding Documents to Appium.io
Markdown files in `docs/` aren't automatically added to the site. To add a document to https://appium.io
Markdown files in `docs/` aren't automatically added to the site. To add a document to [appium.io](https://appium.io)
you need to add it as an entry in the appropriate location in the table of
contents, [toc.js](https://github.com/appium/appium/blob/master/docs/toc.js)
#### Publishing
To publish documentation on appium.io see [appium.io](https://github.com/appium/appium.io).
To publish documentation on [appium.io](https://appium.io) see [appium.io (Github)](https://github.com/appium/appium.io).

Просмотреть файл

@ -1,256 +0,0 @@
## Style guide for contributors
Thanks for your contribution to Appium! Here are the principles we use when
writing javascript. Please conform to these so we can merge your pull request
without going back and forth about style. The main principle is: *make your
code look like the surrounding code*.
### Rebasing
Commits in a pull request should consist of [logical changes](https://github.com/appium/appium/pull/920#issuecomment-21588553).
If there are multiple authors, make sure each author has their own commit.
It's not a good idea to modify author information. Merge commits should be
rebased out of pull requests.
### Linting
All code (except for code in `bootstrap.js` which uses proprietary Apple
methods) must pass JSLint. To check your code, you can simply run `grunt
lint` from the Appium repo dir. If you've created a new .js file,
please make sure it is covered by the wildcards in `grunt.js` or that it is
added specifically.
It's easy to have your code linted as you type, which makes the whole process
much smoother. We like [jshint](http://www.jshint.com),
which has integrations with a lot of source code editors. The file `
.jshintrc` is checked into the repo, so by adding jshint to your editor, you'll
take advantage of the linting.
Since jshint does not enforce code style anymore, we also use
[jscs](https://github.com/mdevils/node-jscs), for which it also exists some
source editor integrations.
These configuration files define the warnings you will see in your favorite
editor. See [this page for jshint](http://www.jshint.com/platforms/) and
[this page for jscs](https://github.com/mdevils/node-jscs#friendly-packages) to
get the list of editors and platforms supported and how setup your editor for
automatic linting.
### Style notes
We use a future version of JavaScript and take advantage of the Babel
transpiler to render it down to what is supported by current versions of
Node.js. We use ES2015 (link needed) (formerly called ES6) with some
not-yet-standard features, namely `async/await` (link needed). This style guide
must be followed diligently in all Appium contributions!
* Use two spaces for indentation, *no tabs*
* Use single spaces around operators
```javascript
var x = 1;
```
not
```javascript
var x=1;
```
* Spaces after commas and colons in lists, objects, function calls, etc...
```javascript
var x = myFunc("lol", {foo: bar, baz: boo});
```
not
```javascript
var x = myFunc("lol",{foo:bar,baz:boo});
```
* Always end statements with semicolons
* Comma-first
```javascript
var x = {
foo: 'bar'
, baz: 'boo'
, wuz: 'foz'
};
```
* Brackets for `function`, `if`, etc... go on same line, `else` gets sandwiched
```javascript
if (foo === bar) {
// do something
} else {
// do something else
}
```
* Space after `if`, `for`, and `function`:
```javascript
if (foo === bar) {
```
```javascript
for (var i = 0; i < 10; i ++) {
```
```javascript
var lol = function (foo) {
```
not
```javascript
if(foo === bar) {
```
```javascript
for(var i = 0; i < 10; i ++) {
```
```javascript
var lol = function(foo) {
```
* Avoid bracketless `if` for one-liners:
```javascript
if (foo === bar) {
foo++;
}
```
not
```javascript
if (foo === bar)
foo++;
```
except in the case of short-circuiting to a callback in the event of an error
```javascript
if (err) return cb(err);
```
* Use `===`, not `==`, and `!==`, not `!=` for no surprises
* Line length shouldn't be longer than 79 characters
* Break up long strings like this:
```javascript
myFunc("This is a really long string that's longer " +
"than 79 characters so I broke it up, woo");
```
* Comments should line up with code
```javascript
if (foo === 5) {
myFunc(foo);
// foo++;
}
```
not
```javascript
if (foo === 5) {
myFunc(foo);
//foo++;
}
```
* Subclassing by extending prototypes
```javascript
var _ = require('underscore');
var SuperClass = function () {
this.init();
};
SuperClass.prototype.init = function () {
// initialize
};
// Create a subclass
var SubClass = function () {
this.init();
};
_.extend(SubClass.prototype, SuperClass.prototype);
```
* Callbacks are always last in function definitions
```javascript
var foo = function (arg1, arg2, cb) {
...
};
```
* Define functions as variables
```javascript
var myFunc = function (a, b, c) {};
```
not
```javascript
function myFunc (a, b, c) {}
```
* Variable names should be camelCased:
```javascript
var myVariable = 42;
```
not
```javascript
var my_variable = 42;
```
* Check for undefined
```javascript
typeof myVariable === "undefined"
```
not
```javascript
myVariable === undefined
```
* Define a variable with a default value
```javascript
var x = y || z;
```
not
```javascript
var x = y ? y : z;
```
### Test Style:
Keep on the same line if it makes sense semantically and length is not an issue:
Examples:
```javascript
driver.elementByTagName('el1').should.become("123")
.nodeify(done);
driver
.elementsByTagName('el1').should.eventually.have.length(0)
.nodeify(done);
```
Alternatively use extra indents to improve readability:
```javascript
h.driver
.elementById('comments')
.clear()
.click()
.keys("hello world")
.getValue()
.should.become("hello world")
.elementById('comments')
.getValue().should.become("hello world")
.nodeify(done);
h.driver
.execute("'nan'--")
.should.be.rejectedWith("status: 13")
.nodeify(done);
```

Просмотреть файл

@ -2,8 +2,17 @@
Thanks for your contribution to Appium! Here are the principles we use when
writing javascript. Please conform to these so we can merge your pull request
without going back and forth about style. The main principle is: *make your
code look like the surrounding code*.
without going back and forth about style. The main principle is: *make your
code look like the surrounding code*.
### JavaScript
With the exception of the code that runs on the devices themselves
([appium-uiautomator2-server](https://github.com/appium/appium-uiautomator2-server) for
Android, [WebDriverAgent](https://github.com/appium/WebDriverAgent) for iOS), Appium is written in [Node.js](https://nodejs.org/). If you are
not familiar with JavaScript, please familiarize yourself before attempting
to modify the code. There are plenty of good, free resources (see, for example,
[You Don't Know JavaScript](https://github.com/getify/You-Dont-Know-JS)).
### Rebasing
@ -14,266 +23,187 @@ rebased out of pull requests.
### Linting
All code (except for code in `bootstrap.js` which uses proprietary Apple
methods) must pass JSLint. To check your code, you can simply run `grunt
lint` from the Appium repo dir. If you've created a new .js file,
please make sure it is covered by the wildcards in `grunt.js` or that it is
added specifically.
All code must pass [ESLint](https://eslint.org/). To check your code, you can simply run `npm run lint`
from the Appium repo dir. The configuration is specified in the
[eslint-config-appium](https://github.com/appium/eslint-config-appium) package.
It's easy to have your code linted as you type, which makes the whole process
much smoother. We like [jshint](http://www.jshint.com),
which has integrations with a lot of source code editors. The file `
.jshintrc` is checked into the repo, and its contents are:
```json
{
"laxcomma": true,
"strict": true,
"undef": true,
"unused": true,
"node": true,
"eqeqeq": true,
"trailing": true,
"indent": 2
}
```
Since jshint does not enforce code style anymore, we also use
[jscs](https://github.com/mdevils/node-jscs), for which it also exists some
source editor integrations. The configuration file is:
```json
{
"excludeFiles": ["submodules/**", "node_modules/**",
"./lib/server/static/**", "./lib/devices/firefoxos/atoms/*.js",
"./test/harmony/**/*.js", "./sample-code/examples/node/**/*-yiewd.js",
"./sample-code/apps/**", "./sample-code/examples/php/vendor/**"],
"requireCurlyBraces": ["for", "while", "do", "try", "catch"],
"requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch",
"return", "try", "catch", "function"],
"disallowMixedSpacesAndTabs": true,
"disallowTrailingWhitespace": true,
"requireSpacesInFunctionExpression": {
"beforeOpeningCurlyBrace": true
}
}
```
These configuration files define the warnings you will see in your favorite
editor. See [this page for jshint](http://www.jshint.com/platforms/) and
[this page for jscs](https://github.com/mdevils/node-jscs#friendly-packages) to
get the list of editors and platforms supported and how setup your editor for
automatic linting.
Most modern editors have integration with ESLint. See [here](https://eslint.org/docs/user-guide/integrations) for details.
### Style notes
We use a future version of JavaScript and take advantage of the [Babel](https://babeljs.io/)
transpiler to render it down to what is supported by current versions of
[Node.js](https://nodejs.org/). We use [ES2015](https://babeljs.io/learn-es2015/) (formerly called ES6) with some
not-yet-standard features, namely [async/await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function). This style guide
must be followed diligently in all Appium contributions! Luckily, linting
will enforce most of these rules!
* Use two spaces for indentation, *no tabs*
* Use single spaces around operators
```javascript
var x = 1;
```js
let x = 1;
```
not
```javascript
var x=1;
```js
let x=1;
```
* Spaces after commas and colons in lists, objects, function calls, etc...
```javascript
var x = myFunc("lol", {foo: bar, baz: boo});
```js
let x = myFunc('lol', {foo: bar, baz: boo});
```
not
```javascript
var x = myFunc("lol",{foo:bar,baz:boo});
```
* Always end statements with semicolons
* Comma-first
```javascript
var x = {
foo: 'bar'
, baz: 'boo'
, wuz: 'foz'
};
```js
let x = myFunc('lol',{foo:bar,baz:boo});
```
* Always end statements with semicolons (see, for example, [Kent Dodds](https://blog.kentcdodds.com/semicolons-in-javascript-a-preference-dd8fc8b80895))
* Brackets for `function`, `if`, etc... go on same line, `else` gets sandwiched
```javascript
```js
if (foo === bar) {
// do something
} else {
// do something else
}
```
not
```js
if (foo === bar)
{
// do something
}
else
{
// do something else
}
```
* Space after `if`, `for`, and `function`:
```javascript
```js
if (foo === bar) {
```
```javascript
for (var i = 0; i < 10; i ++) {
```js
for (let i = 0; i < 10; i ++) {
```
```javascript
var lol = function (foo) {
```js
let lol = function (foo) {
```
not
```javascript
```js
if(foo === bar) {
```
```javascript
for(var i = 0; i < 10; i ++) {
```js
for(let i = 0; i < 10; i ++) {
```
```javascript
var lol = function(foo) {
```js
let lol = function(foo) {
```
* Avoid bracketless `if` for one-liners:
```javascript
```js
if (foo === bar) {
foo++;
}
```
not
```javascript
```js
if (foo === bar)
foo++;
```
except in the case of short-circuiting to a callback in the event of an error
```javascript
if (err) return cb(err);
except in the case of short-circuiting to return/error
```js
if (err) return;
```
```js
if (err) throw new Error(err);
```
* Use `===`, not `==`, and `!==`, not `!=` for no surprises
* Use `===`, not `==`, and `!==`, not `!=` for [no surprises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness)
* Line length shouldn't be longer than 79 characters
* Break up long strings like this:
```javascript
myFunc("This is a really long string that's longer " +
"than 79 characters so I broke it up, woo");
myFunc('This is a really long string that's longer ' +
'than 79 characters so I broke it up, woo');
```
* Comments should line up with code
```javascript
```js
if (foo === 5) {
myFunc(foo);
// foo++;
}
```
not
```javascript
```js
if (foo === 5) {
myFunc(foo);
//foo++;
}
```
* Subclassing by extending prototypes
```javascript
var _ = require('underscore');
var SuperClass = function () {
this.init();
};
SuperClass.prototype.init = function () {
// initialize
};
// Create a subclass
var SubClass = function () {
this.init();
};
_.extend(SubClass.prototype, SuperClass.prototype);
```
* Callbacks are always last in function definitions
```javascript
var foo = function (arg1, arg2, cb) {
...
};
```
* Define functions as variables
```javascript
var myFunc = function (a, b, c) {};
```
not
```javascript
function myFunc (a, b, c) {}
```
* Variable names should be camelCased:
```javascript
var myVariable = 42;
```js
let myVariable = 42;
```
not
```javascript
var my_variable = 42;
```js
let my_variable = 42;
```
* Check for undefined
* Check for `undefined` using Appium's [appium-support](https://github.com/appium/appium-support) package
```javascript
typeof myVariable === "undefined"
```
not
```javascript
myVariable === undefined
```js
util.hasValue(myVariable)
```
* Define a variable with a default value
```javascript
var x = y || z;
```js
let x = y || z;
```
not
```javascript
var x = y ? y : z;
```js
let x = y ? y : z;
```
### Test Style:
Tests are written using [mocha](https://mochajs.org/) and [chai](http://chaijs.com/). The WebDriver
library used is [wd](https://github.com/admc/wd).
Keep on the same line if it makes sense semantically and length is not an issue:
Examples:
```javascript
driver.elementByTagName('el1').should.become("123")
.nodeify(done);
```js
driver.elementByTagName('el1').should.become('123');
driver
.elementsByTagName('el1').should.eventually.have.length(0)
.nodeify(done);
driver
.elementsByTagName('el1').should.eventually.have.length(0);
```
Alternatively use extra indents to improve readability:
```javascript
h.driver
```js
driver
.elementById('comments')
.clear()
.click()
.keys("hello world")
.keys('hello world')
.getValue()
.should.become("hello world")
.should.become('hello world')
.elementById('comments')
.getValue().should.become("hello world")
.nodeify(done);
.getValue().should.become('hello world');
h.driver
.execute("'nan'--")
.should.be.rejectedWith("status: 13")
.nodeify(done);
driver
.execute("'NaN'--")
.should.be.rejectedWith('status: 13');
```

Просмотреть файл

@ -28,27 +28,27 @@ The versioning and release model shape how we set Appium milestones. The next mi
For Appium, the basic flow looks like this:
1. All PRs go to `master` (aka `trunk`).
2. Whoever is leading a release acts as the "release engineer" (RE). When the release is ready to be shared (“Beta" status or better), the RE creates a new branch `v[Major].[Minor].[Patch]-branch`.
3. PRs continue to go to `master`.
4. If the release requires fixes committed to `master`, the RE cherrypicks those commits into the release branch.
5. The release branch can be amended with hotfixes for subsequent patch releases. This allows the team to carefully scope small changesets for quick release. Fixes can also be pulled into previous release branches branches when needed.
6. Rinse, repeat.
1. Whoever is leading a release acts as the "release engineer" (RE). When the release is ready to be shared (“Beta" status or better), the RE creates a new branch `v[Major].[Minor].[Patch]-branch`.
1. PRs continue to go to `master`.
1. If the release requires fixes committed to `master`, the RE cherrypicks those commits into the release branch.
1. The release branch can be amended with hotfixes for subsequent patch releases. This allows the team to carefully scope small changesets for quick release. Fixes can also be pulled into previous release branches branches when needed.
1. Rinse, repeat.
Developers can maintain working branches however they like. These are strictly for personal use. All “official” branches should conform to the model defined above.
### Example
1. Its 1 June. The Appium team plans on releasing 20.1-beta on 15 July and the full 20.1 release on 1 August.
2. For the next six weeks, the team commits their work to `master`.
3. On 15 July, the acting RE creates `20.1-branch`. The first node is tagged “20.1.0 Beta”.
4. One team member begins fixing bugs in the beta. The fixes are committed to `master`.
5. Other contributors begin committing changes that are planned for 20.2. These also go to `master`.
6. The RE cherrypicks the fixes into `20.1-branch`, leaving the other changes on `master`.
7. The team celebrates that all the beta bugs are fixed for the 1 August release.
8. The RE tags HEAD of `20.1-branch` as `20.1.0` and publishes the release.
9. A few weeks later, a crash is discovered in `20.1.0` and users need a fix NOW.
10. The acting RE pulls the crash fix from master into `20.1-branch`, tags HEAD as `20.1.1`, and publishes the hotfix.
11. The cycle repeats once the `20.2` release is ready.
1. For the next six weeks, the team commits their work to `master`.
1. On 15 July, the acting RE creates `20.1-branch`. The first node is tagged “20.1.0 Beta”.
1. One team member begins fixing bugs in the beta. The fixes are committed to `master`.
1. Other contributors begin committing changes that are planned for 20.2. These also go to `master`.
1. The RE cherrypicks the fixes into `20.1-branch`, leaving the other changes on `master`.
1. The team celebrates that all the beta bugs are fixed for the 1 August release.
1. The RE tags HEAD of `20.1-branch` as `20.1.0` and publishes the release.
1. A few weeks later, a crash is discovered in `20.1.0` and users need a fix NOW.
1. The acting RE pulls the crash fix from master into `20.1-branch`, tags HEAD as `20.1.1`, and publishes the hotfix.
1. The cycle repeats once the `20.2` release is ready.

Просмотреть файл

@ -239,8 +239,8 @@ module.exports = {
["Contributing", ["contributing-to-appium",
["Running Appium from Source", "appium-from-source.md"],
["Developer Overview", "developers-overview.md"],
["Standard Gulp Commands", "gulp.md"],
["Appium Style Guide", "style-guide-2.0.md"],
["Standard Dev Commands", "dev-tools.md"],
["Appium Style Guide", "style-guide.md"],
["How to Write Docs", "how-to-write-docs.md"],
["Appium Package Structure", "appium-packages.md"],
["Credits", "credits.md"]]]

Просмотреть файл

@ -74,7 +74,8 @@
"precommit-test": "REPORTER=dot gulp once",
"lint": "gulp eslint",
"coverage": "gulp coveralls",
"generate-docs": "babel-node ./commands-yml/parse.js"
"generate-docs": "babel-node ./commands-yml/parse.js",
"clean": "rm -rf node_modules && rm -rf package-lock.json && npm install"
},
"pre-commit": [
"precommit-msg",