1
0
mirror of https://github.com/ascribe/onion.git synced 2024-06-16 09:33:16 +02:00

Merge with master

This commit is contained in:
Brett Sun 2016-02-04 14:00:03 +01:00
commit 0a4d19677f
29 changed files with 270 additions and 135 deletions

1
.gitignore vendored
View File

@ -21,6 +21,7 @@ build/*
gemini-coverage/* gemini-coverage/*
gemini-report/* gemini-report/*
test/gemini/screenshots/*
node_modules/* node_modules/*

View File

@ -1,4 +1,4 @@
'use strict' 'use strict';
import React from 'react'; import React from 'react';

View File

@ -156,7 +156,7 @@ let Form = React.createClass({
for(let ref in this.refs) { for(let ref in this.refs) {
if(this.refs[ref] && typeof this.refs[ref].handleSuccess === 'function'){ if(this.refs[ref] && typeof this.refs[ref].handleSuccess === 'function'){
this.refs[ref].handleSuccess(); this.refs[ref].handleSuccess(response);
} }
} }
this.setState({ this.setState({

View File

@ -171,7 +171,7 @@ let LoanForm = React.createClass({
editable={!gallery} editable={!gallery}
overrideForm={!!gallery}> overrideForm={!!gallery}>
<input <input
value={gallery} defaultValue={gallery}
type="text" type="text"
placeholder={getLangText('Gallery/exhibition (optional)')}/> placeholder={getLangText('Gallery/exhibition (optional)')}/>
</Property> </Property>

View File

@ -17,10 +17,7 @@ let InputDate = React.createClass({
}, },
getInitialState() { getInitialState() {
return { return this.getStateFromMoment(this.props.defaultValue);
value: null,
value_moment: null
};
}, },
// InputDate needs to support setting a defaultValue from outside. // InputDate needs to support setting a defaultValue from outside.
@ -28,20 +25,30 @@ let InputDate = React.createClass({
// to the outer Property // to the outer Property
componentWillReceiveProps(nextProps) { componentWillReceiveProps(nextProps) {
if(!this.state.value && !this.state.value_moment && nextProps.defaultValue) { if(!this.state.value && !this.state.value_moment && nextProps.defaultValue) {
this.handleChange(this.props.defaultValue); this.handleChange(nextProps.defaultValue);
} }
}, },
handleChange(date) { getStateFromMoment(date) {
let formattedDate = date.format('YYYY-MM-DD'); const state = {};
this.setState({
value: formattedDate,
value_moment: date
});
if (date) {
state.value = date.format('YYYY-MM-DD');
state.value_moment = date;
}
return state;
},
handleChange(date) {
const newState = this.getStateFromMoment(date);
this.setState(newState);
// Propagate change up by faking event
this.props.onChange({ this.props.onChange({
target: { target: {
value: formattedDate value: newState.value
} }
}); });
}, },

View File

@ -36,7 +36,10 @@ let PieceList = React.createClass({
accordionListItemType: React.PropTypes.func, accordionListItemType: React.PropTypes.func,
bulkModalButtonListType: React.PropTypes.func, bulkModalButtonListType: React.PropTypes.func,
canLoadPieceList: React.PropTypes.bool, canLoadPieceList: React.PropTypes.bool,
redirectTo: React.PropTypes.string, redirectTo: React.PropTypes.shape({
pathname: React.PropTypes.string,
query: React.PropTypes.object
}),
shouldRedirect: React.PropTypes.func, shouldRedirect: React.PropTypes.func,
customSubmitButton: React.PropTypes.element, customSubmitButton: React.PropTypes.element,
customThumbnailPlaceholder: React.PropTypes.func, customThumbnailPlaceholder: React.PropTypes.func,
@ -62,8 +65,11 @@ let PieceList = React.createClass({
] ]
}], }],
orderParams: ['artist_name', 'title'], orderParams: ['artist_name', 'title'],
redirectTo: '/register_piece', redirectTo: {
shouldRedirect: () => true pathname: '/register_piece',
query: null
},
shouldRedirect: (pieceCount) => !pieceCount
}; };
}, },
@ -120,10 +126,16 @@ let PieceList = React.createClass({
const { location: { query }, redirectTo, shouldRedirect } = this.props; const { location: { query }, redirectTo, shouldRedirect } = this.props;
const { unfilteredPieceListCount } = this.state; const { unfilteredPieceListCount } = this.state;
if (redirectTo && unfilteredPieceListCount === 0 && if (redirectTo && redirectTo.pathname &&
(typeof shouldRedirect === 'function' && shouldRedirect(unfilteredPieceListCount))) { (typeof shouldRedirect === 'function' && shouldRedirect(unfilteredPieceListCount))) {
// FIXME: hack to redirect out of the dispatch cycle // FIXME: hack to redirect out of the dispatch cycle
window.setTimeout(() => this.history.push({ query, pathname: redirectTo }), 0); window.setTimeout(() => this.history.push({
// Occasionally, the back end also sets query parameters for Onion.
// We need to consider this by merging all passed query parameters, as we'll
// otherwise end up in a 404 screen
query: Object.assign({}, query, redirectTo.query),
pathname: redirectTo.pathname
}), 0);
} }
}, },

View File

@ -73,7 +73,7 @@ const ROUTES = {
component={EditionContainer} component={EditionContainer}
hideFooter /> hideFooter />
<Route <Route
path='verify' path='coa_verify'
component={CoaVerifyContainer} component={CoaVerifyContainer}
hideFooter /> hideFooter />
<Route <Route
@ -134,7 +134,7 @@ const ROUTES = {
component={EditionContainer} component={EditionContainer}
hideFooter /> hideFooter />
<Route <Route
path='verify' path='coa_verify'
component={CoaVerifyContainer} component={CoaVerifyContainer}
hideFooter /> hideFooter />
<Route <Route

View File

@ -62,13 +62,15 @@ let PrizePieceList = React.createClass({
}, },
render() { render() {
const { is_judge: isJudge, is_jury: isJury, is_admin: isAdmin } = this.state.currentUser;
setDocumentTitle(getLangText('Collection')); setDocumentTitle(getLangText('Collection'));
let orderParams = ['artist_name', 'title']; let orderParams = ['artist_name', 'title'];
if (this.state.currentUser.is_jury) { if (isJury) {
orderParams = ['rating', 'title']; orderParams = ['rating', 'title'];
} }
if (this.state.currentUser.is_judge) { if (isJudge) {
orderParams = ['rating', 'title', 'selected']; orderParams = ['rating', 'title', 'selected'];
} }
return ( return (
@ -80,7 +82,8 @@ let PrizePieceList = React.createClass({
orderBy={this.state.currentUser.is_jury ? 'rating' : null} orderBy={this.state.currentUser.is_jury ? 'rating' : null}
filterParams={[]} filterParams={[]}
customSubmitButton={this.getButtonSubmit()} customSubmitButton={this.getButtonSubmit()}
location={this.props.location}/> location={this.props.location}
shouldRedirect={() => !(isJury || isJudge || isAdmin)} />
</div> </div>
); );
} }

View File

@ -1,4 +1,4 @@
'use strict' 'use strict';
import React from 'react'; import React from 'react';
import Moment from 'moment'; import Moment from 'moment';

View File

@ -1,4 +1,4 @@
'use strict' 'use strict';
import React from 'react'; import React from 'react';

View File

@ -1,4 +1,4 @@
'use strict' 'use strict';
import React from 'react'; import React from 'react';

View File

@ -6,11 +6,14 @@ import PieceList from '../../../../piece_list';
import UserActions from '../../../../../actions/user_actions'; import UserActions from '../../../../../actions/user_actions';
import UserStore from '../../../../../stores/user_store'; import UserStore from '../../../../../stores/user_store';
import WhitelabelActions from '../../../../../actions/whitelabel_actions';
import WhitelabelStore from '../../../../../stores/whitelabel_store';
import CylandAccordionListItem from './cyland_accordion_list/cyland_accordion_list_item'; import CylandAccordionListItem from './cyland_accordion_list/cyland_accordion_list_item';
import { getLangText } from '../../../../../utils/lang_utils'; import { getLangText } from '../../../../../utils/lang_utils';
import { setDocumentTitle } from '../../../../../utils/dom_utils'; import { setDocumentTitle } from '../../../../../utils/dom_utils';
import { mergeOptions } from '../../../../../utils/general_utils';
let CylandPieceList = React.createClass({ let CylandPieceList = React.createClass({
propTypes: { propTypes: {
@ -18,15 +21,22 @@ let CylandPieceList = React.createClass({
}, },
getInitialState() { getInitialState() {
return UserStore.getState(); return mergeOptions(
UserStore.getState(),
WhitelabelStore.getState()
);
}, },
componentDidMount() { componentDidMount() {
UserStore.listen(this.onChange); UserStore.listen(this.onChange);
WhitelabelStore.listen(this.onChange);
WhitelabelActions.fetchWhitelabel();
UserActions.fetchCurrentUser(); UserActions.fetchCurrentUser();
}, },
componentWillUnmount() { componentWillUnmount() {
WhitelabelStore.unlisten(this.onChange);
UserStore.unlisten(this.onChange); UserStore.unlisten(this.onChange);
}, },
@ -34,13 +44,28 @@ let CylandPieceList = React.createClass({
this.setState(state); this.setState(state);
}, },
shouldRedirect(pieceCount) {
const { currentUser: { email: userEmail },
whitelabel: {
user: whitelabelAdminEmail
} } = this.state;
return userEmail !== whitelabelAdminEmail && !pieceCount;
},
render() { render() {
setDocumentTitle(getLangText('Collection')); setDocumentTitle(getLangText('Collection'));
return ( return (
<div> <div>
<PieceList <PieceList
redirectTo="/register_piece?slide_num=0" redirectTo={{
pathname: '/register_piece',
query: {
'slide_num': 0
}
}}
shouldRedirect={this.shouldRedirect}
accordionListItemType={CylandAccordionListItem} accordionListItemType={CylandAccordionListItem}
filterParams={[{ filterParams={[{
label: getLangText('Show works I have'), label: getLangText('Show works I have'),

View File

@ -6,8 +6,12 @@ import PieceList from '../../../../piece_list';
import UserActions from '../../../../../actions/user_actions'; import UserActions from '../../../../../actions/user_actions';
import UserStore from '../../../../../stores/user_store'; import UserStore from '../../../../../stores/user_store';
import NotificationStore from '../../../../../stores/notification_store'; import NotificationStore from '../../../../../stores/notification_store';
import WhitelabelActions from '../../../../../actions/whitelabel_actions';
import WhitelabelStore from '../../../../../stores/whitelabel_store';
import IkonotvAccordionListItem from './ikonotv_accordion_list/ikonotv_accordion_list_item'; import IkonotvAccordionListItem from './ikonotv_accordion_list/ikonotv_accordion_list_item';
import { setDocumentTitle } from '../../../../../utils/dom_utils'; import { setDocumentTitle } from '../../../../../utils/dom_utils';
@ -23,31 +27,41 @@ let IkonotvPieceList = React.createClass({
getInitialState() { getInitialState() {
return mergeOptions( return mergeOptions(
NotificationStore.getState(), NotificationStore.getState(),
UserStore.getState() UserStore.getState(),
WhitelabelStore.getState()
); );
}, },
componentDidMount() { componentDidMount() {
NotificationStore.listen(this.onChange); NotificationStore.listen(this.onChange);
WhitelabelStore.listen(this.onChange);
UserStore.listen(this.onChange); UserStore.listen(this.onChange);
WhitelabelActions.fetchWhitelabel();
UserActions.fetchCurrentUser(); UserActions.fetchCurrentUser();
}, },
componentWillUnmount() { componentWillUnmount() {
NotificationStore.unlisten(this.onChange); NotificationStore.unlisten(this.onChange);
WhitelabelStore.unlisten(this.onChange);
UserStore.unlisten(this.onChange); UserStore.unlisten(this.onChange);
}, },
onChange(state) { onChange(state) {
this.setState(state); this.setState(state);
}, },
redirectIfNoContractNotifications() { shouldRedirect(pieceCount) {
const { contractAgreementListNotifications } = this.state; const { contractAgreementListNotifications,
currentUser: { email: userEmail },
whitelabel: {
user: whitelabelAdminEmail
} } = this.state;
return contractAgreementListNotifications && !contractAgreementListNotifications.length; return contractAgreementListNotifications &&
!contractAgreementListNotifications.length &&
userEmail !== whitelabelAdminEmail &&
!pieceCount;
}, },
render() { render() {
@ -56,8 +70,13 @@ let IkonotvPieceList = React.createClass({
return ( return (
<div> <div>
<PieceList <PieceList
redirectTo="/register_piece?slide_num=0" redirectTo={{
shouldRedirect={this.redirectIfNoContractNotifications} pathname: '/register_piece',
query: {
'slide_num': 0
}
}}
shouldRedirect={this.shouldRedirect}
accordionListItemType={IkonotvAccordionListItem} accordionListItemType={IkonotvAccordionListItem}
filterParams={[{ filterParams={[{
label: getLangText('Show works I have'), label: getLangText('Show works I have'),

View File

@ -59,11 +59,12 @@ let MarketPieceList = React.createClass({
} } = this.state; } } = this.state;
let filterParams = null; let filterParams = null;
let isUserAdmin = null;
let canLoadPieceList = false; let canLoadPieceList = false;
if (userEmail && whitelabelAdminEmail) { if (userEmail && whitelabelAdminEmail) {
canLoadPieceList = true; canLoadPieceList = true;
const isUserAdmin = userEmail === whitelabelAdminEmail; isUserAdmin = userEmail === whitelabelAdminEmail;
filterParams = [{ filterParams = [{
label: getLangText('Show works I can'), label: getLangText('Show works I can'),
@ -78,7 +79,13 @@ let MarketPieceList = React.createClass({
return ( return (
<PieceList <PieceList
canLoadPieceList={canLoadPieceList} canLoadPieceList={canLoadPieceList}
redirectTo="/register_piece?slide_num=0" redirectTo={{
pathname: '/register_piece',
query: {
'slide_num': 0
}
}}
shouldRedirect={(pieceCount) => !isUserAdmin && !pieceCount}
bulkModalButtonListType={MarketAclButtonList} bulkModalButtonListType={MarketAclButtonList}
customThumbnailPlaceholder={customThumbnailPlaceholder} customThumbnailPlaceholder={customThumbnailPlaceholder}
filterParams={filterParams} filterParams={filterParams}

View File

@ -112,12 +112,11 @@ let MarketRegisterPiece = React.createClass({
render() { render() {
const { location } = this.props; const { location } = this.props;
const { const { piece,
piece, step,
step, whitelabel: {
whitelabel: { name: whitelabelName = 'Market'
name: whitelabelName = 'Market' } } = this.state;
} } = this.state;
setDocumentTitle(getLangText('Register a new piece')); setDocumentTitle(getLangText('Register a new piece'));

View File

@ -218,7 +218,7 @@ let ROUTES = {
<Route <Route
path='editions/:editionId' path='editions/:editionId'
component={EditionContainer} component={EditionContainer}
hideFooter /> hideFooter />
<Route <Route
path='coa_verify' path='coa_verify'
component={CoaVerifyContainer} component={CoaVerifyContainer}

View File

@ -1,4 +1,4 @@
'use strict' 'use strict';
// TODO: Create Unittests that test all functions // TODO: Create Unittests that test all functions

View File

@ -1,4 +1,4 @@
'use strict' 'use strict';
import camelCase from 'camelcase'; import camelCase from 'camelcase';
import decamelize from 'decamelize'; import decamelize from 'decamelize';

View File

@ -20,15 +20,16 @@
"vi-clean": "rm -rf ./gemini-report", "vi-clean": "rm -rf ./gemini-report",
"vi-phantom": "phantomjs --webdriver=4444", "vi-phantom": "phantomjs --webdriver=4444",
"vi-update": "gemini update -c ./test/gemini/.gemini.yml", "vi-update": "gemini update -c ./test/gemini/.gemini.yml",
"vi-test": "npm run vi-clean && gemini test -c ./test/gemini/.gemini.yml --reporter html --reporter vflat || true", "vi-test": "npm run vi-test:base || true",
"vi-test:base": "npm run vi-clean && gemini test -c ./test/gemini/.gemini.yml --reporter html --reporter vflat",
"vi-test:all": "npm run vi-test", "vi-test:all": "npm run vi-test",
"vi-test:main": "npm run vi-test -- --browser MainDesktop --browser MainMobile", "vi-test:main": "npm run vi-test:base -- --browser MainDesktop --browser MainMobile || true",
"vi-test:whitelabel": "GEMINI_BROWSERS='CcDesktop, CcMobile, CylandDesktop, CylandMobile, IkonotvDesktop, IkonotvMobile, LumenusDesktop, LumenusMobile, 23viviDesktop, 23viviMobile' npm run vi-test", "vi-test:whitelabel": "GEMINI_BROWSERS='CcDesktop, CcMobile, CylandDesktop, CylandMobile, IkonotvDesktop, IkonotvMobile, LumenusDesktop, LumenusMobile, 23viviDesktop, 23viviMobile' npm run vi-test:base || true",
"vi-test:cc": "npm run vi-test -- --browser CcDesktop --browser CcMobile", "vi-test:cc": "npm run vi-test:base -- --browser CcDesktop --browser CcMobile",
"vi-test:cyland": "npm run vi-test -- --browser CylandDesktop --browser CylandMobile", "vi-test:cyland": "npm run vi-test:base -- --browser CylandDesktop --browser CylandMobile || true",
"vi-test:ikonotv": "npm run vi-test -- --browser IkonotvDesktop --browser IkonotvMobile", "vi-test:ikonotv": "npm run vi-test:base -- --browser IkonotvDesktop --browser IkonotvMobile || true",
"vi-test:lumenus": "npm run vi-test -- --browser LumenusDesktop --browser LumenusMobile", "vi-test:lumenus": "npm run vi-test:base -- --browser LumenusDesktop --browser LumenusMobile || true",
"vi-test:23vivi": "npm run vi-test -- --browser 23viviDesktop --browser 23viviMobile" "vi-test:23vivi": "npm run vi-test:base -- --browser 23viviDesktop --browser 23viviMobile || true"
}, },
"browser": { "browser": {
"fineUploader": "./js/components/ascribe_uploader/vendor/s3.fine-uploader.js" "fineUploader": "./js/components/ascribe_uploader/vendor/s3.fine-uploader.js"

View File

@ -122,9 +122,12 @@ See [the docs](https://github.com/gemini-testing/gemini/blob/master/doc/tests.md
actions](https://github.com/gemini-testing/gemini/blob/master/doc/tests.md#available-actions) for what scripted actions actions](https://github.com/gemini-testing/gemini/blob/master/doc/tests.md#available-actions) for what scripted actions
are available. are available.
Our tests are located in `onion/test/gemini/tests/`. Our tests are located in `onion/test/gemini/tests/`. For now, the tests use the environment defined in
`onion/test/gemini/tests/environment.js` for which user, piece, and edition to run tests against. In the future, it'd be
nice if we had some db scripts that we could use to populate a test db for these regression tests.
**It would be nice if we kept the whitelabels up to date.** **It would also be nice if we kept the whitelabels up to date, so if you add one, please also test (at least) its landing
page.**
Some useful tips: Some useful tips:
* The `find()` method in the callbacks is equivalent to `document.querySelector`; it will only return the first * The `find()` method in the callbacks is equivalent to `document.querySelector`; it will only return the first
@ -187,13 +190,13 @@ current execution state of that breakpoint on the page you're on.
--- ---
To simplify triaging simple issues and test if everything is working, I've added a short test script that can be run To simplify triaging simple issues and test if everything is working, The repo had a short test script that can be run
with PhantomJS to check if it can access the web app and log in. You can edit the `lauch_app_and_login.js` file to with PhantomJS to check if it can access the web app and log in. Find `onion/test/phantomjs/launch_app_and_login.js` in
change the environment to run against. the repo's history, restore it, and then run:
```bash ```bash
# In root /onion folder # In root /onion folder
phantomjs phantomjs/launch_app_and_login.js phantomjs test/phantomjs/launch_app_and_login.js
``` ```

View File

@ -0,0 +1,35 @@
'use strict';
const MAIN_USER = {
email: 'dimi@mailinator.com',
password: '0000000000'
};
const MAIN_PIECE_ID = '12374';
const MAIN_EDITION_ID = '14gw9x3VA9oJaxp4cHaAuK2bvJzvEj4Xvc';
const TIMEOUTS = {
SHORT: 3000,
NORMAL: 5000,
LONG: 10000,
SUPER_DUPER_EXTRA_LONG: 30000
};
console.log('================== Test environment ==================\n');
console.log('Main user:');
console.log(` Email: ${MAIN_USER.email}`);
console.log(` Password: ${MAIN_USER.password}\n`);
console.log(`Main piece: ${MAIN_PIECE_ID}`);
console.log(`Main edition: ${MAIN_EDITION_ID}\n`);
console.log('Timeouts:');
console.log(` Short: ${TIMEOUTS.SHORT}`);
console.log(` Normal: ${TIMEOUTS.NORMAL}\n`);
console.log(` Long: ${TIMEOUTS.LONG}\n`);
console.log(` Super super extra long: ${TIMEOUTS.SUPER_DUPER_EXTRA_LONG}\n`);
console.log('========================================================\n');
module.exports = {
MAIN_USER,
MAIN_PIECE_ID,
MAIN_EDITION_ID,
TIMEOUTS
};

View File

@ -1,6 +1,9 @@
'use strict'; 'use strict';
const gemini = require('gemini'); const gemini = require('gemini');
const environment = require('../environment');
const MAIN_USER = environment.MAIN_USER;
const TIMEOUTS = environment.TIMEOUTS;
/** /**
* Suite of tests against routes that require the user to be authenticated. * Suite of tests against routes that require the user to be authenticated.
@ -14,7 +17,7 @@ gemini.suite('Authenticated', (suite) => {
// also defines a `.before()` // also defines a `.before()`
// FIXME: use a more generic class for this, like just '.app', // FIXME: use a more generic class for this, like just '.app',
// when we can use this file with the whitelabels // when we can use this file with the whitelabels
actions.waitForElementToShow('.ascribe-default-app', 5000); actions.waitForElementToShow('.ascribe-default-app', TIMEOUTS.NORMAL);
}); });
// Suite just to log us in before any other suites run // Suite just to log us in before any other suites run
@ -23,13 +26,13 @@ gemini.suite('Authenticated', (suite) => {
.setUrl('/login') .setUrl('/login')
.ignoreElements('.ascribe-body') .ignoreElements('.ascribe-body')
.capture('logged in', (actions, find) => { .capture('logged in', (actions, find) => {
actions.waitForElementToShow('.ascribe-form', 5000); actions.waitForElementToShow('.ascribe-form', TIMEOUTS.NORMAL);
actions.sendKeys(find('.ascribe-login-wrapper input[name=email]'), 'dimi@mailinator.com'); actions.sendKeys(find('.ascribe-login-wrapper input[name=email]'), MAIN_USER.email);
actions.sendKeys(find('.ascribe-login-wrapper input[name=password]'), '0000000000'); actions.sendKeys(find('.ascribe-login-wrapper input[name=password]'), MAIN_USER.password);
actions.click(find('.ascribe-login-wrapper button[type=submit]')); actions.click(find('.ascribe-login-wrapper button[type=submit]'));
actions.waitForElementToShow('.ascribe-accordion-list:not(.ascribe-loading-position)', 5000); actions.waitForElementToShow('.ascribe-accordion-list:not(.ascribe-loading-position)', TIMEOUTS.NORMAL);
}); });
}); });
@ -40,7 +43,7 @@ gemini.suite('Authenticated', (suite) => {
.ignoreElements('.client--cyland img.img-brand') .ignoreElements('.client--cyland img.img-brand')
.skip(/Mobile/) .skip(/Mobile/)
.before((actions, find) => { .before((actions, find) => {
actions.waitForElementToShow('.ascribe-accordion-list:not(.ascribe-loading-position)', 5000); actions.waitForElementToShow('.ascribe-accordion-list:not(.ascribe-loading-position)', TIMEOUTS.NORMAL);
}) })
.capture('desktop header'); .capture('desktop header');
@ -69,7 +72,7 @@ gemini.suite('Authenticated', (suite) => {
.ignoreElements('.client--cyland img.img-brand') .ignoreElements('.client--cyland img.img-brand')
.skip(/Desktop/) .skip(/Desktop/)
.before((actions, find) => { .before((actions, find) => {
actions.waitForElementToShow('.ascribe-accordion-list:not(.ascribe-loading-position)', 5000); actions.waitForElementToShow('.ascribe-accordion-list:not(.ascribe-loading-position)', TIMEOUTS.NORMAL);
}) })
.capture('mobile header') .capture('mobile header')
.capture('expanded mobile header', (actions, find) => { .capture('expanded mobile header', (actions, find) => {
@ -89,18 +92,18 @@ gemini.suite('Authenticated', (suite) => {
collectionSuite collectionSuite
.setCaptureElements('.ascribe-accordion-list') .setCaptureElements('.ascribe-accordion-list')
.before((actions, find) => { .before((actions, find) => {
actions.waitForElementToShow('.ascribe-accordion-list:not(.ascribe-loading-position)', 5000); actions.waitForElementToShow('.ascribe-accordion-list:not(.ascribe-loading-position)', TIMEOUTS.NORMAL);
// Wait for the images to load // Wait for the images to load
// FIXME: unfortuntately gemini doesn't support ignoring multiple elements from a single selector // FIXME: unfortuntately gemini doesn't support ignoring multiple elements from a single selector
// so we're forced to wait and hope that the images will all finish loading after 5s. // so we're forced to wait and hope that the images will all finish loading after 5s.
// We could also change the thumbnails with JS, but setting up a test user is probably easier. // We could also change the thumbnails with JS, but setting up a test user is probably easier.
actions.wait(5000); actions.wait(TIMEOUTS.NORMAL);
}) })
.capture('collection') .capture('collection')
.capture('expanded edition in collection', (actions, find) => { .capture('expanded edition in collection', (actions, find) => {
actions.click(find('.ascribe-accordion-list-item .ascribe-accordion-list-item-edition-widget')); actions.click(find('.ascribe-accordion-list-item .ascribe-accordion-list-item-edition-widget'));
// Wait for editions to load // Wait for editions to load
actions.waitForElementToShow('.ascribe-accordion-list-item-table', 5000); actions.waitForElementToShow('.ascribe-accordion-list-item-table', TIMEOUTS.LONG);
}) })
gemini.suite('Collection placeholder', (collectionPlaceholderSuite) => { gemini.suite('Collection placeholder', (collectionPlaceholderSuite) => {
@ -108,7 +111,7 @@ gemini.suite('Authenticated', (suite) => {
.setCaptureElements('.ascribe-accordion-list-placeholder') .setCaptureElements('.ascribe-accordion-list-placeholder')
.capture('collection empty search', (actions, find) => { .capture('collection empty search', (actions, find) => {
actions.sendKeys(find('.ascribe-piece-list-toolbar .search-bar input[type="text"]'), 'no search result'); actions.sendKeys(find('.ascribe-piece-list-toolbar .search-bar input[type="text"]'), 'no search result');
actions.waitForElementToShow('.ascribe-accordion-list-placeholder', 5000); actions.waitForElementToShow('.ascribe-accordion-list-placeholder', TIMEOUTS.NORMAL);
}); });
}); });
@ -118,7 +121,7 @@ gemini.suite('Authenticated', (suite) => {
.capture('items selected', (actions, find) => { .capture('items selected', (actions, find) => {
actions.click(find('.ascribe-accordion-list-item .ascribe-accordion-list-item-edition-widget')); actions.click(find('.ascribe-accordion-list-item .ascribe-accordion-list-item-edition-widget'));
// Wait for editions to load // Wait for editions to load
actions.waitForElementToShow('.ascribe-accordion-list-item-table', 5000); actions.waitForElementToShow('.ascribe-accordion-list-item-table', TIMEOUTS.NORMAL);
actions.click('.ascribe-table thead tr input[type="checkbox"]'); actions.click('.ascribe-table thead tr input[type="checkbox"]');
actions.waitForElementToShow('.piece-list-bulk-modal'); actions.waitForElementToShow('.piece-list-bulk-modal');
@ -132,6 +135,7 @@ gemini.suite('Authenticated', (suite) => {
.capture('piece list toolbar') .capture('piece list toolbar')
.capture('piece list toolbar search filled', (actions, find) => { .capture('piece list toolbar search filled', (actions, find) => {
actions.sendKeys(find('.ascribe-piece-list-toolbar .search-bar input[type="text"]'), 'search text'); actions.sendKeys(find('.ascribe-piece-list-toolbar .search-bar input[type="text"]'), 'search text');
actions.waitForElementToShow('.ascribe-piece-list-toolbar .search-bar .icon-ascribe-search', TIMEOUTS.NORMAL);
}) })
gemini.suite('Order widget dropdown', (pieceListToolbarOrderWidgetSuite) => { gemini.suite('Order widget dropdown', (pieceListToolbarOrderWidgetSuite) => {
@ -142,7 +146,7 @@ gemini.suite('Authenticated', (suite) => {
actions.click(find('#ascribe-piece-list-toolbar-order-widget-dropdown')); actions.click(find('#ascribe-piece-list-toolbar-order-widget-dropdown'));
// Wait as the dropdown screenshot still includes the collection in the background // Wait as the dropdown screenshot still includes the collection in the background
actions.waitForElementToShow('.ascribe-accordion-list:not(.ascribe-loading-position)', 5000); actions.waitForElementToShow('.ascribe-accordion-list:not(.ascribe-loading-position)', TIMEOUTS.NORMAL);
}); });
}); });
@ -154,7 +158,7 @@ gemini.suite('Authenticated', (suite) => {
actions.click(find('#ascribe-piece-list-toolbar-filter-widget-dropdown')); actions.click(find('#ascribe-piece-list-toolbar-filter-widget-dropdown'));
// Wait as the dropdown screenshot still includes the collection in the background // Wait as the dropdown screenshot still includes the collection in the background
actions.waitForElementToShow('.ascribe-accordion-list:not(.ascribe-loading-position)', 5000); actions.waitForElementToShow('.ascribe-accordion-list:not(.ascribe-loading-position)', TIMEOUTS.NORMAL);
}); });
}); });
}); });
@ -165,7 +169,7 @@ gemini.suite('Authenticated', (suite) => {
.capture('register work', (actions, find) => { .capture('register work', (actions, find) => {
// The uploader options are only rendered after the user is fetched, so // The uploader options are only rendered after the user is fetched, so
// we have to wait for it here // we have to wait for it here
actions.waitForElementToShow('.file-drag-and-drop-dialog .present-options', 5000); actions.waitForElementToShow('.file-drag-and-drop-dialog .present-options', TIMEOUTS.NORMAL);
}) })
.capture('register work filled', (actions, find) => { .capture('register work filled', (actions, find) => {
actions.sendKeys(find('.ascribe-form input[name="artist_name"]'), 'artist name'); actions.sendKeys(find('.ascribe-form input[name="artist_name"]'), 'artist name');
@ -197,7 +201,7 @@ gemini.suite('Authenticated', (suite) => {
.before((actions, find) => { .before((actions, find) => {
// This will be called before every nested suite begins unless that suite // This will be called before every nested suite begins unless that suite
// also defines a `.before()` // also defines a `.before()`
actions.waitForElementToShow('.settings-container', 5000); actions.waitForElementToShow('.settings-container', TIMEOUTS.NORMAL);
}) })
.capture('user settings'); .capture('user settings');
}); });
@ -208,7 +212,7 @@ gemini.suite('Authenticated', (suite) => {
.setUrl('/logout') .setUrl('/logout')
.ignoreElements('.ascribe-body') .ignoreElements('.ascribe-body')
.capture('logout', (actions, find) => { .capture('logout', (actions, find) => {
actions.waitForElementToShow('.ascribe-login-wrapper', 10000); actions.waitForElementToShow('.ascribe-login-wrapper', TIMEOUTS.LONG);
}); });
}); });
}); });

View File

@ -1,6 +1,9 @@
'use strict'; 'use strict';
const gemini = require('gemini'); const gemini = require('gemini');
const environment = require('../environment');
const MAIN_USER = environment.MAIN_USER;
const TIMEOUTS = environment.TIMEOUTS;
/** /**
* Basic suite of tests against routes that do not require the user to be authenticated. * Basic suite of tests against routes that do not require the user to be authenticated.
@ -13,7 +16,7 @@ gemini.suite('Basic', (suite) => {
// This will be called before every nested suite begins unless that suite // This will be called before every nested suite begins unless that suite
// also defines a `.before()` // also defines a `.before()`
// FIXME: use a more generic class for this, like just '.ascribe-app' // FIXME: use a more generic class for this, like just '.ascribe-app'
actions.waitForElementToShow('.ascribe-default-app', 5000); actions.waitForElementToShow('.ascribe-default-app', TIMEOUTS.NORMAL);
}); });
gemini.suite('Header-desktop', (headerSuite) => { gemini.suite('Header-desktop', (headerSuite) => {
@ -21,7 +24,7 @@ gemini.suite('Basic', (suite) => {
.setCaptureElements('nav.navbar .container') .setCaptureElements('nav.navbar .container')
.skip(/Mobile/) .skip(/Mobile/)
.capture('desktop header', (actions, find) => { .capture('desktop header', (actions, find) => {
actions.waitForElementToShow('nav.navbar .container', 5000); actions.waitForElementToShow('nav.navbar .container', TIMEOUTS.NORMAL);
}) })
.capture('hover on active item', (actions, find) => { .capture('hover on active item', (actions, find) => {
const activeItem = find('nav.navbar li.active'); const activeItem = find('nav.navbar li.active');
@ -39,7 +42,7 @@ gemini.suite('Basic', (suite) => {
.setCaptureElements('nav.navbar .container') .setCaptureElements('nav.navbar .container')
.skip(/Desktop/) .skip(/Desktop/)
.capture('mobile header', (actions, find) => { .capture('mobile header', (actions, find) => {
actions.waitForElementToShow('nav.navbar .container', 5000); actions.waitForElementToShow('nav.navbar .container', TIMEOUTS.NORMAL);
}) })
.capture('expanded mobile header', (actions, find) => { .capture('expanded mobile header', (actions, find) => {
actions.click(find('nav.navbar .navbar-toggle')); actions.click(find('nav.navbar .navbar-toggle'));
@ -55,7 +58,7 @@ gemini.suite('Basic', (suite) => {
footerSuite footerSuite
.setCaptureElements('.ascribe-footer') .setCaptureElements('.ascribe-footer')
.capture('footer', (actions, find) => { .capture('footer', (actions, find) => {
actions.waitForElementToShow('.ascribe-footer', 5000); actions.waitForElementToShow('.ascribe-footer', TIMEOUTS.NORMAL);
}) })
.capture('hover on footer item', (actions, find) => { .capture('hover on footer item', (actions, find) => {
const footerItem = find('.ascribe-footer a:not(.social)'); const footerItem = find('.ascribe-footer a:not(.social)');
@ -70,7 +73,7 @@ gemini.suite('Basic', (suite) => {
gemini.suite('Login', (loginSuite) => { gemini.suite('Login', (loginSuite) => {
loginSuite loginSuite
.capture('login', (actions, find) => { .capture('login', (actions, find) => {
actions.waitForElementToShow('.ascribe-form', 5000); actions.waitForElementToShow('.ascribe-form', TIMEOUTS.NORMAL);
}) })
.capture('hover on login submit', (actions, find) => { .capture('hover on login submit', (actions, find) => {
actions.mouseMove(find('.ascribe-form button[type=submit]')); actions.mouseMove(find('.ascribe-form button[type=submit]'));
@ -84,8 +87,8 @@ gemini.suite('Basic', (suite) => {
// Remove hover from sign up link // Remove hover from sign up link
actions.click(emailInput); actions.click(emailInput);
actions.sendKeys(emailInput, 'dimi@mailinator.com'); actions.sendKeys(emailInput, MAIN_USER.email);
actions.sendKeys(find('.ascribe-form input[name=password]'), '0000000000'); actions.sendKeys(find('.ascribe-form input[name=password]'), MAIN_USER.password);
}) })
.capture('login form filled', (actions, find) => { .capture('login form filled', (actions, find) => {
actions.click(find('.ascribe-form-header')); actions.click(find('.ascribe-form-header'));
@ -96,12 +99,12 @@ gemini.suite('Basic', (suite) => {
signUpSuite signUpSuite
.setUrl('/signup') .setUrl('/signup')
.capture('sign up', (actions, find) => { .capture('sign up', (actions, find) => {
actions.waitForElementToShow('.ascribe-form', 5000); actions.waitForElementToShow('.ascribe-form', TIMEOUTS.NORMAL);
}) })
.capture('sign up form filled with focus', (actions, find) => { .capture('sign up form filled with focus', (actions, find) => {
actions.sendKeys(find('.ascribe-form input[name=email]'), 'dimi@mailinator.com'); actions.sendKeys(find('.ascribe-form input[name=email]'), MAIN_USER.email);
actions.sendKeys(find('.ascribe-form input[name=password]'), '0000000000'); actions.sendKeys(find('.ascribe-form input[name=password]'), MAIN_USER.password);
actions.sendKeys(find('.ascribe-form input[name=password_confirm]'), '0000000000'); actions.sendKeys(find('.ascribe-form input[name=password_confirm]'), MAIN_USER.password);
}) })
.capture('sign up form filled with check', (actions, find) => { .capture('sign up form filled with check', (actions, find) => {
actions.click(find('.ascribe-form input[type="checkbox"] ~ .checkbox')); actions.click(find('.ascribe-form input[type="checkbox"] ~ .checkbox'));
@ -112,10 +115,10 @@ gemini.suite('Basic', (suite) => {
passwordResetSuite passwordResetSuite
.setUrl('/password_reset') .setUrl('/password_reset')
.capture('password reset', (actions, find) => { .capture('password reset', (actions, find) => {
actions.waitForElementToShow('.ascribe-form', 5000); actions.waitForElementToShow('.ascribe-form', TIMEOUTS.NORMAL);
}) })
.capture('password reset form filled with focus', (actions, find) => { .capture('password reset form filled with focus', (actions, find) => {
actions.sendKeys(find('.ascribe-form input[name="email"]'), 'dimi@mailinator.com'); actions.sendKeys(find('.ascribe-form input[name="email"]'), MAIN_USER.email);
}) })
.capture('password reset form filled', (actions, find) => { .capture('password reset form filled', (actions, find) => {
actions.click(find('.ascribe-form-header')); actions.click(find('.ascribe-form-header'));
@ -126,7 +129,7 @@ gemini.suite('Basic', (suite) => {
coaVerifySuite coaVerifySuite
.setUrl('/coa_verify') .setUrl('/coa_verify')
.capture('coa verify', (actions, find) => { .capture('coa verify', (actions, find) => {
actions.waitForElementToShow('.ascribe-form', 5000); actions.waitForElementToShow('.ascribe-form', TIMEOUTS.NORMAL);
}) })
.capture('coa verify form filled with focus', (actions, find) => { .capture('coa verify form filled with focus', (actions, find) => {
actions.sendKeys(find('.ascribe-form input[name="message"]'), 'sample text'); actions.sendKeys(find('.ascribe-form input[name="message"]'), 'sample text');

View File

@ -1,8 +1,12 @@
'use strict'; 'use strict';
const gemini = require('gemini'); const gemini = require('gemini');
const pieceUrl = '/pieces/12374'; const environment = require('../environment');
const editionUrl = '/editions/14gw9x3VA9oJaxp4cHaAuK2bvJzvEj4Xvc'; const MAIN_USER = environment.MAIN_USER;
const TIMEOUTS = environment.TIMEOUTS;
const pieceUrl = `/pieces/${environment.MAIN_PIECE_ID}`;
const editionUrl = `/editions/${environment.MAIN_EDITION_ID}`;
/** /**
* Suite of tests against the piece and edition routes. * Suite of tests against the piece and edition routes.
@ -17,12 +21,12 @@ gemini.suite('Work detail', (suite) => {
// also defines a `.before()` // also defines a `.before()`
// FIXME: use a more generic class for this, like just '.app', // FIXME: use a more generic class for this, like just '.app',
// when we can use this file with the whitelabels // when we can use this file with the whitelabels
actions.waitForElementToShow('.ascribe-default-app', 5000); actions.waitForElementToShow('.ascribe-default-app', TIMEOUTS.NORMAL);
// Wait for the social media buttons to appear // Wait for the social media buttons to appear
actions.waitForElementToShow('.ascribe-social-button-list .fb-share-button iframe', 20000); actions.waitForElementToShow('.ascribe-social-button-list .fb-share-button iframe', TIMEOUTS.SUPER_DUPER_EXTRA_LONG);
actions.waitForElementToShow('.ascribe-social-button-list .twitter-share-button', 20000); actions.waitForElementToShow('.ascribe-social-button-list .twitter-share-button', TIMEOUTS.SUPER_DUPER_EXTRA_LONG);
actions.waitForElementToShow('.ascribe-media-player', 10000); actions.waitForElementToShow('.ascribe-media-player', TIMEOUTS.LONG);
}); });
gemini.suite('Basic piece', (basicPieceSuite) => { gemini.suite('Basic piece', (basicPieceSuite) => {
@ -35,7 +39,7 @@ gemini.suite('Work detail', (suite) => {
setCaptureElements('.shmui-wrap') setCaptureElements('.shmui-wrap')
.capture('shmui', (actions, find) => { .capture('shmui', (actions, find) => {
actions.click(find('.ascribe-media-player')); actions.click(find('.ascribe-media-player'));
actions.waitForElementToShow('.shmui-wrap:not(.loading)', 30000); actions.waitForElementToShow('.shmui-wrap:not(.loading)', TIMEOUTS.SUPER_DUPER_EXTRA_LONG);
// Wait for the transition to end // Wait for the transition to end
actions.wait(1000); actions.wait(1000);
}); });
@ -54,14 +58,14 @@ gemini.suite('Work detail', (suite) => {
.setUrl('/login') .setUrl('/login')
.ignoreElements('.ascribe-body') .ignoreElements('.ascribe-body')
.before((actions, find) => { .before((actions, find) => {
actions.waitForElementToShow('.ascribe-default-app', 5000); actions.waitForElementToShow('.ascribe-default-app', TIMEOUTS.NORMAL);
}) })
.capture('logged in', (actions, find) => { .capture('logged in', (actions, find) => {
actions.sendKeys(find('.ascribe-login-wrapper input[name=email]'), 'dimi@mailinator.com'); actions.sendKeys(find('.ascribe-login-wrapper input[name=email]'), MAIN_USER.email);
actions.sendKeys(find('.ascribe-login-wrapper input[name=password]'), '0000000000'); actions.sendKeys(find('.ascribe-login-wrapper input[name=password]'), MAIN_USER.password);
actions.click(find('.ascribe-login-wrapper button[type=submit]')); actions.click(find('.ascribe-login-wrapper button[type=submit]'));
actions.waitForElementToShow('.ascribe-accordion-list:not(.ascribe-loading-position)', 5000); actions.waitForElementToShow('.ascribe-accordion-list:not(.ascribe-loading-position)', TIMEOUTS.NORMAL);
}); });
}); });
@ -121,10 +125,10 @@ gemini.suite('Work detail', (suite) => {
.setUrl('/logout') .setUrl('/logout')
.ignoreElements('.ascribe-body') .ignoreElements('.ascribe-body')
.before((actions, find) => { .before((actions, find) => {
actions.waitForElementToShow('.ascribe-default-app', 5000); actions.waitForElementToShow('.ascribe-default-app', TIMEOUTS.NORMAL);
}) })
.capture('logout', (actions, find) => { .capture('logout', (actions, find) => {
actions.waitForElementToShow('.ascribe-login-wrapper', 10000); actions.waitForElementToShow('.ascribe-login-wrapper', TIMEOUTS.LONG);
}); });
}); });
}); });

View File

@ -1,6 +1,8 @@
'use strict'; 'use strict';
const gemini = require('gemini'); const gemini = require('gemini');
const environment = require('../../environment');
const TIMEOUTS = environment.TIMEOUTS;
/** /**
* Suite of tests against 23vivi specific routes * Suite of tests against 23vivi specific routes
@ -11,7 +13,7 @@ gemini.suite('23vivi', (suite) => {
.setCaptureElements('.ascribe-wallet-app') .setCaptureElements('.ascribe-wallet-app')
.before((actions, find) => { .before((actions, find) => {
// This will be called before every nested suite begins // This will be called before every nested suite begins
actions.waitForElementToShow('.ascribe-wallet-app', 5000); actions.waitForElementToShow('.ascribe-wallet-app', TIMEOUTS.NORMAL);
}); });
gemini.suite('Landing', (landingSuite) => { gemini.suite('Landing', (landingSuite) => {
@ -19,7 +21,7 @@ gemini.suite('23vivi', (suite) => {
.setUrl('/') .setUrl('/')
.capture('landing', (actions, find) => { .capture('landing', (actions, find) => {
// Wait for the logo to appear // Wait for the logo to appear
actions.waitForElementToShow('.vivi23-landing--header-logo', 10000); actions.waitForElementToShow('.vivi23-landing--header-logo', TIMEOUTS.LONG);
}); });
}); });

View File

@ -1,6 +1,8 @@
'use strict'; 'use strict';
const gemini = require('gemini'); const gemini = require('gemini');
const environment = require('../../environment');
const TIMEOUTS = environment.TIMEOUTS;
/** /**
* Suite of tests against Cyland specific routes * Suite of tests against Cyland specific routes
@ -11,7 +13,7 @@ gemini.suite('Cyland', (suite) => {
.setCaptureElements('.ascribe-wallet-app') .setCaptureElements('.ascribe-wallet-app')
.before((actions, find) => { .before((actions, find) => {
// This will be called before every nested suite begins // This will be called before every nested suite begins
actions.waitForElementToShow('.ascribe-wallet-app', 5000); actions.waitForElementToShow('.ascribe-wallet-app', TIMEOUTS.NORMAL);
}); });
gemini.suite('Landing', (landingSuite) => { gemini.suite('Landing', (landingSuite) => {
@ -20,7 +22,7 @@ gemini.suite('Cyland', (suite) => {
// Ignore Cyland's logo as it's a gif // Ignore Cyland's logo as it's a gif
.ignoreElements('.cyland-landing img') .ignoreElements('.cyland-landing img')
.capture('landing', (actions, find) => { .capture('landing', (actions, find) => {
actions.waitForElementToShow('.cyland-landing img', 10000); actions.waitForElementToShow('.cyland-landing img', TIMEOUTS.LONG);
}); });
}); });

View File

@ -1,6 +1,9 @@
'use strict'; 'use strict';
const gemini = require('gemini'); const gemini = require('gemini');
const environment = require('../../environment');
const MAIN_USER = environment.MAIN_USER;
const TIMEOUTS = environment.TIMEOUTS;
/** /**
* Suite of tests against Cyland specific routes * Suite of tests against Cyland specific routes
@ -11,7 +14,7 @@ gemini.suite('Ikonotv', (suite) => {
.setCaptureElements('.ascribe-wallet-app') .setCaptureElements('.ascribe-wallet-app')
.before((actions, find) => { .before((actions, find) => {
// This will be called before every nested suite begins // This will be called before every nested suite begins
actions.waitForElementToShow('.ascribe-wallet-app', 5000); actions.waitForElementToShow('.ascribe-wallet-app', TIMEOUTS.NORMAL);
}); });
gemini.suite('Landing', (landingSuite) => { gemini.suite('Landing', (landingSuite) => {
@ -29,7 +32,7 @@ gemini.suite('Ikonotv', (suite) => {
}); });
// Wait for logo to appear // Wait for logo to appear
actions.waitForElementToShow('.ikonotv-landing header img', 10000); actions.waitForElementToShow('.ikonotv-landing header img', TIMEOUTS.LONG);
}); });
}); });
@ -43,13 +46,13 @@ gemini.suite('Ikonotv', (suite) => {
// also defines a `.before()` // also defines a `.before()`
// FIXME: use a more generic class for this, like just '.app', // FIXME: use a more generic class for this, like just '.app',
// when we can use this file with the whitelabels // when we can use this file with the whitelabels
actions.waitForElementToShow('.ascribe-wallet-app', 5000); actions.waitForElementToShow('.ascribe-wallet-app', TIMEOUTS.NORMAL);
// Wait for the forms to appear // Wait for the forms to appear
actions.waitForElementToShow('.ascribe-form', 5000); actions.waitForElementToShow('.ascribe-form', TIMEOUTS.NORMAL);
// Just use a dumb wait because the logo is set as a background image // Just use a dumb wait because the logo is set as a background image
actions.wait(3000); actions.wait(TIMEOUTS.SHORT);
}); });
gemini.suite('Login', (loginSuite) => { gemini.suite('Login', (loginSuite) => {
@ -68,8 +71,8 @@ gemini.suite('Ikonotv', (suite) => {
// Remove hover from sign up link // Remove hover from sign up link
actions.click(emailInput); actions.click(emailInput);
actions.sendKeys(emailInput, 'dimi@mailinator.com'); actions.sendKeys(emailInput, MAIN_USER.email);
actions.sendKeys(find('.ascribe-form input[name=password]'), '0000000000'); actions.sendKeys(find('.ascribe-form input[name=password]'), MAIN_USER.password);
}) })
.capture('login form filled', (actions, find) => { .capture('login form filled', (actions, find) => {
actions.click(find('.ascribe-form-header')); actions.click(find('.ascribe-form-header'));
@ -81,9 +84,9 @@ gemini.suite('Ikonotv', (suite) => {
.setUrl('/signup') .setUrl('/signup')
.capture('sign up') .capture('sign up')
.capture('sign up form filled with focus', (actions, find) => { .capture('sign up form filled with focus', (actions, find) => {
actions.sendKeys(find('.ascribe-form input[name=email]'), 'dimi@mailinator.com'); actions.sendKeys(find('.ascribe-form input[name=email]'), MAIN_USER.email);
actions.sendKeys(find('.ascribe-form input[name=password]'), '0000000000'); actions.sendKeys(find('.ascribe-form input[name=password]'), MAIN_USER.password);
actions.sendKeys(find('.ascribe-form input[name=password_confirm]'), '0000000000'); actions.sendKeys(find('.ascribe-form input[name=password_confirm]'), MAIN_USER.password);
}) })
.capture('sign up form filled with check', (actions, find) => { .capture('sign up form filled with check', (actions, find) => {
actions.click(find('.ascribe-form input[type="checkbox"] ~ .checkbox')); actions.click(find('.ascribe-form input[type="checkbox"] ~ .checkbox'));

View File

@ -1,6 +1,8 @@
'use strict'; 'use strict';
const gemini = require('gemini'); const gemini = require('gemini');
const environment = require('../../environment');
const TIMEOUTS = environment.TIMEOUTS;
/** /**
* Suite of tests against lumenus specific routes * Suite of tests against lumenus specific routes
@ -11,7 +13,7 @@ gemini.suite('Lumenus', (suite) => {
.setCaptureElements('.ascribe-wallet-app') .setCaptureElements('.ascribe-wallet-app')
.before((actions, find) => { .before((actions, find) => {
// This will be called before every nested suite begins // This will be called before every nested suite begins
actions.waitForElementToShow('.ascribe-wallet-app', 5000); actions.waitForElementToShow('.ascribe-wallet-app', TIMEOUTS.NORMAL);
}); });
gemini.suite('Landing', (landingSuite) => { gemini.suite('Landing', (landingSuite) => {
@ -19,7 +21,7 @@ gemini.suite('Lumenus', (suite) => {
.setUrl('/') .setUrl('/')
.capture('landing', (actions, find) => { .capture('landing', (actions, find) => {
// Wait for the logo to appear // Wait for the logo to appear
actions.waitForElementToShow('.wp-landing-wrapper img', 10000); actions.waitForElementToShow('.wp-landing-wrapper img', TIMEOUTS.LONG);
}); });
}); });

View File

@ -1,6 +1,9 @@
'use strict'; 'use strict';
const gemini = require('gemini'); const gemini = require('gemini');
const environment = require('../../environment');
const MAIN_USER = environment.MAIN_USER;
const TIMEOUTS = environment.TIMEOUTS;
/** /**
* Basic suite of tests against whitelabel routes that do not require authentication. * Basic suite of tests against whitelabel routes that do not require authentication.
@ -12,7 +15,7 @@ gemini.suite('Whitelabel basic', (suite) => {
// This will be called before every nested suite begins unless that suite // This will be called before every nested suite begins unless that suite
// also defines a `.before()` // also defines a `.before()`
// FIXME: use a more generic class for this, like just '.ascribe-app' // FIXME: use a more generic class for this, like just '.ascribe-app'
actions.waitForElementToShow('.ascribe-wallet-app', 5000); actions.waitForElementToShow('.ascribe-wallet-app', TIMEOUTS.NORMAL);
// Use a dumb wait in case we're still waiting for other assets, like fonts, to load // Use a dumb wait in case we're still waiting for other assets, like fonts, to load
actions.wait(1000); actions.wait(1000);
@ -24,12 +27,12 @@ gemini.suite('Whitelabel basic', (suite) => {
// See Ikono // See Ikono
.skip(/Ikono/) .skip(/Ikono/)
.capture('login', (actions, find) => { .capture('login', (actions, find) => {
actions.waitForElementToShow('.ascribe-form', 5000); actions.waitForElementToShow('.ascribe-form', TIMEOUTS.NORMAL);
// For some reason, the screenshots seem to keep catching the whitelabel login form // For some reason, the screenshots seem to keep catching the whitelabel login form
// on a refresh and without fonts loaded (maybe because they're the first tests run // on a refresh and without fonts loaded (maybe because they're the first tests run
// and the cache isn't hot yet?). // and the cache isn't hot yet?).
// Let's wait a bit and hope they load. // Let's wait a bit and hope they load.
actions.wait(3000); actions.wait(TIMEOUTS.SHORT);
}) })
.capture('hover on login submit', (actions, find) => { .capture('hover on login submit', (actions, find) => {
actions.mouseMove(find('.ascribe-form button[type=submit]')); actions.mouseMove(find('.ascribe-form button[type=submit]'));
@ -43,8 +46,8 @@ gemini.suite('Whitelabel basic', (suite) => {
// Remove hover from sign up link // Remove hover from sign up link
actions.click(emailInput); actions.click(emailInput);
actions.sendKeys(emailInput, 'dimi@mailinator.com'); actions.sendKeys(emailInput, MAIN_USER.email);
actions.sendKeys(find('.ascribe-form input[name=password]'), '0000000000'); actions.sendKeys(find('.ascribe-form input[name=password]'), MAIN_USER.password);
}) })
.capture('login form filled', (actions, find) => { .capture('login form filled', (actions, find) => {
actions.click(find('.ascribe-form-header')); actions.click(find('.ascribe-form-header'));
@ -57,14 +60,14 @@ gemini.suite('Whitelabel basic', (suite) => {
// See Ikono // See Ikono
.skip(/Ikono/) .skip(/Ikono/)
.capture('sign up', (actions, find) => { .capture('sign up', (actions, find) => {
actions.waitForElementToShow('.ascribe-form', 5000); actions.waitForElementToShow('.ascribe-form', TIMEOUTS.NORMAL);
// Wait in case the form reloads due to other assets loading // Wait in case the form reloads due to other assets loading
actions.wait(500); actions.wait(500);
}) })
.capture('sign up form filled with focus', (actions, find) => { .capture('sign up form filled with focus', (actions, find) => {
actions.sendKeys(find('.ascribe-form input[name=email]'), 'dimi@mailinator.com'); actions.sendKeys(find('.ascribe-form input[name=email]'), MAIN_USER.email);
actions.sendKeys(find('.ascribe-form input[name=password]'), '0000000000'); actions.sendKeys(find('.ascribe-form input[name=password]'), MAIN_USER.password);
actions.sendKeys(find('.ascribe-form input[name=password_confirm]'), '0000000000'); actions.sendKeys(find('.ascribe-form input[name=password_confirm]'), MAIN_USER.password);
}) })
.capture('sign up form filled with check', (actions, find) => { .capture('sign up form filled with check', (actions, find) => {
actions.click(find('.ascribe-form input[type="checkbox"] ~ .checkbox')); actions.click(find('.ascribe-form input[type="checkbox"] ~ .checkbox'));
@ -75,12 +78,12 @@ gemini.suite('Whitelabel basic', (suite) => {
passwordResetSuite passwordResetSuite
.setUrl('/password_reset') .setUrl('/password_reset')
.capture('password reset', (actions, find) => { .capture('password reset', (actions, find) => {
actions.waitForElementToShow('.ascribe-form', 5000); actions.waitForElementToShow('.ascribe-form', TIMEOUTS.NORMAL);
// Wait in case the form reloads due to other assets loading // Wait in case the form reloads due to other assets loading
actions.wait(500); actions.wait(500);
}) })
.capture('password reset form filled with focus', (actions, find) => { .capture('password reset form filled with focus', (actions, find) => {
actions.sendKeys(find('.ascribe-form input[name="email"]'), 'dimi@mailinator.com'); actions.sendKeys(find('.ascribe-form input[name="email"]'), MAIN_USER.email);
}) })
.capture('password reset form filled', (actions, find) => { .capture('password reset form filled', (actions, find) => {
actions.click(find('.ascribe-form-header')); actions.click(find('.ascribe-form-header'));
@ -91,7 +94,7 @@ gemini.suite('Whitelabel basic', (suite) => {
coaVerifySuite coaVerifySuite
.setUrl('/coa_verify') .setUrl('/coa_verify')
.capture('coa verify', (actions, find) => { .capture('coa verify', (actions, find) => {
actions.waitForElementToShow('.ascribe-form', 5000); actions.waitForElementToShow('.ascribe-form', TIMEOUTS.NORMAL);
// Wait in case the form reloads due to other assets loading // Wait in case the form reloads due to other assets loading
actions.wait(500); actions.wait(500);
}) })