├── .editorconfig
├── .gitattributes
├── .gitignore
├── .jshintrc
├── .travis.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── CONTRIBUTORS.md
├── Gruntfile.js
├── LICENSE-MIT
├── README.md
├── examples
└── pagetitle.js
├── lib
├── dalek.js
└── dalek
│ ├── actions.js
│ ├── assertions.js
│ ├── config.js
│ ├── driver.js
│ ├── host.js
│ ├── remote.js
│ ├── reporter.js
│ ├── suite.js
│ ├── timer.js
│ ├── unit.js
│ └── uuid.js
├── package.json
└── test
├── lib_dalek_TEST.js
├── lib_dalek_actions_TEST.js
├── lib_dalek_actions_screenshots_TEST.js
├── lib_dalek_assertions_TEST.js
├── lib_dalek_config_TEST.js
├── lib_dalek_driver_TEST.js
├── lib_dalek_reporter_TEST.js
├── lib_dalek_suite_TEST.js
├── lib_dalek_timer_TEST.js
├── lib_dalek_unit_TEST.js
├── lib_dalek_uuid_TEST.js
└── mock
├── Dalekfile.coffee
├── Dalekfile.js
├── Dalekfile.json
├── Dalekfile.json5
└── Dalekfile.yml
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 | [*]
8 |
9 | # Change these settings to your own preference
10 | indent_style = space
11 | indent_size = 2
12 |
13 | # We recommend you to keep these unchanged
14 | end_of_line = lf
15 | charset = utf-8
16 | trim_trailing_whitespace = true
17 | insert_final_newline = true
18 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | lib-cov
2 | *.seed
3 | *.log
4 | *.csv
5 | *.dat
6 | *.out
7 | *.pid
8 | *.gz
9 |
10 | pids
11 | logs
12 | results
13 |
14 | package-canary.json
15 | index-canary.js
16 | npm-debug.log
17 | report.zip
18 |
19 | /coverage/
20 | /node_modules/
21 | /report/
22 | .DS_STORE
23 | .idea/
24 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "node": true,
3 | "browser": false,
4 | "esnext": false,
5 | "bitwise": false,
6 | "camelcase": true,
7 | "curly": true,
8 | "eqeqeq": true,
9 | "immed": true,
10 | "indent": 2,
11 | "latedef": true,
12 | "newcap": true,
13 | "noarg": true,
14 | "quotmark": "single",
15 | "regexp": true,
16 | "undef": true,
17 | "unused": true,
18 | "strict": true,
19 | "trailing": true,
20 | "smarttabs": true,
21 | "expr": true,
22 | "globals": {
23 | "describe": false,
24 | "it": false,
25 | "before": false,
26 | "beforeEach": false,
27 | "after": false,
28 | "afterEach": false
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "0.10"
4 | before_script:
5 | - npm install -g grunt-cli
6 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 |
2 | ### 0.0.8 (2014-11-28)
3 |
4 |
5 | #### Bug Fixes
6 |
7 | * **actions:**
8 | * before & after test execution ([d0ce489c](http://github.com/dalekjs/dalek/commit/d0ce489cb10f778df0ec9bc1576862827643a370))
9 | * better screenshot handling ([ed50a6fd](http://github.com/dalekjs/dalek/commit/ed50a6fdc8b90b01566a2847ca9087689d42d777))
10 | * **build:** fix build process ([ff45eb3b](http://github.com/dalekjs/dalek/commit/ff45eb3bddd348aa65f3a17c8c440b13a3dd4292))
11 | * **tests:** removed undefined variable ([1ef624da](http://github.com/dalekjs/dalek/commit/1ef624daf6de321996daba10557a50e3e5a7dece))
12 |
13 |
14 | #### Features
15 |
16 | * **suite:** bind this to the current test ([37157057](http://github.com/dalekjs/dalek/commit/3715705799925dde865c36274ef05d7c7129c0da))
17 |
18 |
19 |
20 | ### v0.0.7 (2013-10-28)
21 |
22 |
23 | #### Features
24 |
25 | * **config:** Moved config.js form dalek-internal-config into dalek main module ([a0dadca5](http://github.com/dalekjs/dalek/commit/a0dadca50282dddd52758051cb95a77ef0309894))
26 | * **core:** added remote runner/host capabilities ([77ed1ece](http://github.com/dalekjs/dalek/commit/77ed1ecea5f5b8b2556cbe7606291cb44abda37c))
27 |
28 |
29 | ### v0.0.6 (2013-10-15)
30 |
31 | #### Features
32 |
33 | * **core:**
34 | * bumping dependencies ([6b439aa](https://github.com/dalekjs/dalek/commit/6b439aabbe5f1659e22a34a6c578ac5389000788))
35 |
36 | #### Bug Fixes
37 |
38 | * **core:**
39 | * Added fix for issue #1 of dalek-internal-config ([7ca7df5](https://github.com/dalekjs/dalek/commit/7ca7df54cc44ccc91ae2d8b797d915962c857042))
40 |
41 |
42 | ### v0.0.5 (2013-09-26)
43 |
44 | #### Features
45 |
46 | * **test:**
47 | * improve testharness ([3c98bf9](https://github.com/dalekjs/dalek/commit/3c98bf919e4a9c2d23c1551b8e8690acf46290e0))
48 | * improve testharness ([c890560](https://github.com/dalekjs/dalek/commit/c89056024957c855fe7c856b7c1dfe2c399c85b5))
49 |
50 | #### Bug Fixes
51 |
52 | * **core:**
53 | * fix issue with reload() not working ([b221e77](https://github.com/dalekjs/dalek/commit/b221e77b6f5f27af74403330cce7f623164852a0))
54 |
55 |
56 | ### v0.0.4 (2013-09-25)
57 |
58 | #### Features
59 |
60 | * **core:**
61 | * bumping console reporter dependency ([6325a7a](https://github.com/dalekjs/dalek/commit/6325a7a0f04c5fda7cac1c6e172453fdf59530d2))
62 |
63 |
64 | ### v0.0.3 (2013-09-25)
65 |
66 | #### Features
67 |
68 | * **core:**
69 | * bumping phantom dependency ([b173fce](https://github.com/dalekjs/dalek/commit/b173fce963275102b42ce9ca322fb797981c373e))
70 |
71 |
72 | ### v0.0.2 (2013-09-25)
73 |
74 | #### Features
75 |
76 | * **core:**
77 | * bumping dependencies ([5bd3a7b](https://github.com/dalekjs/dalek/commit/5bd3a7be590ed58e3972c6ae6aab0731567a44e5))
78 |
79 |
80 | ### v0.0.1 (2013-09-23)
81 |
82 | #### Bug Fixes
83 |
84 | * **gruntfile:**
85 | * fix canary builds ([ccc2045](https://github.com/dalekjs/dalek/commit/ccc20454e9d4dde64b6ecdc1b367ebdb9dd41f5e))
86 |
87 | * **typo:**
88 | * fix typo in README.md ([e37f0a1](https://github.com/dalekjs/dalek/commit/e37f0a1c6620def7d966429bbfb3537866ac0753))
89 |
90 | #### Features
91 |
92 | * **gruntfile:**
93 | * added build/release automation tools ([92e2b6c](https://github.com/dalekjs/dalek/commit/92e2b6ca43b93db52d11ce259edd16067cedf69a))
94 | * automatically generate CONTRIBUTORS file ([3b518cf](https://github.com/dalekjs/dalek/commit/3b518cf3e5b22aaf7d8426aa0af9ae1a44c4c093))
95 |
96 | * **core:**
97 | * added proper Error handling for runtime exceptions ([c995bcd](https://github.com/dalekjs/dalek/commit/c995bcd6e3f89764d26c25efe4e73f068ac45ad7))
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | DalekJS has a few very specific guidelines in addition
2 | to some of the standard guidelines that Github and open
3 | source projects in general recommend. These guidelines
4 | are here to facilitate your contribution and streamline
5 | the process of getting the changes merged in and released.
6 |
7 | If you don't follow these guidelines, we'll still work
8 | with you to get the changes in. Any contribution you can
9 | make will help tremendously. Following these guidelines
10 | will help to streamline the pull request and change
11 | submission process.
12 |
13 | ## Documentation Fixes
14 |
15 | If you notice any problems with any documentation, please
16 | fix it and we'll get it merged as soon as we can. For
17 | small things like typos and grammar (which we know I'm
18 | terrible with), just click the "Edit this file" button
19 | and send in the pull request for the fix. For larger
20 | changes and big swaths of documentation changes, a regular
21 | pull request as outlined below is more appropriate.
22 |
23 | ## Pull Requests
24 |
25 | See [Github's documentation for pull requests](https://help.github.com/articles/using-pull-requests).
26 |
27 | Pull requests are by far the best way to contribute to
28 | DalekJS. Any time you can send us a pull request with
29 | the changes that you want, we will have an easier time
30 | seeing what you are trying to do. But a pull request in
31 | itself is not usually sufficient. There needs to be some
32 | context and purpose with it, and it should be done
33 | against a specific branch.
34 |
35 | ## General Submission Guidelines
36 |
37 | These guidelines are generally applicable whether or not
38 | you are submitting a bug or a pull request. Please try to
39 | include as much of this information as possible with any
40 | submission.
41 |
42 | ### Version Numbers
43 |
44 | In order to best help out with bugs, we need to know the
45 | following information in your bug submission:
46 |
47 | * DalekJS version #
48 | * Operating System / version #
49 | * Browser and version #
50 |
51 | Including this information in a submission will help
52 | us to test the problem and ensure that the bug is
53 | both reproduced and corrected on the platforms / versions
54 | that you are having issues with.
55 |
56 | ### Provide A Meaningful Description
57 |
58 | It doesn't matter how beautiful and "obvious" your fix is.
59 | We have 10,000,000,000 things floating around the project
60 | at any given moment and we will not immediately understand
61 | why you are making changes.
62 |
63 | Given that, it is very important to provide a meaningful
64 | description with your pull requests that alter any code.
65 | A good format for these descriptions will include three things:
66 |
67 | 1. Why: The problem you are facing (in as much detail as is
68 | necessary to describe the problem to someone who doesn't
69 | know anything about the system you're building)
70 |
71 | 2. What: A summary of the proposed solution
72 |
73 | 3. How: A description of how this solution solves the problem,
74 | in more detail than item #2
75 |
76 | 4. Any additional discussion on possible problems this might
77 | introduce, questions that you have related to the changes, etc.
78 |
79 | Without at least the first 2 items in this list, we won't
80 | have any clue why you're changing the code. The first thing
81 | we'll ask, then, is that you add that information.
82 |
83 | ### Create A Topic Branch For Your Work
84 |
85 | The work you are doing for your pull request should not be
86 | done in the master branch of your forked repository. Create
87 | a topic branch for your work. This allows you to isolate
88 | the work you are doing from other changes that may be happening.
89 |
90 | Github is a smart system, too. If you submit a pull request
91 | from a topic branch and we ask you to fix something, pushing
92 | a change to your topic branch will automatically update the
93 | pull request.
94 |
95 | ### Isolate Your Changes For The Pull Request
96 |
97 | See the previous item on creating a topic branch.
98 |
99 | If you don't use a topic branch, we may ask you to re-do your
100 | pull request on a topic branch. If your pull request contains
101 | commits or other changes that are not related to the pull
102 | request, we will ask you to re-do your pull request.
103 |
104 | ### Submit Specs With Your Pull Request
105 |
106 | Whenever possible, submit the specs (unit tests) that
107 | correspond to your pull request.
108 |
109 | I would rather see a pull request that is nothing but a
110 | failing spec, than see a large change made to the real
111 | code with no test to support the change.
112 |
113 | In fact...
114 |
115 | ## Submit A Failing Spec If You Don't Know How To Fix The Problem
116 |
117 | If you are stuck in a scenario that fails in your app,
118 | but you don't know how to fix it, submit a failing spec
119 | to show the failing scenario. Follow the guidelines for
120 | pull request submission, but don't worry about fixing the
121 | problem. A failing spec to show that a problem exists is
122 | a very very very helpful pull request for us.
123 |
124 | We'll even accept a failing test pasted in to the ticket
125 | description instead of a pull request. That would at
126 | least get us started on creating the failing test in the code.
127 |
128 | ## Don't Be A Troll
129 |
130 | It is very sad that we need to include this section of
131 | the contribution guidelines...
132 |
133 | If you are running in to a scenario with a problem, don't
134 | be a troll. Comment like "does DalekJS even have tests?"
135 | are not useful, funny or constructive. In fact, it may get
136 | you blocked and reported for abuse to Github.
137 |
138 | Submit a useful comment describing the scenario that is
139 | having an issue. Show us a failing test. Show us some
140 | code that is not behaving the way the documentation says
141 | it should. Be useful and work with us to fix the problem.
142 |
143 | We're all for criticism and tearing apart DalekJS for
144 | the problems it has. Do it in a constructive and helpful
145 | manner: "There isn't a test for this scenario. Here's a
146 | rough idea for one that shows the problem." Tell us why
147 | you don't like DalekJS. Tell us that someone else is
148 | building something better and why that other thing fits
149 | your scenario and needs better than DalekJS does. Just
150 | do it in a manner that allows us to learn from your
151 | experiences, instead of reacting to you being a troll
152 | (likely causing us to get defensive and miss an opportunity
153 | to learn something).
154 |
155 | -----------
156 | All credit for this goes to @derickbaily, he is not involved in this project anyhow,
157 | but made this nice piece up for backbone.marionette.
158 |
--------------------------------------------------------------------------------
/CONTRIBUTORS.md:
--------------------------------------------------------------------------------
1 | Ain Tohvri
2 | Altiss
3 | Dan Woodward
4 | Jev Zelenkov
5 | Johannes Heimbach
6 | JulianLeviston
7 | Krister Kari
8 | Mathias Schaefer (molily)
9 | Niall O'Higgins
10 | Paulo Pires
11 | Peter Dave Hello
12 | RichCrook
13 | Robin Böhm
14 | Rodney Rehm
15 | Ryan Zec
16 | Sebastian Golasch
17 | Sebastian Hardt
18 | Shahar Roth
19 | Skachov, Oleksandr
20 | Vladimir Makhaev
21 | asciidisco
22 | deedubbleyoo
23 | gskachkov
24 | mdix
25 | ryanzec
26 | ryanzec
27 | stuartlangridge
28 | waffle.io
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function(grunt) {
2 | 'use strict';
3 |
4 | // check task runtime
5 | require('time-grunt')(grunt);
6 |
7 | // load generic configs
8 | var configs = require('dalek-build-tools');
9 |
10 | // project config
11 | grunt.initConfig({
12 |
13 | // load module meta data
14 | pkg: grunt.file.readJSON('package.json'),
15 |
16 | // define a src set of files for other tasks
17 | src: {
18 | lint: ['Gruntfile.js', 'lib/**/*.js', 'test/*.js'],
19 | complexity: ['lib/**/*.js'],
20 | test: ['test/*TEST.js'],
21 | src: ['lib/dalek.js']
22 | },
23 |
24 | // clean automatically generated helper files & docs
25 | clean: configs.clean,
26 |
27 | // speed up build by defining concurrent tasks
28 | concurrent: configs.concurrent,
29 |
30 | // linting
31 | jshint: configs.jshint,
32 |
33 | // testing
34 | mochaTest: configs.mocha,
35 |
36 | // code metrics
37 | complexity: configs.complexity,
38 | plato: configs.plato(grunt.file.readJSON('.jshintrc')),
39 |
40 | // api docs
41 | yuidoc: configs.yuidocs(),
42 |
43 | // up version, tag & commit
44 | bump: configs.bump({
45 | pushTo: 'git@github.com:dalekjs/dalek.git',
46 | files: ['package.json', 'CONTRIBUTORS.md', 'CHANGELOG.md']
47 | }),
48 |
49 | // generate contributors file
50 | contributors: configs.contributors,
51 |
52 | // compress artifacts
53 | compress: configs.compress,
54 |
55 | // prepare files for grunt-plato to
56 | // avoid error messages (weird issue...)
57 | preparePlato: {
58 | options: {
59 | folders: [
60 | 'coverage',
61 | 'report',
62 | 'report/coverage',
63 | 'report/complexity',
64 | 'report/complexity/files',
65 | 'report/complexity/files/_js',
66 | 'report/complexity/files/_actions_js',
67 | 'report/complexity/files/_assertions_js',
68 | 'report/complexity/files/_reporter_js',
69 | 'report/complexity/files/_config_js',
70 | 'report/complexity/files/_driver_js',
71 | 'report/complexity/files/_unit_js',
72 | 'report/complexity/files/_suite_js',
73 | 'report/complexity/files/_timer_js',
74 | 'report/complexity/files/_host_js',
75 | 'report/complexity/files/_remote_js',
76 | 'report/complexity/files/_uuid_js',
77 | ],
78 | files: [
79 | 'report.history.json',
80 | 'files/_js/report.history.json',
81 | 'files/_actions_js/report.history.json',
82 | 'files/_assertions_js/report.history.json',
83 | 'files/_reporter_js/report.history.json',
84 | 'files/_config_js/report.history.json',
85 | 'files/_driver_js/report.history.json',
86 | 'files/_unit_js/report.history.json',
87 | 'files/_suite_js/report.history.json',
88 | 'files/_timer_js/report.history.json',
89 | 'files/_host_js/report.history.json',
90 | 'files/_remote_js/report.history.json',
91 | 'files/_uuid_js/report.history.json',
92 | ]
93 | }
94 | },
95 |
96 | // prepare files & folders for coverage
97 | prepareCoverage: {
98 | options: {
99 | folders: ['coverage', 'report', 'report/coverage'],
100 | pattern: '[require("fs").realpathSync(__dirname + "/../lib/dalek.js"), require("fs").realpathSync(__dirname + "/../lib/dalek/")]'
101 | }
102 | },
103 |
104 | // add current timestamp to the html document
105 | includereplace: {
106 | dist: {
107 | options: {
108 | globals: {
109 | timestamp: '<%= grunt.template.today("dddd, mmmm dS, yyyy, h:MM:ss TT") %>'
110 | },
111 | },
112 | src: 'report/docs/*.html',
113 | dest: './'
114 | }
115 | },
116 |
117 | // user docs
118 | documantix: {
119 | options: {
120 | header: 'dalekjs/dalekjs.com/master/assets/header.html',
121 | footer: 'dalekjs/dalekjs.com/master/assets/footer.html',
122 | target: 'report/docs'
123 | },
124 |
125 | // actions
126 | actions: {
127 | src: ['lib/dalek/actions.js'],
128 | options: {
129 | vars: {
130 | title: 'DalekJS - Documentation - Actions',
131 | desc: 'DalekJS - Documentation - Actions',
132 | docs: true
133 | }
134 | }
135 | },
136 |
137 | // assertions
138 | assertions: {
139 | src: ['lib/dalek/assertions.js'],
140 | options: {
141 | vars: {
142 | title: 'DalekJS - Documentation - Actions',
143 | desc: 'DalekJS - Documentation - Actions',
144 | docs: true
145 | }
146 | }
147 | },
148 |
149 | // config
150 | config: {
151 | src: ['lib/dalek/config.js'],
152 | options: {
153 | vars: {
154 | title: 'DalekJS - Documentation - Config',
155 | desc: 'DalekJS - Documentation - Config',
156 | docs: true
157 | }
158 | }
159 | },
160 |
161 | },
162 |
163 | // archive docs
164 | archive: {
165 | options: {
166 | files: ['config.html', 'actions.html', 'assertions.html']
167 | }
168 | },
169 |
170 | // release canary version
171 | 'release-canary': {
172 | options: {
173 | files: []
174 | }
175 | }
176 |
177 | });
178 |
179 | // load 3rd party tasks
180 | require('load-grunt-tasks')(grunt);
181 | grunt.loadTasks('./node_modules/dalek-build-tools/tasks');
182 | grunt.loadNpmTasks('grunt-documantix');
183 |
184 | // define runner tasks
185 | grunt.registerTask('lint', 'jshint');
186 |
187 | // split test & docs for speed
188 | grunt.registerTask('test', ['clean:coverage', 'prepareCoverage', 'concurrent:test', 'generateCoverageBadge']);
189 | grunt.registerTask('docs', ['clean:reportZip', 'clean:report', 'preparePlato', 'concurrent:docs', 'documantix', 'includereplace', 'compress']);
190 |
191 | // release tasks
192 | grunt.registerTask('releasePatch', ['test', 'bump-only:patch', 'contributors', 'changelog', 'bump-commit']);
193 | grunt.registerTask('releaseMinor', ['test', 'bump-only:minor', 'contributors', 'changelog', 'bump-commit']);
194 | grunt.registerTask('releaseMajor', ['test', 'bump-only:major', 'contributors', 'changelog', 'bump-commit']);
195 |
196 | // clean, test, generate docs (the CI task)
197 | grunt.registerTask('all', ['clean', 'test', 'docs']);
198 |
199 | };
200 |
--------------------------------------------------------------------------------
/LICENSE-MIT:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013 asciidisco (Sebastian Golasch)
2 |
3 | Permission is hereby granted, free of charge, to any person
4 | obtaining a copy of this software and associated documentation
5 | files (the "Software"), to deal in the Software without
6 | restriction, including without limitation the rights to use,
7 | copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the
9 | Software is furnished to do so, subject to the following
10 | conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](http://unmaintained.tech/)
2 |
3 | # DalekJS is not maintained any longer :cry:
4 |
5 | We recommend [TestCafé](http://devexpress.github.io/testcafe/) for your automated browser testing needs.
6 |
7 | ---
8 |
9 | dalekjs
10 | ======================
11 |
12 | > DalekJS base framework
13 |
14 | [](https://travis-ci.org/dalekjs/dalek)
15 | [](https://drone.io/github.com/dalekjs/dalek/latest)
16 | [](https://david-dm.org/dalekjs/dalek)
17 | [](https://david-dm.org/dalekjs/dalek#info=devDependencies)
18 | [](http://badge.fury.io/js/dalekjs)
19 | [](http://dalekjs.com/package/dalekjs/master/coverage/index.html)
20 | [](http://github.com/hughsk/stability-badges)
21 | [](https://waffle.io/dalekjs/dalek)
22 | [](https://bitdeli.com/free "Bitdeli Badge")
23 | [](http://gruntjs.com/)
24 |
25 | [](https://nodei.co/npm/dalekjs/)
26 | [](https://nodei.co/npm/dalekjs/)
27 |
28 | ## Resources
29 |
30 | [API Docs](http://dalekjs.com/package/dalekjs/master/api/index.html) -
31 | [Trello](https://trello.com/b/gA1A6RZW/dalekjs) -
32 | [Code coverage](http://dalekjs.com/package/dalekjs/master/coverage/index.html) -
33 | [Code complexity](http://dalekjs.com/package/dalekjs/master/complexity/index.html) -
34 | [Contributing](https://github.com/dalekjs/dalek/blob/master/CONTRIBUTING.md) -
35 | [User Docs](http://dalekjs.com/pages/getStarted.html) -
36 | [Homepage](http://dalekjs.com) -
37 | [Twitter](http://twitter.com/dalekjs)
38 |
39 | # Docs
40 |
41 | Daleks documentation can be found [here](http://dalekjs.com/pages/documentation.html)
42 |
43 | ## Help Is Just A Click Away
44 |
45 | ### #dalekjs on FreeNode.net IRC
46 |
47 | Join the `#daleksjs` channel on [FreeNode.net](http://freenode.net) to ask questions and get help.
48 |
49 | ### [Google Group Mailing List](https://groups.google.com/forum/#!forum/dalekjs)
50 |
51 | Get announcements for new releases, share your projects and ideas that are
52 | using DalekJS, and join in open-ended discussion that does not fit in
53 | to the Github issues list or StackOverflow Q&A.
54 |
55 | **For help with syntax, specific questions on how to implement a feature
56 | using DalekJS, and other Q&A items, use StackOverflow.**
57 |
58 | ### [StackOverflow](http://stackoverflow.com/questions/tagged/dalekjs)
59 |
60 | Ask questions about using DalekJS in specific scenarios, with
61 | specific features. For example, help with syntax, understanding how a feature works and
62 | how to override that feature, browser specific problems and so on.
63 |
64 | Questions on StackOverflow often turn in to blog posts or issues.
65 |
66 | ### [Github Issues](//github.com/dalekjs/dalek/issues)
67 |
68 | Report issues with DalekJS, submit pull requests to fix problems, or to
69 | create summarized and documented feature requests (preferably with pull
70 | requests that implement the feature).
71 |
72 | **Please don't ask questions or seek help in the issues list.** There are
73 | other, better channels for seeking assistance, like StackOverflow and the
74 | Google Groups mailing list.
75 |
76 | 
77 |
78 | ## Legal FooBar (MIT License)
79 |
80 | Copyright (c) 2013 Sebastian Golasch
81 |
82 | Distributed under [MIT license](https://github.com/dalekjs/dalek/blob/master/LICENSE-MIT)
83 |
84 |
--------------------------------------------------------------------------------
/examples/pagetitle.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | // Checks if the of ´github.com´ has the expected value
3 | 'Page title is correct': function (test) {
4 | 'use strict';
5 | test.expect(1);
6 |
7 | test
8 | .open('http://github.com')
9 | .assert.title('GitHub')
10 | .done();
11 | }
12 | };
13 |
--------------------------------------------------------------------------------
/lib/dalek.js:
--------------------------------------------------------------------------------
1 | /*!
2 | *
3 | * Copyright (c) 2013 Sebastian Golasch
4 | *
5 | * Permission is hereby granted, free of charge, to any person obtaining a
6 | * copy of this software and associated documentation files (the "Software"),
7 | * to deal in the Software without restriction, including without limitation
8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 | * and/or sell copies of the Software, and to permit persons to whom the
10 | * Software is furnished to do so, subject to the following conditions:
11 | *
12 | * The above copyright notice and this permission notice shall be included
13 | * in all copies or substantial portions of the Software.
14 | *
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 | * DEALINGS IN THE SOFTWARE.
22 | *
23 | */
24 |
25 | 'use strict';
26 |
27 | // ext. libs
28 | var async = require('async');
29 | var EventEmitter2 = require('eventemitter2').EventEmitter2;
30 |
31 | // int. libs
32 | var Driver = require('./dalek/driver');
33 | var Reporter = require('./dalek/reporter');
34 | var Timer = require('./dalek/timer');
35 | var Config = require('./dalek/config');
36 | var Host = require('./dalek/host');
37 |
38 | /**
39 | * Default options
40 | * @type {Object}
41 | */
42 |
43 | var defaults = {
44 | reporter: ['console'],
45 | driver: ['native'],
46 | browser: ['phantomjs'],
47 | viewport: {width: 1280, height: 1024},
48 | logLevel: 3
49 | };
50 |
51 | /**
52 | * Setup all the options needed to configure dalek
53 | *
54 | * @param {options} opts Configuration options
55 | * @constructor
56 | */
57 |
58 | var Dalek = function (opts) {
59 | // setup instance
60 | this._initialize();
61 |
62 | // register exception handler
63 | this._registerExceptionHandler();
64 |
65 | // normalize options
66 | this.options = this.normalizeOptions(opts);
67 |
68 | // getting advanced options
69 | if (opts && opts.advanced) {
70 | this.advancedOptions = opts.advanced;
71 | }
72 |
73 | // initiate config
74 | this.config = new Config(defaults, this.options, this.advancedOptions);
75 |
76 | // override tests if provided on the commandline
77 | if (this.options.tests) {
78 | this.config.config.tests = this.options.tests;
79 | }
80 |
81 | // prepare and load reporter(s)
82 | this._setupReporters();
83 |
84 | // count all passed & failed assertions
85 | this.reporterEvents.on('report:assertion', this._onReportAssertion.bind(this));
86 |
87 | // init the timer instance
88 | this.timer = new Timer();
89 |
90 | // prepare driver event emitter instance
91 | this._setupDriverEmitter();
92 |
93 | // check for file option, throw error if none is given
94 | // only bypasses if dalek runs in the remote mode
95 | if (!Array.isArray(this.config.get('tests')) && !this.options.remote) {
96 | this.reporterEvents.emit('error', 'No test files given!');
97 | this.driverEmitter.emit('killAll');
98 | process.exit(127);
99 | }
100 |
101 | // init the driver instance
102 | this._initDriver();
103 |
104 | // check if dalek runs as a remote browser launcher
105 | if (this.options.remote) {
106 | var host = new Host({reporterEvents: this.reporterEvents, config: this.config});
107 | host.run({
108 | port: !isNaN(parseFloat(this.options.remote)) && isFinite(this.options.remote) ? this.options.remote : false
109 | });
110 | }
111 | };
112 |
113 | /**
114 | * Daleks base module
115 | * Used to configure all the things
116 | * and to start off the tests
117 | *
118 | * @module DalekJS
119 | * @class Dalek
120 | */
121 |
122 | Dalek.prototype = {
123 |
124 | /**
125 | * Runs the configured testsuites
126 | *
127 | * @method run
128 | * @chainable
129 | */
130 |
131 | run: function () {
132 | // early return; in case of remote
133 | if (this.options.remote) {
134 | return this;
135 | }
136 |
137 | // start the timer to measure the execution time
138 | this.timer.start();
139 |
140 | // emit the runner started event
141 | this.reporterEvents.emit('report:runner:started');
142 |
143 | // execute all given drivers sequentially
144 | var drivers = this.driver.getDrivers();
145 | async.series(drivers, this.testsuitesFinished.bind(this));
146 | return this;
147 | },
148 |
149 | /**
150 | * Reports the all testsuites executed event
151 | *
152 | * @method testsuitesFinished
153 | * @chainable
154 | */
155 |
156 | testsuitesFinished: function () {
157 | this.driverEmitter.emit('tests:complete');
158 | setTimeout(this.reportRunFinished.bind(this), 0);
159 | return this;
160 | },
161 |
162 | /**
163 | * Reports the all testsuites executed event
164 | *
165 | * @method reportRunFinished
166 | * @chainable
167 | */
168 |
169 | reportRunFinished: function () {
170 | this.reporterEvents.emit('report:runner:finished', {
171 | elapsedTime: this.timer.stop().getElapsedTimeFormatted(),
172 | assertions: this.assertionsFailed + this.assertionsPassed,
173 | assertionsFailed: this.assertionsFailed,
174 | assertionsPassed: this.assertionsPassed,
175 | status: this.runnerStatus
176 | });
177 |
178 | //we want to exit process with code 1 to single that test did not pass
179 | if(this.runnerStatus !== true) {
180 | var processExitCaptured = false;
181 |
182 | process.on('exit', function() {
183 | if(processExitCaptured === false) {
184 | processExitCaptured = true;
185 | process.exit(1);
186 | }
187 | });
188 | }
189 |
190 | return this;
191 | },
192 |
193 | /**
194 | * Normalizes options
195 | *
196 | * @method normalizeOptions
197 | * @param {object} options Raw options
198 | * @return {object} Normalized options
199 | */
200 |
201 | normalizeOptions: function (options) {
202 | Object.keys(options).forEach(function (key) {
203 | if ({reporter: 1, driver: 1}[key]) {
204 | options[key] = options[key].map(function (input) { return input.trim(); });
205 | }
206 | });
207 |
208 | return options;
209 | },
210 |
211 | /**
212 | * Sets up system env properties
213 | *
214 | * @method _initialize
215 | * @chainable
216 | * @private
217 | */
218 |
219 | _initialize: function () {
220 | // prepare error data
221 | this.warnings = [];
222 | this.errors = [];
223 |
224 | // prepare state data for the complete test run
225 | this.runnerStatus = true;
226 | this.assertionsFailed = 0;
227 | this.assertionsPassed = 0;
228 |
229 | return this;
230 | },
231 |
232 | /**
233 | * Sets up all the reporters
234 | *
235 | * @method _setupReporters
236 | * @chainable
237 | * @private
238 | */
239 |
240 | _setupReporters: function () {
241 | this.reporters = [];
242 | this.reporterEvents = new EventEmitter2();
243 | this.reporterEvents.setMaxListeners(Infinity);
244 | this.options.reporter = this.config.verifyReporters(this.config.get('reporter'), Reporter);
245 | this.options.reporter.forEach(this._addReporter, this);
246 | return this;
247 | },
248 |
249 | /**
250 | * Adds a reporter
251 | *
252 | * @method _addReporter
253 | * @param {string} reporter Name of the reporter to add
254 | * @chainable
255 | * @private
256 | */
257 |
258 | _addReporter: function (reporter) {
259 | this.reporters.push(Reporter.loadReporter(reporter, {events: this.reporterEvents, config: this.config, logLevel: this.config.get('logLevel')}));
260 | return this;
261 | },
262 |
263 | /**
264 | * Updates the assertion state
265 | *
266 | * @method _onReportAssertion
267 | * @param {object} assertion Informations aout the runned assertions
268 | * @chainable
269 | * @private
270 | */
271 |
272 | _onReportAssertion: function (assertion) {
273 | if (assertion.success) {
274 | this.assertionsPassed++;
275 | } else {
276 | this.runnerStatus = false;
277 | this.assertionsFailed++;
278 | }
279 | return this;
280 | },
281 |
282 | /**
283 | * Initizializes the driver instances
284 | *
285 | * @method _initDriver
286 | * @chainable
287 | * @private
288 | */
289 |
290 | _initDriver: function () {
291 | this.driver = new Driver({
292 | config: this.config,
293 | driverEmitter: this.driverEmitter,
294 | reporterEvents: this.reporterEvents
295 | });
296 |
297 | this.options.driver = this.config.verifyDrivers(this.config.get('driver'), this.driver);
298 | return this;
299 | },
300 |
301 | /**
302 | * Sets up the event dispatcher for driver events
303 | *
304 | * @method _setupDriverEmitter
305 | * @chainable
306 | * @private
307 | */
308 |
309 | _setupDriverEmitter: function () {
310 | var driverEmitter = new EventEmitter2();
311 | driverEmitter.setMaxListeners(Infinity);
312 | this.driverEmitter = driverEmitter;
313 | return this;
314 | },
315 |
316 | /**
317 | * Make sure to shutdown dalek & its spawned
318 | * components, webservers gracefully if a
319 | * runtime error pops up
320 | *
321 | * @method _registerExceptionHandler
322 | * @private
323 | * @chainable
324 | */
325 |
326 | _registerExceptionHandler: function () {
327 | process.setMaxListeners(Infinity);
328 | process.on('uncaughtException', this._shutdown.bind(this));
329 | return this;
330 | },
331 |
332 | /**
333 | * Shutdown on uncaught exception
334 | *
335 | * @method _shutdown
336 | * @param {object} exception Runtime exception
337 | * @private
338 | */
339 |
340 | _shutdown: function (exception) {
341 | // ios emulator hack, needs to go in the future
342 | if (exception.message && exception.message.search('This socket has been ended by the other party') !== -1) {
343 | return false;
344 | }
345 |
346 | this.driverEmitter.emit('killAll');
347 | this.reporterEvents.emit('error', exception);
348 | }
349 |
350 | };
351 |
352 | // export dalek as a module
353 | module.exports = Dalek;
354 |
--------------------------------------------------------------------------------
/lib/dalek/actions.js:
--------------------------------------------------------------------------------
1 | /*!
2 | *
3 | * Copyright (c) 2013 Sebastian Golasch
4 | *
5 | * Permission is hereby granted, free of charge, to any person obtaining a
6 | * copy of this software and associated documentation files (the "Software"),
7 | * to deal in the Software without restriction, including without limitation
8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 | * and/or sell copies of the Software, and to permit persons to whom the
10 | * Software is furnished to do so, subject to the following conditions:
11 | *
12 | * The above copyright notice and this permission notice shall be included
13 | * in all copies or substantial portions of the Software.
14 | *
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 | * DEALINGS IN THE SOFTWARE.
22 | */
23 |
24 | 'use strict';
25 |
26 | // ext. libs
27 | var Q = require('q');
28 | var uuid = require('./uuid');
29 | var cheerio = require('cheerio');
30 |
31 | // int. global
32 | var reporter = null;
33 |
34 | /**
35 | * Actions are a way to control your browsers, e.g. simulate user interactions
36 | * like clicking elements, open urls, filling out input fields, etc.
37 | *
38 | * @class Actions
39 | * @constructor
40 | * @part Actions
41 | * @api
42 | */
43 |
44 | var Actions = function () {
45 | this.uuids = {};
46 | };
47 |
48 | /**
49 | * It can be really cumbersome to repeat selectors all over when performing
50 | * multiple actions or assertions on the same element(s).
51 | * When you use the query method (or its alias $), you're able to specify a
52 | * selector once instead of repeating it all over the place.
53 | *
54 | * So, instead of writing this:
55 | *
56 | * ```javascript
57 | * test.open('http://doctorwhotv.co.uk/')
58 | * .assert.text('#nav').is('Navigation')
59 | * .assert.visible('#nav')
60 | * .assert.attr('#nav', 'data-nav', 'true')
61 | * .click('#nav')
62 | * .done();
63 | * ```
64 | *
65 | * you can write this:
66 | *
67 | * ```javascript
68 | * test.open('http://doctorwhotv.co.uk/')
69 | * .query('#nav')
70 | * .assert.text().is('Navigation')
71 | * .assert.visible()
72 | * .assert.attr('data-nav', 'true')
73 | * .click()
74 | * .end()
75 | * .done();
76 | * ```
77 | *
78 | * Always make sure to terminate it with the [end](assertions.html#meth-end) method!
79 | *
80 | * @api
81 | * @method query
82 | * @param {string} selector Selector of the element to query
83 | * @chainable
84 | */
85 |
86 | Actions.prototype.query = function (selector) {
87 | var that = !this.test ? this : this.test;
88 | that.lastChain.push('querying');
89 | that.selector = selector;
90 | that.querying = true;
91 | return this.test ? this : that;
92 | };
93 |
94 | /**
95 | * Alias of query
96 | *
97 | * @api
98 | * @method $
99 | * @param {string} selector Selector of the element to query
100 | * @chainable
101 | */
102 |
103 | Actions.prototype.$ = Actions.prototype.query;
104 |
105 | /**
106 | * Triggers a mouse event on the first element found matching the provided selector.
107 | * Supported events are mouseup, mousedown, click, mousemove, mouseover and mouseout.
108 | * TODO: IMPLEMENT
109 | *
110 | * @method mouseEvent
111 | * @param {string} type
112 | * @param {string} selector
113 | * @chainable
114 | */
115 |
116 | Actions.prototype.mouseEvent = function (type, selector) {
117 | var hash = uuid();
118 | var cb = this._generateCallbackAssertion('mouseEvent', 'mouseEvent', type, selector, hash);
119 | this._addToActionQueue([type, selector, hash], 'mouseEvent', cb);
120 | return this;
121 | };
122 |
123 | /**
124 | * Sets HTTP_AUTH_USER and HTTP_AUTH_PW values for HTTP based authentication systems.
125 | *
126 | * If your site is behind a HTTP basic auth, you're able to set the username and the password
127 | *
128 | * ```javascript
129 | * test.setHttpAuth('OSWIN', 'rycbrar')
130 | * .open('http://admin.therift.com');
131 | * ```
132 | *
133 | * Most of the time, you`re not storing your passwords within files that will be checked
134 | * in your vcs, for this scenario, you have two options:
135 | *
136 | * The first option is, to use daleks cli capabilities to generate config variables
137 | * from the command line, like this
138 | *
139 | * ```batch
140 | * $ dalek --vars USER=OSWIN,PASS=rycbrar
141 | * ```
142 | *
143 | * ```javascript
144 | * test.setHttpAuth(test.config.get('USER'), test.config.get('PASS'))
145 | * .open('http://admin.therift.com');
146 | * ```
147 | *
148 | * The second option is, to use env variables to generate config variables
149 | * from the command line, like this
150 | *
151 | * ```batch
152 | * $ SET USER=OSWIN
153 | * $ SET PASS=rycbrar
154 | * $ dalek
155 | * ```
156 | *
157 | * ```javascript
158 | * test.setHttpAuth(test.config.get('USER'), test.config.get('PASS'))
159 | * .open('http://admin.therift.com');
160 | * ```
161 | *
162 | * If both, dalek variables & env variables are set, the dalek variables win.
163 | * For more information about this, I recommend to check out the [configuration docs](/docs/config.html)
164 | *
165 | * TODO: IMPLEMENT
166 | *
167 | * @method setHttpAuth
168 | * @param {string} username
169 | * @param {string} password
170 | * @return {Actions}
171 | */
172 |
173 | Actions.prototype.setHttpAuth = function (username, password) {
174 | var hash = uuid();
175 | var cb = this._generateCallbackAssertion('setHttpAuth', 'setHttpAuth', username, password, hash);
176 | this._addToActionQueue([username, password, hash], 'setHttpAuth', cb);
177 | return this;
178 | };
179 |
180 | /**
181 | * Switches to an iFrame context
182 | *
183 | * Sometimes you encounter situations, where you need to drive/access an iFrame sitting in your page.
184 | * You can access such frames with this method, but be aware of the fact, that the complete test context
185 | * than switches to the iframe context, every action and assertion will be executed within the iFrame context.
186 | * Btw.: The domain of the IFrame can be whatever you want, this method has no same origin policy restrictions.
187 | *
188 | * If you wan't to get back to the parents context, you have to use the [toParent](#meth-toParent) method.
189 | *
190 | * ```html
191 | *
192 | *
193 | *
194 | * ```
195 | *
196 | * ```javascript
197 | * test.open('http://adomain.withiframe.com')
198 | * .assert.title().is('Title of a page that embeds an iframe')
199 | * .toFrame('#login')
200 | * .assert.title().is('Title of a page that can be embedded as an iframe')
201 | * .toParent()
202 | * .done();
203 | * ```
204 | *
205 | * > NOTE: Buggy in Firefox
206 | *
207 | * @api
208 | * @method toFrame
209 | * @param {string} selector Selector of the frame to switch to
210 | * @chainable
211 | */
212 |
213 | Actions.prototype.toFrame = function (selector) {
214 | var hash = uuid();
215 |
216 | if (this.querying === true) {
217 | selector = this.selector;
218 | }
219 |
220 | var cb = this._generateCallbackAssertion('toFrame', 'toFrame', selector, hash);
221 | this._addToActionQueue([selector, hash], 'toFrame', cb);
222 | return this;
223 | };
224 |
225 | /**
226 | * Switches back to the parent page context when the test context has been
227 | * switched to an iFrame context
228 | *
229 | * ```html
230 | *
231 | *
232 | *
233 | * ```
234 | *
235 | * ```javascript
236 | * test.open('http://adomain.withiframe.com')
237 | * .assert.title().is('Title of a page that embeds an iframe')
238 | * .toFrame('#login')
239 | * .assert.title().is('Title of a page that can be embedded as an iframe')
240 | * .toParent()
241 | * .assert.title().is('Title of a page that embeds an iframe')
242 | * .done();
243 | * ```
244 | *
245 | * > NOTE: Buggy in Firefox
246 | *
247 | * @api
248 | * @method toParent
249 | * @chainable
250 | */
251 |
252 | Actions.prototype.toParent = function () {
253 | var hash = uuid();
254 | var cb = this._generateCallbackAssertion('toFrame', 'toFrame', null, hash);
255 | this._addToActionQueue([null, hash], 'toFrame', cb);
256 | return this;
257 | };
258 |
259 | /**
260 | * Switches to a different window context
261 | *
262 | * Sometimes you encounter situations, where you need to access a different window, like popup windows.
263 | * You can access such windows with this method, but be aware of the fact, that the complete test context
264 | * than switches to the window context, every action and assertion will be executed within the chosen window context.
265 | * Btw.: The domain of the window can be whatever you want, this method has no same origin policy restrictions.
266 | *
267 | * If you want to get back to the parents context, you have to use the [toParentWindow](#meth-toParentWindow) method.
268 | *
269 | * ```html
270 | *