]> git.immae.eu Git - perso/Immae/Projets/Nodejs/Surfer.git/blob - test/test.js
Add update tests
[perso/Immae/Projets/Nodejs/Surfer.git] / test / test.js
1 #!/usr/bin/env node
2
3 'use strict';
4
5 /* global describe */
6 /* global before */
7 /* global after */
8 /* global it */
9
10 var execSync = require('child_process').execSync,
11 expect = require('expect.js'),
12 path = require('path'),
13 util = require('util'),
14 superagent = require('superagent'),
15 { Builder, By, until } = require('selenium-webdriver'),
16 { Options } = require('selenium-webdriver/chrome');
17
18 if (!process.env.USERNAME || !process.env.PASSWORD) {
19 console.log('USERNAME and PASSWORD env vars need to be set');
20 process.exit(1);
21 }
22
23 describe('Application life cycle test', function () {
24 this.timeout(0);
25
26 const EXEC_ARGS = { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' };
27 const LOCATION = 'test';
28 const TEST_TIMEOUT = 10000;
29 const TEST_FILE_NAME_0 = 'index.html';
30 const TEST_FILE_NAME_1 = 'test.txt';
31
32 var app;
33 var browser;
34
35 before(function () {
36 browser = new Builder().forBrowser('chrome').setChromeOptions(new Options().windowSize({ width: 1280, height: 1024 })).build();
37 });
38
39 after(function () {
40 browser.quit();
41 });
42
43 function getAppInfo() {
44 var inspect = JSON.parse(execSync('cloudron inspect'));
45 app = inspect.apps.filter(function (a) { return a.location === LOCATION; })[0];
46 expect(app).to.be.an('object');
47 }
48
49 function waitForElement(elem) {
50 return browser.wait(until.elementLocated(elem), TEST_TIMEOUT).then(function () {
51 return browser.wait(until.elementIsVisible(browser.findElement(elem)), TEST_TIMEOUT);
52 });
53 }
54
55 // tests which are used more than once
56 function login(done) {
57 browser.manage().deleteAllCookies();
58 browser.get('https://' + app.fqdn + '/_admin');
59
60 waitForElement(By.id('loginUsernameInput')).then(function () {
61 browser.findElement(By.id('loginUsernameInput')).sendKeys(process.env.USERNAME);
62 browser.findElement(By.id('loginPasswordInput')).sendKeys(process.env.PASSWORD);
63 browser.findElement(By.id('loginSubmitButton')).click();
64
65 waitForElement(By.id('burgerMenuButton')).then(function () {
66 done();
67 });
68 });
69 }
70
71 function logout(done) {
72 browser.get('https://' + app.fqdn + '/_admin');
73
74 waitForElement(By.id('burgerMenuButton')).then(function () {
75 browser.findElement(By.id('burgerMenuButton')).click();
76
77 // wait for open animation
78 browser.sleep(5000);
79
80 waitForElement(By.id('logoutButton')).then(function () {
81 browser.findElement(By.id('logoutButton')).click();
82
83 waitForElement(By.id('loginUsernameInput')).then(function () {
84 done();
85 });
86 });
87 });
88 }
89
90 function checkFileIsListed(name, done) {
91 browser.get('https://' + app.fqdn + '/_admin');
92
93 waitForElement(By.xpath('//*[text()="' + name + '"]')).then(function () {
94 done();
95 });
96 }
97
98 function checkFileIsPresent(done) {
99 browser.get('https://' + app.fqdn + '/' + TEST_FILE_NAME_0);
100
101 waitForElement(By.xpath('//*[text()="test"]')).then(function () {
102 done();
103 });
104 }
105
106 function checkIndexFileIsServedUp(done) {
107 browser.get('https://' + app.fqdn);
108
109 waitForElement(By.xpath('//*[text()="test"]')).then(function () {
110 done();
111 });
112 }
113
114 function checkFileIsGone(name, done) {
115 superagent.get('https://' + app.fqdn + '/' + name).end(function (error, result) {
116 expect(error).to.be.an('object');
117 expect(error.response.status).to.equal(404);
118 expect(result).to.be.an('object');
119 done();
120 });
121 }
122
123 function cliLogin(done) {
124 execSync(util.format('%s login %s --username %s --password %s', path.join(__dirname, '/../cli/surfer.js'), app.fqdn, process.env.USERNAME, process.env.PASSWORD), { stdio: 'inherit' } );
125 done();
126 }
127
128 function uploadFile(name, done) {
129 // File upload can't be tested with selenium, since the file input is not visible and thus can't be interacted with :-(
130
131 execSync(path.join(__dirname, '/../cli/surfer.js') + ' put ' + path.join(__dirname, name) + ' /', { stdio: 'inherit' } );
132 done();
133 }
134
135 xit('build app', function () { execSync('cloudron build', EXEC_ARGS); });
136
137 it('install app', function () { execSync(`cloudron install --location ${LOCATION}`, EXEC_ARGS); });
138
139 it('can get app information', getAppInfo);
140
141 it('can login', login);
142 it('can cli login', cliLogin);
143 it('can upload file', uploadFile.bind(null, TEST_FILE_NAME_0));
144 it('file is listed', checkFileIsListed.bind(null, TEST_FILE_NAME_0));
145 it('file is served up', checkFileIsPresent);
146 it('file is served up', checkIndexFileIsServedUp);
147 it('can upload second file', uploadFile.bind(null, TEST_FILE_NAME_1));
148 it('file is listed', checkFileIsListed.bind(null, TEST_FILE_NAME_1));
149 it('can delete second file with cli', function () {
150 execSync(path.join(__dirname, '/../cli/surfer.js') + ' del ' + TEST_FILE_NAME_1, { stdio: 'inherit' } );
151 });
152 it('second file is gone', checkFileIsGone.bind(null, TEST_FILE_NAME_1));
153 it('can logout', logout);
154
155 it('backup app', function () { execSync(`cloudron backup create --app ${app.id}`, EXEC_ARGS); });
156 it('restore app', function () { execSync(`cloudron restore --app ${app.id}`, EXEC_ARGS); });
157
158 it('can login', login);
159 it('file is listed', checkFileIsListed.bind(null, TEST_FILE_NAME_0));
160 it('file is served up', checkFileIsPresent);
161 it('file is served up', checkIndexFileIsServedUp);
162 it('second file is still gone', checkFileIsGone.bind(null, TEST_FILE_NAME_1));
163 it('can logout', logout);
164
165 it('move to different location', function (done) {
166 browser.manage().deleteAllCookies();
167
168 // ensure we don't hit NXDOMAIN in the mean time
169 browser.get('about:blank').then(function () {
170 execSync(`cloudron configure --location ${LOCATION}2 --app ${app.id}`, EXEC_ARGS);
171
172 getAppInfo();
173
174 done();
175 });
176 });
177
178 it('can login', login);
179 it('file is listed', checkFileIsListed.bind(null, TEST_FILE_NAME_0));
180 it('file is served up', checkFileIsPresent);
181 it('file is served up', checkIndexFileIsServedUp);
182 it('can logout', logout);
183
184 it('uninstall app', function (done) {
185 // ensure we don't hit NXDOMAIN in the mean time
186 browser.get('about:blank').then(function () {
187 execSync(`cloudron uninstall --app ${app.id}`, EXEC_ARGS);
188 done();
189 });
190 });
191
192 // test update
193 it('can install app', function () {
194 execSync(`cloudron install --appstore-id io.cloudron.surfer --location ${LOCATION}`, EXEC_ARGS);
195 });
196
197 it('can get app information', getAppInfo);
198 it('can login', login);
199 it('can cli login', cliLogin);
200 it('can upload file', uploadFile.bind(null, TEST_FILE_NAME_0));
201 it('file is listed', checkFileIsListed.bind(null, TEST_FILE_NAME_0));
202 it('file is served up', checkFileIsPresent);
203 it('file is served up', checkIndexFileIsServedUp);
204 it('can logout', logout);
205
206 it('can update', function () {
207 execSync(`cloudron update --app ${LOCATION}`, EXEC_ARGS);
208 });
209
210 it('can login', login);
211 it('file is listed', checkFileIsListed.bind(null, TEST_FILE_NAME_0));
212 it('file is served up', checkFileIsPresent);
213 it('file is served up', checkIndexFileIsServedUp);
214 it('can logout', logout);
215
216 it('uninstall app', function (done) {
217 // ensure we don't hit NXDOMAIN in the mean time
218 browser.get('about:blank').then(function () {
219 execSync(`cloudron uninstall --app ${app.id}`, EXEC_ARGS);
220 done();
221 });
222 });
223 });