1 | # Getting started
|
2 |
|
3 | ## Initial setup
|
4 | To create an initial setup, run the following commands:
|
5 |
|
6 | ```
|
7 | npm install green-light --save-dev
|
8 | mkdir -p test/{mocks,tests}
|
9 | touch test/runner.js
|
10 | touch test/tests/hello-world.js
|
11 | touch test/mocks/hello-world.json
|
12 | ```
|
13 |
|
14 | Use Node to run GreenLight:
|
15 |
|
16 | ```
|
17 | node test/runner.js
|
18 | ```
|
19 |
|
20 | Or add the following to your `package.json` and run `npm test`:
|
21 |
|
22 | ```json
|
23 | "scripts": {
|
24 | "test": "node test/runner.js"
|
25 | }
|
26 | ```
|
27 |
|
28 | At this point, this doesn't do anything. That's because `runner.js` doesn't have anything in it. Let's do that:
|
29 |
|
30 | ```js
|
31 | var GreenLight = require('green-light');
|
32 |
|
33 | GreenLight
|
34 | .init()
|
35 | .then(function(exitCode) {
|
36 | GreenLight.done(exitCode);
|
37 | })
|
38 | .catch(function(err) {
|
39 | GreenLight.fail(err);
|
40 | });
|
41 | ```
|
42 |
|
43 | To make things easier later on, I'd recommend installing [Babel](https://babeljs.io) for fancy ES6-support:
|
44 |
|
45 | ```
|
46 | npm install --save-dev babel-core babel-preset-es2015 babel-register
|
47 | echo '{ "presets": ["es2015"] }' > .babelrc
|
48 | ```
|
49 |
|
50 | and add the require hook to `test/runner.js`:
|
51 |
|
52 | ```js
|
53 | require('babel-register');
|
54 | const GreenLight = require('green-light');
|
55 |
|
56 | GreenLight
|
57 | .init()
|
58 | .then(exitCode => GreenLight.done(exitCode))
|
59 | .catch(err => GreenLight.fail(err));
|
60 | ```
|
61 |
|
62 | > Watch out: `require('babel-register')` makes it possible to do new stuff in nested files, but not in `runner.js` itself. While newer versions of Node support things like fat arrows, you have to `require` `GreenLight` here the old way :(
|
63 |
|
64 | Well... `npm test` still doesn't do a lot, but we'll get to that. Let's start with the API.
|
65 |
|
66 | ## API
|
67 | To setup the mocked API, add some content to `test/mocks/hello-world.json`:
|
68 |
|
69 | ```json
|
70 | {
|
71 | "title": "Hey there!"
|
72 | }
|
73 | ```
|
74 |
|
75 | and add the following to `test/runner.js`:
|
76 |
|
77 | ```js
|
78 | // GreenLight
|
79 | // .init()
|
80 | .then(() => {
|
81 | return GreenLight.runAPI({
|
82 | verbose: true,
|
83 | port: 4000, // or whatever port is available to use
|
84 | dir: './test/mocks' // or wherever your mock-files are
|
85 | });
|
86 | })
|
87 | .then(() => {
|
88 | return new Promise((resolve, reject) => {
|
89 | setTimeout(resolve, 100000);
|
90 | });
|
91 | })
|
92 | // .then(exitCode => GreenLight.done(exitCode))
|
93 | // .catch(err => GreenLight.fail(err));
|
94 | ```
|
95 |
|
96 | That extra promise and timeout are there to check out what's going on. Run `npm test` and open `http://localhost:4000/hello-world.json` to see if this works as expected.
|
97 |
|
98 | ## Target
|
99 | The target is your app we want to test. It can be anything, as long as it can be started with a command on your CLI, and it can be configured to connect to the mocked API instead of its regular source. Add `runTarget()` to `test/runner.js`:
|
100 |
|
101 | ```js
|
102 | // GreenLight
|
103 | // .init()
|
104 | // .then(() => {
|
105 | // return GreenLight.runAPI({
|
106 | // verbose: true,
|
107 | // port: 4000,
|
108 | // dir: './test/mocks'
|
109 | // });
|
110 | // })
|
111 | .then(() => {
|
112 | return GreenLight.runTarget({
|
113 | verbose: true,
|
114 | command: 'npm start --config=test', // or whatever command you'll run to start your project
|
115 | checkUrl: 'http://localhost:8000', // or whatever page is available as soon as your project is ready
|
116 | });
|
117 | })
|
118 | // .then(() => {
|
119 | // return new Promise((resolve, reject) => {
|
120 | // setTimeout(resolve, 100000);
|
121 | // });
|
122 | // })
|
123 | // .then(exitCode => GreenLight.done(exitCode))
|
124 | // .catch(err => GreenLight.fail(err));
|
125 | ```
|
126 |
|
127 | After starting the API, your project will start running (and it will be checked periodically to see if it's ready to test).
|
128 |
|
129 | ## Browser
|
130 | The browser will visit your target and can be configured like so:
|
131 |
|
132 | ```js
|
133 | // GreenLight
|
134 | // .init()
|
135 | // .then(() => {
|
136 | // return GreenLight.runAPI({
|
137 | // verbose: true,
|
138 | // port: 4000,
|
139 | // dir: './test/mocks'
|
140 | // });
|
141 | // })
|
142 | // .then(() => {
|
143 | // return GreenLight.runTarget({
|
144 | // verbose: true,
|
145 | // command: 'npm start --config=test',
|
146 | // checkUrl: 'http://localhost:8000',
|
147 | // });
|
148 | // })
|
149 | .then(() => {
|
150 | return GreenLight.runBrowser({
|
151 | verbose: true,
|
152 | baseUrl: 'http://localhost:8000', // or wherever your target is running
|
153 | jQuery: true,
|
154 | });
|
155 | })
|
156 | // .then(() => {
|
157 | // return new Promise((resolve, reject) => {
|
158 | // setTimeout(resolve, 100000);
|
159 | // });
|
160 | // })
|
161 | // .then(exitCode => GreenLight.done(exitCode))
|
162 | // .catch(err => GreenLight.fail(err));
|
163 | ```
|
164 |
|
165 | ## Tests
|
166 | Are you ready for this? Let's write an actual test in `test/tests/hello-world.js`:
|
167 |
|
168 | ```js
|
169 | import { api, browser, expect } from 'green-light';
|
170 |
|
171 | describe('Article', () => {
|
172 | describe('when it has a title', () => {
|
173 | it('renders the title', (done) => {
|
174 | api
|
175 | .respondTo('/hello-world.json')
|
176 | .andReplace('/title', 'Test title');
|
177 |
|
178 | browser
|
179 | .go('/hello-world')
|
180 | .then(window => {
|
181 | expect(window.$('h1').text()).to.equal('Test title');
|
182 | })
|
183 | .then(done, done);
|
184 | });
|
185 | });
|
186 |
|
187 | describe('when it does not have a title', () => {
|
188 | it('renders no title', (done) => {
|
189 | api
|
190 | .respondTo('/hello-world.json')
|
191 | .andReplace('/title', null);
|
192 |
|
193 | browser
|
194 | .go('/hello-world')
|
195 | .then(window => {
|
196 | expect(window.$('h1').length).to.equal(0);
|
197 | })
|
198 | .then(done, done);
|
199 | });
|
200 | });
|
201 | });
|
202 | ```
|
203 |
|
204 | Now we can configure the last step in `test/runner.js`:
|
205 |
|
206 | ```js
|
207 | // GreenLight
|
208 | // .init()
|
209 | // .then(() => {
|
210 | // return GreenLight.runAPI({
|
211 | // verbose: true,
|
212 | // port: 4000,
|
213 | // dir: './test/mocks'
|
214 | // });
|
215 | // })
|
216 | // .then(() => {
|
217 | // return GreenLight.runTarget({
|
218 | // verbose: true,
|
219 | // command: 'npm start --config=test',
|
220 | // checkUrl: 'http://localhost:8000',
|
221 | // });
|
222 | // })
|
223 | // .then(() => {
|
224 | // return GreenLight.runBrowser({
|
225 | // verbose: true,
|
226 | // baseUrl: 'http://localhost:8000',
|
227 | // jQuery: true,
|
228 | // });
|
229 | // })
|
230 | .then(() => {
|
231 | return GreenLight.runTests({
|
232 | verbose: true,
|
233 | glob: 'test/tests/**/*.js',
|
234 | mocha: {
|
235 | reporter: 'list',
|
236 | timeout: 5000,
|
237 | ui: 'bdd',
|
238 | }
|
239 | });
|
240 | })
|
241 | // .then(() => {
|
242 | // return new Promise((resolve, reject) => {
|
243 | // setTimeout(resolve, 100000);
|
244 | // });
|
245 | // })
|
246 | // .then(exitCode => GreenLight.done(exitCode))
|
247 | // .catch(err => GreenLight.fail(err));
|
248 | ```
|
249 |
|
250 | # Congratulations
|
251 | Remove that debugging and you should be good to go:
|
252 |
|
253 | ```js
|
254 | require('babel-register');
|
255 | const GreenLight = require('green-light');
|
256 |
|
257 | GreenLight
|
258 | .init()
|
259 | .then(() => {
|
260 | return GreenLight.runAPI({
|
261 | port: 4000,
|
262 | dir: './test/mocks'
|
263 | });
|
264 | })
|
265 | .then(() => {
|
266 | return GreenLight.runTarget({
|
267 | command: 'npm start --config=test',
|
268 | checkUrl: 'http://localhost:8000',
|
269 | });
|
270 | })
|
271 | .then(() => {
|
272 | return GreenLight.runBrowser({
|
273 | baseUrl: 'http://localhost:8000',
|
274 | jQuery: true,
|
275 | });
|
276 | })
|
277 | .then(() => {
|
278 | return GreenLight.runTests({
|
279 | glob: 'test/tests/**/*.js',
|
280 | mocha: {
|
281 | reporter: 'list',
|
282 | timeout: 5000,
|
283 | ui: 'bdd',
|
284 | }
|
285 | });
|
286 | })
|
287 | .then(exitCode => GreenLight.done(exitCode))
|
288 | .catch(err => GreenLight.fail(err));
|
289 | ```
|
290 |
|
291 | For more advanced options, take a look at:
|
292 |
|
293 | - [API](api.md)
|
294 | - [Target](target.md)
|
295 | - [Browser](browser.md)
|
296 | - [Tests](tests.md)
|