diff --git a/package.json b/package.json index caf7681d20..99e0bbfb03 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "q": "^1.4.1", "request": "~2.44.0", "serve-favicon": "^2.3.0", - "stripe": "*", + "stripe": "^4.2.0", "superagent": "~1.4.0", "swagger-node-express": "lefnire/swagger-node-express#habitrpg", "universal-analytics": "~0.3.2", @@ -112,7 +112,7 @@ "test:karma:watch": "karma start", "test:prepare:webdriver": "webdriver-manager update", "test:e2e:webdriver": "webdriver-manager start", - "test:e2e": "protractor protractor.conf.js", + "test:e2e": "protractor test/e2e/protractor.conf.js", "test:nodemon": "gulp test:nodemon", "start": "gulp run:dev", "sprites": "gulp sprites:compile", @@ -145,7 +145,7 @@ "mongoskin": "~0.6.1", "nock": "^2.17.0", "phantomjs": "^1.9", - "protractor": "~2.5.1", + "protractor": "^3.1.1", "rewire": "^2.3.3", "rimraf": "^2.4.3", "run-sequence": "^1.1.4", diff --git a/protractor.conf.js b/protractor.conf.js deleted file mode 100644 index 0f810a8915..0000000000 --- a/protractor.conf.js +++ /dev/null @@ -1,26 +0,0 @@ -// An example configuration file. -exports.config = { - // The address of a running selenium server. - seleniumAddress: 'http://localhost:4444/wd/hub', - - // Capabilities to be passed to the webdriver instance. - capabilities: { - 'browserName': 'firefox' - }, - - // Spec patterns are relative to the current working directly when - // protractor is called. - specs: ['test/e2e/e2e.js'], - - // A base URL for your application under test. Calls to protractor.get() - // with relative paths will be prepended with this. - baseUrl: 'http://localhost:3003', - - // Options to be passed to Jasmine-node. - jasmineNodeOpts: { - showColors: true, - defaultTimeoutInterval: 90000, - isVerbose: true, - displayPendingSpec: true - } -}; diff --git a/tasks/gulp-tests.js b/tasks/gulp-tests.js index 56a759bdfe..09a974c7f5 100644 --- a/tasks/gulp-tests.js +++ b/tasks/gulp-tests.js @@ -272,9 +272,6 @@ gulp.task('test:e2e', ['test:prepare', 'test:prepare:server'], (cb) => { let runner = exec( 'npm run test:e2e', (err, stdout, stderr) => { - /* - * Note: As it stands, protractor wont report pending specs - */ support.forEach(kill); cb(err); } @@ -296,15 +293,13 @@ gulp.task('test:e2e:safe', ['test:prepare', 'test:prepare:server'], (cb) => { let runner = exec( 'npm run test:e2e', (err, stdout, stderr) => { - /* - * Note: As it stands, protractor wont report pending specs - */ let match = stdout.match(/(\d+) tests?.*(\d) failures?/); + testResults.push({ - suite: 'End-to-End Specs', - pass: parseInt(match[1]) - parseInt(match[2]), - fail: parseInt(match[2]), - pend: 0 + suite: 'End-to-End Specs\t', + pass: testCount(stdout, /(\d+) passing/), + fail: testCount(stdout, /(\d+) failing/), + pend: testCount(stdout, /(\d+) pending/) }); support.forEach(kill); cb(); diff --git a/test/.eslintrc b/test/.eslintrc index 7b5868eca9..9ee7ce9e28 100644 --- a/test/.eslintrc +++ b/test/.eslintrc @@ -1,6 +1,7 @@ { "rules": { "one-var": 0, + "func-names": 0, "max-nested-callbacks": 0, "no-unused-expressions": 0, "mocha/no-exclusive-tests": 2, diff --git a/test/e2e/.eslintrc b/test/e2e/.eslintrc index ecf3d02e9f..252188793a 100644 --- a/test/e2e/.eslintrc +++ b/test/e2e/.eslintrc @@ -1,13 +1,7 @@ { - "rules": { - "func-names": 0, - "no-var": 0, - "prefer-template": 0 - }, "globals": { "browser": true, "by": true, - "element": true, - "jasmine": true + "element": true } } diff --git a/test/e2e/e2e.js b/test/e2e/e2e.js deleted file mode 100644 index 90a3a742f3..0000000000 --- a/test/e2e/e2e.js +++ /dev/null @@ -1,62 +0,0 @@ -'use strict'; - -var fs = require('fs'); - -describe('front page', function () { - beforeEach(function () { - browser.ignoreSynchronization = true; - browser.get('/'); - browser.sleep(1000); - }); - - // based on https://github.com/angular/protractor/issues/114#issuecomment-29046939 - afterEach(function () { - var currentSpec = jasmine.getEnv().currentSpec; - var passed = currentSpec.results().passed(); - if (!passed) { - var filename = 'exception_' + currentSpec.description + '.png'; - browser.takeScreenshot().then(function (png) { - var buffer = new Buffer(png, 'base64'); - var stream = fs.createWriteStream(filename); - stream.write(buffer); - stream.end(); - }); - } - }); - - it('shows the front page', function () { - var button = element(by.id('play-btn')); - expect(button.getText()).toEqual('Join for free'); - }); - - it('does not login when using wrong credentials', function () { - var button = element(by.id('play-btn')); - button.click(); - browser.sleep(1000); - element(by.model('loginUsername')).sendKeys('username'); - element(by.model('loginPassword')).sendKeys('pass'); - var login = element(by.css('#loginForm input[value="Login"]')); - login.click(); - var alertDialog = browser.switchTo().alert(); - expect(alertDialog.getText()).toMatch('Uh-oh - your username or password is incorrect.\n- Make sure your username or email is typed correctly.\n- You may have signed up with Facebook, not email. Double-check by trying Facebook login.\n- If you forgot your password, click "Forgot Password" on the habitica.com website\'s login form.'); - alertDialog.accept(); - }); - - xit('registers a new user', function () { - var button = element(by.id('play-btn')); - button.click(); - browser.sleep(1000); - var registerTab = element(by.linkText('Register')); - registerTab.click(); - element(by.model('registerVals.username')).sendKeys('user'); - element(by.model('registerVals.email')).sendKeys('user@example.com'); - element(by.model('registerVals.password')).sendKeys('pass'); - element(by.model('registerVals.confirmPassword')).sendKeys('pass'); - var register = element(by.css('#registrationForm input[value="Register"]')); - register.click(); - browser.sleep(1000); - browser.getCurrentUrl().then(function (url) { - expect(url).not.toMatch(/static\/front/); - }); - }); -}); diff --git a/test/e2e/helper.js b/test/e2e/helper.js new file mode 100644 index 0000000000..dda430085c --- /dev/null +++ b/test/e2e/helper.js @@ -0,0 +1,22 @@ +import fs from 'fs'; +import { resetHabiticaDB } from '../helpers/api-integration/mongo'; + +before(async () => { + await resetHabiticaDB(); +}); + +// based on https://github.com/angular/protractor/issues/114#issuecomment-29046939 +afterEach(async function () { + let lastTest = this.currentTest; + + if (lastTest.state === 'failed') { + let filename = `exception_${lastTest.title}.png`; + let png = await browser.takeScreenshot(); + let buffer = new Buffer(png, 'base64'); + let stream = fs.createWriteStream(filename); + + stream.write(buffer); + stream.end(); + } +}); + diff --git a/test/e2e/protractor.conf.js b/test/e2e/protractor.conf.js new file mode 100644 index 0000000000..4aea36e0dc --- /dev/null +++ b/test/e2e/protractor.conf.js @@ -0,0 +1,30 @@ +'use strict'; + +let chai = require('chai'); +let chaiAsPromised = require('chai-as-promised'); + +require('babel-register'); +require('babel-polyfill'); + +exports.config = { + specs: ['./helper.js', './**/*.test.js'], + baseUrl: 'http://localhost:3003/', + capabilities: { + browserName: 'firefox', + }, + directConnect: true, + seleniumAddress: 'http://localhost:4444/wd/hub', + framework: 'mocha', + mochaOpts: { + reporter: 'spec', + slow: 6000, + timeout: 10000, + compilers: 'js:babel-register', + }, + onPrepare: () => { + browser.ignoreSynchronization = true; + + chai.use(chaiAsPromised); + global.expect = chai.expect; + }, +}; diff --git a/test/e2e/static-pages/front-page.test.js b/test/e2e/static-pages/front-page.test.js new file mode 100644 index 0000000000..9f1475d455 --- /dev/null +++ b/test/e2e/static-pages/front-page.test.js @@ -0,0 +1,64 @@ +import { v4 as generateUniqueId } from 'uuid'; + +describe('Static Front Page', () => { + beforeEach(() => { + browser.get('/'); + browser.sleep(1000); + }); + + it('shows the front page', async () => { + let button = element(by.id('play-btn')); + + await expect(button.getText()).to.eventually.eql('Join for free'); + }); + + it('does not login when using wrong credentials', async () => { + let button = element(by.id('play-btn')); + let randomName = generateUniqueId(); + + button.click(); + browser.sleep(1000); + + element(by.model('loginUsername')).sendKeys(randomName); + element(by.model('loginPassword')).sendKeys('pass'); + + let login = element(by.css('#loginForm input[value="Login"]')); + + login.click(); + browser.sleep(1000); + + let alertDialog = browser.switchTo().alert(); + + await expect(alertDialog.getText()).to.eventually.match(/username or password is incorrect./); + + alertDialog.accept(); + }); + + it('registers a new user', async function () { + this.timeout(30000); // TODO: Speed up registration action. Takes way too long and times out unless you extend the timeout + + let button = element(by.id('play-btn')); + let randomName = generateUniqueId(); + + button.click(); + browser.sleep(1000); + + let registerTab = element(by.linkText('Register')); + registerTab.click(); + element(by.model('registerVals.username')).sendKeys(randomName); + element(by.model('registerVals.email')).sendKeys(`${randomName}@example.com`); + element(by.model('registerVals.password')).sendKeys('pass'); + element(by.model('registerVals.confirmPassword')).sendKeys('pass'); + + let register = element(by.css('#registrationForm input[type="submit"]')); + + register.click(); + browser.sleep(3000); + + let url = await browser.getCurrentUrl(); + + expect(url).to.not.match(/static\/front/); + }); + + it('logs in an existing user'); +});