Skip to content

Commit

Permalink
Merge branch 'release/v0.9.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
scott2449 committed Dec 16, 2014
2 parents 441d2dc + 54e0ba1 commit 008b947
Show file tree
Hide file tree
Showing 15 changed files with 85 additions and 334 deletions.
41 changes: 34 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
[Fiveby](http://en.wikipedia.org/wiki/Five_by_five) [![Build Status](http://djin-jenkins01.dowjones.net/job/fiveby/badge/icon)](http://djin-jenkins01.dowjones.net/job/fiveby/)
========

makes it easier to write automated tests/suites. Here's the idea: don't worry about selenium (or it's config), don't worry about selenium JS api oddities, don't worry about mocha, just use fiveby:
All the things you expect from a robust testing framework by neatly packaging: [WebDriverJS](https://code.google.com/p/selenium/wiki/WebDriverJs), [mocha](http://mochajs.org/), and [should](https://github.com/shouldjs/should.js) with a little glue and zero magic:

```javascript
var fiveby = require('fiveby');

new fiveby(function (browser) { //browser is driver if you are looking at selenium docs
fiveby(function (browser) {
return describe('Google Search in ' + browser.name, function () {
it('should work', function () {
browser.get('http://www.google.com');
var searchBox = browser.findElement(by.name('q')); //notice webdriver.By convenience method
var searchBox = browser.findElement(by.name('q'));
searchBox.sendKeys('awesome');
return searchBox.getAttribute('value').then(function (value) {
'awesome'.should.equal(value);
Expand All @@ -18,7 +19,14 @@ new fiveby(function (browser) { //browser is driver if you are looking at seleni
});
});
```
See [docs](https://github.dowjones.net/institutional/fiveby/docs) for more details and use [gulp-fiveby](https://github.dowjones.net/institutional/gulp-fiveby) as a scaffold project. [Live Help](https://dowjones.slack.com/messages/fiveby/)
Add [gulp](http://gulpjs.com/) and some convention to make it even more powerful: [slush-fiveby](https://github.com/dowjones/slush-fiveby)

###What's unique about fiveby?

- Cleanly allows mocha and webdriverjs to coexist
- MUCH simpler configuration and less boilerplate code
- [environment properties](/docs/properties.md)
- conveniences: api cleanup, spins up a selenium server if not provided, closes the browser for you, etc ...

###Configuration - fiveby-config.json

Expand All @@ -27,11 +35,30 @@ See [docs](https://github.dowjones.net/institutional/fiveby/docs) for more detai
"implicitWait": 5000,
"hubUrl": null,
"browsers": {
"chrome": 1
"firefox": true,
"chrome": {
"version": "37.0.2062.103",
"chromeOptions": {
"args": ["--disable-extensions"]
}
}
},
"disableBrowsers": false
}
```
disableBrowsers is optional, defaults to false

hubUrl is optional, if not provided (and disableBrowsers = false) it will spin up a selenium server *requires java*
disableBrowsers and hubUrl are optional, disableBrowsers defaults to false

###English?

#####Have little to no experience with end to end testing?

Ok, this tool will allow you to write a bit of javascript that will open any browser (even mobile), emulate user behavior via a few simple commands, and then verify what's displayed onscreen is correct. You can compile large suites of these tests and easily run them against many different browsers at once and get nice reports. It can be run with something like [jenkins](http://jenkins-ci.org/) to automate further.

###Pre-reqs

- [node.js](http://nodejs.org/)
- [mocha cli](http://mochajs.org/)
- [java](https://www.java.com/en/download/help/download_options.xml)

See [docs folder](/docs) for even more details!
18 changes: 8 additions & 10 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
####1. Introduction

Automated browser testing is writing code to simulation a user: click element x, wait for event y, click again, assert results, repeat.
Automated browser testing is writing code to simulate a user: click element x, wait for event y, click again, assert results, repeat.

####2. Project Structure - the important part to note here is the distinction between tests and components. Components abstract the dom details from the tests using the [page objects pattern](pop.md). You can see some real projects [here](https://github.dowjones.net/factivaautomation). Keep in mind other projects are immature as well and probably DO NOT follow many of the best practices discussed here... and suffered for it!
####2. Project Structure - the important part to note here is the distinction between tests and components. Components abstract the dom details from the tests using the [page objects pattern](pop.md). Services are where you perform actions that have nothing to do with the browser, like rest calls used by setup/teardown.

```
└── tests
Expand All @@ -21,6 +21,9 @@
│    └── smoke
│     └── ...
└── services
│ └── LoginService.js
└── components
   ├── BaseComponent.js
   ├── CommonConfig.js
Expand All @@ -45,13 +48,13 @@

####5. [Code Style & API](api.md)

####6.[External Dependencies](/docs/external-dependencies.md)
####6.[External Dependencies](external-dependencies.md)

####7. Based on:

*Selenium Javascript* api:

> http://selenium.googlecode.com/git/docs/api/javascript/index.html
> http://selenium.googlecode.com/git/docs/api/javascript/module_selenium-webdriver.html
> (webdriver.By and webdriver.promise surfaced as globals for convience)
*Mocha BDD* api:
Expand All @@ -63,9 +66,4 @@

> https://github.com/shouldjs/should.js

####8. Ecosystem

![Ecosystem](ecosystem.png)

####9. [FAQ](/docs/faq.md)
####8. [FAQ](/docs/faq.md)
2 changes: 1 addition & 1 deletion docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ something.sendKeys('else');

**Find multiple elements**

[Working example leveraging the page objects pattern](https://github.dowjones.net/institutional/gulp-fiveby/blob/master/tests/smoke/bootstrap.js)
[Working example leveraging the page objects pattern](https://github.com/dowjones/slush-fiveby/blob/master/tests/smoke/bootstrap.js)

**Complex mouses operations** using action chains:

Expand Down
2 changes: 1 addition & 1 deletion docs/clean-promises.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
There are many cases where you need to wait for multiple promises before doing something.
Sometimes you need to run them in series, sometimes in parallel, sometimes you need all the results at the end,
and sometimes you need each function to know about the results of the previous function.
Following are all the examples we could think of =D
Following are some of the examples we could think of =D
***
####Sequence (Waterfall)
output:
Expand Down
Binary file removed docs/ecosystem.png
Binary file not shown.
4 changes: 2 additions & 2 deletions docs/external-dependencies.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#### Things to consider about your application before testing:

1. **Performance.** If your application's performance is inconsistent, your tests will be brittle or long running. You will either set short timeouts and fail often, or set long timeouts and take forever. This is not a problem with Automated Testing. If your experience is that inconsistent, it's going to be a problem with your customers!
1. **Performance.** If your application's performance is inconsistent, your tests will be brittle or long running. You will either set short timeouts and fail often, or set long timeouts and take forever. This is not a problem with Automated Testing. If your experience is that inconsistent, it's going to be a problem with your users!
2. **Setup / Teardown.** You should be able to programmatically set up and tear down everything related to a test. You should have APIs to create and delete users as well as populate and delete user data in bulk. These will make tests faster and more stable. They will also be more reliable as the state is pristine and therefore 100% known.
3. **ARM limits!** Most institutional transactions have limits to prevent a single user from damaging the experience of others by hogging the system resources. Your testing WILL trigger these limits. Plan accordingly.
3. **Resource limits!** Like all things automated, make sure you are not going to strain the system you are testing (or lock out a user, engage rate limiting, etc). No use testing if you bring the system down by overloading it :grin:
22 changes: 11 additions & 11 deletions docs/faq.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
**I know what promises are but mine look terrible, is there a better way?**
**I know what promises are ... but mine look terrible, is there a better way?**

1. [Our Suggestions](/docs/clean-promises.md)
1. [Our Suggestions](clean-promises.md)
2. Good practices for promises http://solutionoptimist.com/2013/12/27/javascript-promise-chains-2/

**What is implicit wait and do my tests use it?**
Expand All @@ -9,7 +9,7 @@

**Can I change the timeout on individual Mocha tests?**

Test timeout is 30 seconds, this is per "it". This can be edited via gulpfile.js
Test timeout is 30 seconds, this is per "it". This can be edited via mocha cli or something like gulpfile.js

**How can I check on the state of things while my tests run?**

Expand All @@ -20,20 +20,20 @@ helpful to debug selectors (making sure you have what you think you have):
console.info(html);
});
```
if you want to debug the actual code just run

if you want to debug the actual code just run

mocha debug *yourfile* //runs the cli debugger or
mocha --debug *yourfile //runs the debugger on a port for attach

**Can I run or exclude specific tests?**
**Can I run or exclude specific tests?**

describe.only it.only describe.skip it.skip for excluding and including tests, see http://visionmedia.github.io/mocha/
**Help, I keep getting NoSuchElementError**

**Help, I keep getting NoSuchElementError**

Make selectors very specific to avoid too many elements or NoSuchElementError (also use isElementPresent, isDisplayed). You should not run into NoSuchElement errors in the course of testing, only look up things you expect to find. You rarely perform negative testing in this space and if you do you look for elements (like a modal) that are telling the user they failed or are unauthorized.

**My code is always changing how do I maintain multiple suite to match different versions of code:**
**My code is always changing how do I maintain multiple suites to match different versions of code:**

Branch for versions of tests that only will run against specific versions of code. Fiveby will be enhanced shortly to include environment variables (much like tesla property service)
scm branching for versions of tests that only will run against specific versions of code. use [enviroment properties](properties.md) to handle things like different urls and timeouts in various environements.
4 changes: 3 additions & 1 deletion gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ gulp.task('test', function (cb) {
.on('finish', function () {
gulp.src(['test/*.js'])
.pipe(mocha())
.pipe(istanbul.writeReports())
.pipe(istanbul.writeReports({
reporters: [ 'text', 'lcov', 'cobertura' ]
}))
.on('end', cb);
});
});
18 changes: 0 additions & 18 deletions lib/cache.js

This file was deleted.

16 changes: 9 additions & 7 deletions lib/fiveby.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,17 @@ fiveby.prototype.runSuiteInBrowsers = function (test) {
var testComplete = webdriver.promise.defer();
global.testPromise = testComplete.promise;

//create a control flow and driver per test file
//create a driver per test file
lastPromise.then(function() {

// set options for current browser
var capabilities = webdriver.Capabilities[elem]();

if (elem === 'chrome') {
capabilities.set('chromeOptions', {
args: ['--disable-extensions']
var cap = self.config.browsers[elem];

if (typeof cap === 'object' && cap !== null) {
Object.keys(cap).forEach(function (n) {
capabilities.set(n, cap[n]);
});
}

Expand All @@ -77,12 +79,12 @@ fiveby.prototype.runSuiteInBrowsers = function (test) {

//register hooks with mocha
self.registerHook('fiveby error handling', describe, "beforeEach", function () {
this.currentTest.parent.file = this.currentTest.file = file;
webdriver.promise.controlFlow().on('uncaughtException', function (e) {
this.currentTest.parent.file = this.currentTest.file = file; //correct file name bug with async execution and mocha
webdriver.promise.controlFlow().on('uncaughtException', function (e) { //map errors to test when appropriate
if(this.currentTest) {
this.currentTest.callback(e);
} else {
console.error("Failed in setup or teardown, test result may not be valid for this file");
console.error("Failed in setup or teardown, test result may not be valid for this file"); //failed in non-test
throw(e);
}
});
Expand Down
Loading

0 comments on commit 008b947

Please sign in to comment.