]>
Commit | Line | Data |
---|---|---|
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_OPTIONS = { 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 waitForElement(elem) { | |
44 | return browser.wait(until.elementLocated(elem), TEST_TIMEOUT).then(function () { | |
45 | return browser.wait(until.elementIsVisible(browser.findElement(elem)), TEST_TIMEOUT); | |
46 | }); | |
47 | } | |
48 | ||
49 | // tests which are used more than once | |
50 | function login(done) { | |
51 | browser.manage().deleteAllCookies(); | |
52 | browser.get('https://' + app.fqdn + '/_admin'); | |
53 | ||
54 | waitForElement(By.id('loginUsernameInput')).then(function () { | |
55 | browser.findElement(By.id('loginUsernameInput')).sendKeys(process.env.USERNAME); | |
56 | browser.findElement(By.id('loginPasswordInput')).sendKeys(process.env.PASSWORD); | |
57 | browser.findElement(By.id('loginSubmitButton')).click(); | |
58 | ||
59 | waitForElement(By.id('burgerMenuButton')).then(function () { | |
60 | done(); | |
61 | }); | |
62 | }); | |
63 | } | |
64 | ||
65 | function logout(done) { | |
66 | browser.get('https://' + app.fqdn + '/_admin'); | |
67 | ||
68 | waitForElement(By.id('burgerMenuButton')).then(function () { | |
69 | browser.findElement(By.id('burgerMenuButton')).click(); | |
70 | ||
71 | // wait for open animation | |
72 | browser.sleep(5000); | |
73 | ||
74 | waitForElement(By.id('logoutButton')).then(function () { | |
75 | browser.findElement(By.id('logoutButton')).click(); | |
76 | ||
77 | waitForElement(By.id('loginUsernameInput')).then(function () { | |
78 | done(); | |
79 | }); | |
80 | }); | |
81 | }); | |
82 | } | |
83 | ||
84 | function checkFileIsListed(name, done) { | |
85 | browser.get('https://' + app.fqdn + '/_admin'); | |
86 | ||
87 | waitForElement(By.xpath('//*[text()="' + name + '"]')).then(function () { | |
88 | done(); | |
89 | }); | |
90 | } | |
91 | ||
92 | function checkFileIsPresent(done) { | |
93 | browser.get('https://' + app.fqdn + '/' + TEST_FILE_NAME_0); | |
94 | ||
95 | waitForElement(By.xpath('//*[text()="test"]')).then(function () { | |
96 | done(); | |
97 | }); | |
98 | } | |
99 | ||
100 | function checkIndexFileIsServedUp(done) { | |
101 | browser.get('https://' + app.fqdn); | |
102 | ||
103 | waitForElement(By.xpath('//*[text()="test"]')).then(function () { | |
104 | done(); | |
105 | }); | |
106 | } | |
107 | ||
108 | function checkFileIsGone(name, done) { | |
109 | superagent.get('https://' + app.fqdn + '/' + name).end(function (error, result) { | |
110 | expect(error).to.be.an('object'); | |
111 | expect(error.response.status).to.equal(404); | |
112 | expect(result).to.be.an('object'); | |
113 | done(); | |
114 | }); | |
115 | } | |
116 | ||
117 | function cliLogin(done) { | |
118 | 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' } ); | |
119 | done(); | |
120 | } | |
121 | ||
122 | function uploadFile(name, done) { | |
123 | // File upload can't be tested with selenium, since the file input is not visible and thus can't be interacted with :-( | |
124 | ||
125 | execSync(path.join(__dirname, '/../cli/surfer.js') + ' put ' + path.join(__dirname, name) + ' /', { stdio: 'inherit' } ); | |
126 | done(); | |
127 | } | |
128 | ||
129 | xit('build app', function () { execSync('cloudron build', EXEC_OPTIONS); }); | |
130 | ||
131 | it('install app', function () { execSync(`cloudron install --location ${LOCATION}`, EXEC_OPTIONS); }); | |
132 | ||
133 | it('can get app information', function () { | |
134 | var inspect = JSON.parse(execSync('cloudron inspect')); | |
135 | app = inspect.apps.filter(function (a) { return a.location === LOCATION; })[0]; | |
136 | expect(app).to.be.an('object'); | |
137 | }); | |
138 | ||
139 | it('can login', login); | |
140 | it('can cli login', cliLogin); | |
141 | it('can upload file', uploadFile.bind(null, TEST_FILE_NAME_0)); | |
142 | it('file is listed', checkFileIsListed.bind(null, TEST_FILE_NAME_0)); | |
143 | it('file is served up', checkFileIsPresent); | |
144 | it('file is served up', checkIndexFileIsServedUp); | |
145 | it('can upload second file', uploadFile.bind(null, TEST_FILE_NAME_1)); | |
146 | it('file is listed', checkFileIsListed.bind(null, TEST_FILE_NAME_1)); | |
147 | it('can delete second file with cli', function () { | |
148 | execSync(path.join(__dirname, '/../cli/surfer.js') + ' del ' + TEST_FILE_NAME_1, { stdio: 'inherit' } ); | |
149 | }); | |
150 | it('second file is gone', checkFileIsGone.bind(null, TEST_FILE_NAME_1)); | |
151 | it('can logout', logout); | |
152 | ||
153 | it('backup app', function () { execSync(`cloudron backup create --app ${app.id}`, EXEC_OPTIONS); }); | |
154 | it('restore app', function () { execSync(`cloudron restore --app ${app.id}`, EXEC_OPTIONS); }); | |
155 | ||
156 | it('can login', login); | |
157 | it('file is listed', checkFileIsListed.bind(null, TEST_FILE_NAME_0)); | |
158 | it('file is served up', checkFileIsPresent); | |
159 | it('file is served up', checkIndexFileIsServedUp); | |
160 | it('second file is still gone', checkFileIsGone.bind(null, TEST_FILE_NAME_1)); | |
161 | it('can logout', logout); | |
162 | ||
163 | it('move to different location', function (done) { | |
164 | browser.manage().deleteAllCookies(); | |
165 | ||
166 | // ensure we don't hit NXDOMAIN in the mean time | |
167 | browser.get('about:blank').then(function () { | |
168 | execSync(`cloudron configure --location ${LOCATION}2 --app ${app.id}`, EXEC_OPTIONS); | |
169 | ||
170 | var inspect = JSON.parse(execSync('cloudron inspect')); | |
171 | app = inspect.apps.filter(function (a) { return a.location === LOCATION + '2'; })[0]; | |
172 | expect(app).to.be.an('object'); | |
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_OPTIONS); | |
188 | done(); | |
189 | }); | |
190 | }); | |
191 | }); |