diff --git a/config/initdb_testing.js b/config/initdb_testing.js index 2dde7384c..a2333bb3a 100644 --- a/config/initdb_testing.js +++ b/config/initdb_testing.js @@ -14,7 +14,11 @@ db.user.update( name: 'admin', img: '/images/blank_user.gif' /* needed for "has default avatar" e2e test */, - pwd: '21232f297a57a5a743894a0e4a801fc3' /* password = "admin" */ + pwd: '21232f297a57a5a743894a0e4a801fc3' /* password = "admin" */, + 'consent.lang': 'en' + }, + $currentDate: { + 'consent.date': true // => mongodb will store a ISODate in consent.date } }, { upsert: true } @@ -28,7 +32,11 @@ db.user.update( handle: 'dummy', name: 'dummy', img: '/images/blank_user.gif', - pwd: '21232f297a57a5a743894a0e4a801fc3' /* password = "admin" */ + pwd: '21232f297a57a5a743894a0e4a801fc3' /* password = "admin" */, + 'consent.lang': 'en' + }, + $currentDate: { + 'consent.date': true // => mongodb will store a ISODate in consent.date } }, { upsert: true } diff --git a/cypress/integration/acceptance.spec.ts b/cypress/integration/acceptance.spec.ts index ed36a5d2e..8d6b2a010 100644 --- a/cypress/integration/acceptance.spec.ts +++ b/cypress/integration/acceptance.spec.ts @@ -1,5 +1,8 @@ /// +// This end-to-end / functional test suite covers the happy path, +// as inspired by https://www.youtube.com/watch?v=aZT8VlTV1YY + context('Openwhyd', () => { it('should allow user to login', () => { cy.visit('/'); @@ -15,7 +18,183 @@ context('Openwhyd', () => { cy.get('form').submit(); cy.get('#loginDiv .username').should('have.text', admin.name); // https://youtu.be/5XQOK0v_YRE?t=1430 }); + }); + + it('should allow a user to add a track', function() { + // should allow user to login + cy.loginAsAdmin(); + cy.visit('/'); + + // should recognize a track when pasting a Youtube URL in the search box + cy.get('#q').type('https://www.youtube.com/watch?v=aZT8VlTV1YY'); + cy.get('#searchResults').contains('Demo'); + + // should lead to a track page when clicking on the Youtube search result + cy.get('#searchResults li a') + .first() + .click(); + cy.url().should('include', '/yt/aZT8VlTV1YY'); + + // should display the name of the track + cy.get('a.btnRepost[href*="Openwhyd Demo (formerly"]').should('exist'); + + // should open a dialog after clicking on the "Add to" button + cy.contains('Add to').click(); //$('a.btnRepost').click(); + cy.get('.dlgPostBox').should('be.visible'); + + // should show a link to the post after adding the track + cy.wait(500); // TODO: we should not have to wait for the "Add" link to be clickable + cy.get('.dlgPostBox span') + .contains('Add') + .click(); + cy.contains('your tracks'); // notification bar with link to "your tracks" + + // should show the post on the user's profile after clicking the link + cy.get('a') + .contains('your tracks') + .click(); + cy.url().should('include', '/u/'); + cy.get('.post a[data-eid="/yt/aZT8VlTV1YY"]').should('be.visible'); + + // should open the playbar after the user clicks on the post + cy.get('.post a[data-eid="/yt/aZT8VlTV1YY"]').click(); + cy.get('#btnPlay').should('be.visible'); + + // should play the track + cy.get('#btnPlay.playing').should('be.visible'); + + // should pause the track when the user clicks on the play/pause button + cy.get('#btnPlay').click(); + cy.get('#btnPlay').should('not.have.class', 'playing'); + }); + + it('should allow a visitor to sign up and follow the onboarding process', function() { + // should not let visitors access admin endpoints + cy.visit('/admin/config/config.json'); + cy.get('pre').should('not.exist'); + + // should have Openwhyd in its title + cy.visit('/'); + cy.title().should('include', 'Openwhyd'); + + // should lead new user to genre selection page + cy.visit('/'); + cy.get('#signup').click(); + cy.fixture('users.js').then(({ testUser }) => { + cy.get('input[name="name"]').type(testUser.username); + cy.get('input[name="email"]').type(testUser.email); + cy.get('input[name="password"]').type(testUser.pwd); + }); + cy.get('input[type="submit"]').click(); + cy.url().should('include', '/pick/genres'); + + // should suggest people to follow after picking genres + cy.get('#genreGallery li').as('genres'); + cy.contains('Indie').click(); + cy.contains('Rock').click(); + cy.contains('Punk').click(); + cy.contains('Next').click(); + cy.url().should('include', '/pick/people'); + + // should suggest to install the extension after picking people + cy.contains('Next').click(); + cy.url().should('include', '/pick/button'); + + // should lead new user to the gdpr consent page, after installing extension + cy.contains('Next').click(); + cy.url().should('include', '/consent'); + + // should lead to the welcome page, after giving consent + cy.get('input[type="checkbox"]') + .first() + .click(); + cy.get('form') + .first() + .submit(); + cy.url().should('include', '/welcome'); + + // should display user name after skipping the welcome tutorial + cy.contains(`Ok, Got it`); + cy.fixture('users.js').then(({ testUser }) => { + cy.get('#loginDiv .username').should('have.text', testUser.username); + }); + + cy.logout(); + }); + + it('should allow user to re-add a track into a playlist', function() { + // requirement: one track should be accessible from the user's stream + cy.fixture('users.js').then(({ dummy }) => { + cy.login(dummy); + }); + cy.postDummyTracks(1); + cy.visit('/'); + + // should display a pop-in dialog when clicking the "Add to" button of that track + cy.scrollTo('bottom'); + cy.get('.post') + .last() // because Cypress is scrolling down for some reason, making the first one unreachable. see https://github.com/cypress-io/cypress/issues/2353 + .contains('Add to') + .click(); + cy.get('.dlgPostBox').should('be.visible'); - cy.wait(3000); // to check that we don't get any runtime javascript error + // should allow to create a new playlist + cy.get('#selPlaylist').should('be.visible'); + cy.wait(1000); // leave some time for onclick handler to be setup => TODO: get rid of this! + cy.get('#selPlaylist').click(); + cy.get('#newPlaylistName').type('test playlist'); + cy.get('input[value="Create"]').click(); + cy.get('#selPlaylist').contains('test playlist'); + + // should show a link to the post after re-adding the track + cy.get('.dlgPostBox span') + .contains('Add') + .click(); + cy.get('.dlgPostBox').should('not.be.visible'); + cy.contains('test playlist'); // notification bar with link + + // should show the post on the user's new playlist after clicking the link + cy.get('a') + .contains('test playlist') + .click(); + cy.url().should('include', '/u/'); + cy.get('.post').should('have.length', 1); + cy.get('.post a[data-eid]').should('be.visible'); + }); + + it('should allow user to manipulate comments', function() { + // requirement: at least one track should be accessible from the user's stream + cy.fixture('users.js').then(({ dummy }) => { + cy.login(dummy); + }); + cy.postDummyTracks(1); + + // comments should be visible from the user's stream + cy.visit('/stream'); + cy.contains('Comment').click(); + cy.contains('You can mention people'); + + // comment should appear after being added + cy.get('textarea').type('hello world\n'); + cy.fixture('users.js').then(({ dummy }) => { + cy.get('.comments').contains(dummy.name); + }); + cy.get('.comments').contains('hello world'); + + // TODO: it(`should change after being updated`, function() { + + // TODO: it(`should disappear after being deleted`, function() { + }); + + it('should allow users to search external tracks', function() { + // should find a youtube track with id that starts with underscore + cy.visit('/'); + cy.get('#q') + .click() + .type('http://www.youtube.com/watch?v=_BU841qpQsI'); + const searchResult = `a[onclick="window.goToPage('/yt/_BU841qpQsI');return false;"]`; + cy.get(searchResult) + .should('be.visible') + .should('have.text', 'Los Van Van - Llegada'); // an empty string would mean that no metadata was fetched, caused to https://github.com/openwhyd/openwhyd/issues/102 }); }); diff --git a/cypress/integration/bookmarklet.spec.ts b/cypress/integration/bookmarklet.spec.ts index 33a5ccec6..a68518128 100644 --- a/cypress/integration/bookmarklet.spec.ts +++ b/cypress/integration/bookmarklet.spec.ts @@ -1,8 +1,10 @@ /// -context('Openwhyd', () => { - before('login', () => { - cy.loginAsAdmin(); +context('Openwhyd bookmarklet', () => { + beforeEach('login', () => { + cy.fixture('users.js').then(({ dummy }) => { + cy.login(dummy); + }); }); it('can add a track from a youtube page', () => { diff --git a/cypress/support/commands.js b/cypress/support/commands.js index 5a9f1ad1f..3251155bc 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -21,7 +21,6 @@ Cypress.Commands.add('logout', () => { Cypress.Commands.add('login', ({ email, md5 }) => { cy.request('GET', `/login?action=login&ajax=1&email=${email}&md5=${md5}`); - cy.request('POST', `/consent`); }); Cypress.Commands.add('loginAsAdmin', () => { diff --git a/cypress/support/index.js b/cypress/support/index.js index 584af04f2..647b4e28d 100644 --- a/cypress/support/index.js +++ b/cypress/support/index.js @@ -18,7 +18,6 @@ require('./commands'); beforeEach(function() { // reset the db before each it() test, across all files no matter what, // as recommended in https://docs.cypress.io/guides/references/best-practices.html#State-reset-should-go-before-each-test - cy.visit('about:blank'); cy.resetDb(); // Safety: this function will work only against the "openwhyd_test" database. // => otherwise, it fail throw and prevent tests from running. diff --git a/test/specs/acceptance.tests.js b/test/specs/acceptance.tests.js deleted file mode 100644 index 9e9bbb5b5..000000000 --- a/test/specs/acceptance.tests.js +++ /dev/null @@ -1,282 +0,0 @@ -var assert = require('assert'); -var { URL_PREFIX, ADMIN_USER, TEST_USER } = require('../fixtures.js'); -const webUI = require('../web-ui.js'); - -const WAIT_DURATION = 10000; - -require('../acceptance-cmds.js'); // also checks that openwhyd's server is tested against the test database -// TODO: make sure that DB was reset before starting Openwhyd's app server - -// reference scenario: https://www.youtube.com/watch?v=aZT8VlTV1YY - -describe('landing page page', function() { - it('should not let visitors access admin endpoints', function() { - browser.url(URL_PREFIX + '/admin/config/config.json'); - assert(!$('pre').isExisting()); - }); - - it('should have Openwhyd in its title', function() { - browser.url(URL_PREFIX); - var title = browser.getTitle(); - assert(/Openwhyd/.test(title)); - }); - - /* - it('should not have changed from previous build', function() { - browser.url(URL_PREFIX); - var results = browser.checkDocument(); // http://webdriver.io/guide/services/visual-regression.html - results.forEach((result) => { - assert(result.isWithinMisMatchTolerance); - }); - }); - */ -}); - -describe('onboarding', function() { - it('should lead new user to genre selection page', function() { - browser.url(URL_PREFIX); - $('#signup').click(); - $('input[name="email"]').waitForDisplayed(); - $('input[name="name"]').setValue(TEST_USER.username); - $('input[name="email"]').setValue(TEST_USER.email); - $('input[name="password"]').setValue(TEST_USER.pwd); - // TODO: takeSnapshot(); - $('input[type="submit"]').click(); - browser.waitUntil( - () => /.*\/pick\/genres/.test(browser.getUrl()), - WAIT_DURATION, - 'expected to be on /pick/genres after 5s' - ); - // TODO: takeSnapshot(); - }); - - it('should suggest people to follow after picking genres', function() { - const genres = $$('#genreGallery li'); - genres.find(genre => /INDIE/.test(genre.getText())).click(); - genres.find(genre => /ROCK/.test(genre.getText())).click(); - genres.find(genre => /PUNK/.test(genre.getText())).click(); - // TODO: takeSnapshot(); - browser.clickOnLinkWithText('Next'); - browser.waitUntil( - () => /.*\/pick\/people/.test(browser.getUrl()), - WAIT_DURATION, - 'expected to be on /pick/people after 5s' - ); - }); - - it('should suggest to install the extension after picking people', function() { - // TODO: takeSnapshot(); - browser.clickOnLinkWithText('Next'); - browser.waitUntil( - () => /.*\/pick\/button/.test(browser.getUrl()), - WAIT_DURATION, - 'expected to be on /pick/button after 5s' - ); - }); - - it('should lead new user to the gdpr consent page, after installing extension', function() { - // TODO: takeSnapshot(); - browser.clickOnLinkWithText('Next'); - browser.waitUntil( - () => /.*\/consent/.test(browser.getUrl()), - WAIT_DURATION, - 'expected to be on /consent after 5s' - ); - }); - - it('should lead to the welcome page, after giving consent', function() { - // TODO: takeSnapshot(); - browser.waitForContent(/consent to let Openwhyd collect/); // text of the consent checkbox - $('input[type="checkbox"]').scrollIntoView(); - $('input[type="checkbox"]').click(); - $('input[type="submit"]').click(); - browser.waitUntil( - () => /.*\/welcome/.test(browser.getUrl()), - WAIT_DURATION, - 'expected to be on /welcome after 5s' - ); - }); - - it('should display user name after skipping the welcome tutorial', function() { - // TODO: takeSnapshot(); - browser.waitForContent(/Ok\, Got it/); - var loggedInUsername = $('#loginDiv .username').getText(); - assert.equal(loggedInUsername, TEST_USER.username); - }); - - webUI.logout(); -}); - -describe('adding a track', function() { - it('should allow user to login', webUI.loginAs(ADMIN_USER)); - - it('should lead user to the gdpr consent page', function() { - browser.waitUntil( - () => /.*\/consent/.test(browser.getUrl()), - WAIT_DURATION, - 'expected to be on /consent after 5s' - ); - // now, let's give consent - browser.waitForContent(/consent to let Openwhyd collect/); // text of the consent checkbox - $('input[type="checkbox"]').scrollIntoView(); - $('input[type="checkbox"]').click(); - $('input[type="submit"]').click(); - }); - - it('should recognize a track when pasting a Youtube URL in the search box', function() { - //browser.url(URL_PREFIX + '/all'); - $('#q').waitForExist(); - $('#q').setValue('https://www.youtube.com/watch?v=aZT8VlTV1YY'); - browser.waitUntil( - () => $$('#searchResults li a').find(a => /Demo/.test(a.getText())), - WAIT_DURATION, - 'expected to find a search result after 5s' - ); - }); - - it('should lead to a track page when clicking on the Youtube search result', function() { - $('#searchResults li a').click(); - browser.waitUntil( - () => /\/yt\/aZT8VlTV1YY/.test(browser.getUrl()), - WAIT_DURATION, - 'expected to be on /yt/aZT8VlTV1YY after 5s' - ); - }); - - it('should display the name of the track', function() { - /* - browser.waitForContent(/Openwhyd Demo/); // name of the track, fetched asynchronously from youtube - browser.waitForContent(/Add to/); - */ - const containsName = () => { - var crit = false; - try { - crit = /Openwhyd Demo \(formerly/.test($('a.btnRepost').getHTML()); - } catch (e) {} - return crit; - }; - browser.waitUntil(containsName, WAIT_DURATION); - assert(true); - }); - - it('should open a dialog after clicking on the "Add to" button', function() { - //$('a.btnRepost').click(); - browser.clickOnLinkWithText('Add to'); - $('.dlgPostBox').waitForDisplayed(); - browser.pause(1000); - assert($('.dlgPostBox').isDisplayedInViewport()); - }); - - it('should show a link to the post after adding the track', function() { - $$('.dlgPostBox span') - .find(a => /Add/.test(a.getText())) - .click(); - browser.waitForLinkWithText('your tracks'); - }); - - it("should show the post on the user's profile after clicking the link", function() { - browser.clickOnLinkWithText('your tracks'); - browser.waitUntil( - () => /\/u\//.test(browser.getUrl()), - WAIT_DURATION, - "expected to be on the user's profile page after 5s" - ); - $('.post a[data-eid="/yt/aZT8VlTV1YY"]').waitForDisplayed(); - }); - - it('should open the playbar after the user clicks on the post', function() { - $('.post a[data-eid="/yt/aZT8VlTV1YY"]').click(); - $('#btnPlay').waitForDisplayed(); - }); - - it('should play the track', function() { - $('#btnPlay.playing').waitForDisplayed(); - }); - - it('should pause the track when the user clicks on the play/pause button', function() { - $('#btnPlay.playing').click(); - assert(!/playing/.test($('#btnPlay').classname)); - }); - - //webUI.logout(); -}); - -describe('re-adding a track in a playlist', function() { - // requirement: one track should be accessible from the user's stream - - // webUI.loginAs(ADMIN_USER); - - it('will display a pop-in dialog when clicking the "Add to" button of that track', function() { - browser.waitForContent(/Add to/); - browser.clickOnLinkWithText('Add to'); - $('.dlgPostBox').waitForDisplayed(); - }); - - it('allows to create a new playlist', function() { - $('#selPlaylist').waitForDisplayed(); - browser.pause(1000); // leave some time for onclick handler to be setup - $('#selPlaylist').click(); - $('#newPlaylistName').waitForDisplayed(); - $('#newPlaylistName').setValue('test playlist'); - $('input[value="Create"]').click(); - browser.waitForContent(/test playlist/, '#selPlaylist'); - }); - - it('should show a link to the post after re-adding the track', function() { - $$('.dlgPostBox span') - .find(a => /Add/.test(a.getText())) - .click(); - browser.waitForLinkWithText('test playlist'); - }); - - it("should show the post on the user's new playlist after clicking the link", function() { - browser.clickOnLinkWithText('test playlist'); - browser.waitUntil( - () => /\/u\//.test(browser.getUrl()), - WAIT_DURATION, - "expected to be on the user's playlist page after 5s" - ); - $('.post a[data-eid="/yt/aZT8VlTV1YY"]').waitForDisplayed(); - }); - - //webUI.logout(); -}); - -describe('track comments', function() { - // requirement: at least one track should be accessible from the user's stream - - // webUI.loginAs(ADMIN_USER); - - it(`can be displayed from the user\'s stream`, function() { - browser.url(URL_PREFIX + '/stream'); - browser.clickOnLinkWithText('Comment'); - browser.waitForContent(/You can mention people/); - }); - - it(`should appear after being added`, function() { - browser.keys('hello world\n'); - browser.waitForContent(new RegExp(ADMIN_USER.name), '.comments'); - browser.waitForContent(/hello world/, '.comments'); - }); - - // TODO: it(`should change after being updated`, function() { - - // TODO: it(`should disappear after being deleted`, function() { -}); - -describe('searching external tracks', function() { - it(`can find a youtube track with id that starts with underscore`, function() { - browser.url(URL_PREFIX); - $('#q').click(); - browser.keys('http://www.youtube.com/watch?v=_BU841qpQsI'); - const searchResult = `a[onclick="window.goToPage('/yt/_BU841qpQsI');return false;"]`; - $(searchResult).waitForDisplayed(); - const trimmed = $(searchResult) - .getText() - .trim(); - //console.log('text: ', trimmed); - assert.notEqual(trimmed, ''); // empty string => no metadata was fetched, caused to https://github.com/openwhyd/openwhyd/issues/102 - }); -}); - -// Webdriver API documentation: http://webdriver.io/api.html