Skip to content
Commits on Source (53)
......@@ -38,3 +38,4 @@ cypress/videos
!/.drone.yml
!/.gitlab
!/.githooks
!/.prettierrc
......@@ -306,6 +306,7 @@ deploy:production:
cleanup:review: # We stop the review site after the e2e tests have run
<<: *cleanup_review
stage: cleanup
when: manual
except:
refs:
- master
......
#!/usr/bin/env bash
# Boilerplate generated with create-bash-script (c) 2019 Nikita Skobov
# Available https://github.com/nikita-skobov/create-bash-script
function usage()
{
local just_help=$1
local missing_required=$2
local invalid_argument=$3
local invalid_option=$4
local help="Usage: e2e.sh [OPTIONS]
Intended to serve as an interaction wrapper around Cypress.
Example: ./e2e.sh -u nemofin -p password123 -v true -url http://www.minds.com/
Options (* indicates it is required):"
local help_options="
*\-p ,\--password \<Parameter>\ The password of the user.
\-url ,\--url \<Parameter>\ The URL of the host e.g. https://www.minds.com/ - defaults to use localhost.
\-u ,\--username \<Parameter>\ The username - defaults to cypress_e2e_test.
\-v ,\---video \<Parameter>\ true if you want video providing.
"
if [ "$missing_required" != "" ]
then
echo "Missing required argument: $missing_required"
fi
if [ "$invalid_option" != "" ] && [ "$invalid_value" = "" ]
then
echo "Invalid option: $invalid_option"
elif [ "$invalid_value" != "" ]
then
echo "Invalid value: $invalid_value for option: --$invalid_option"
fi
echo -e "
"
echo "$help"
echo "$help_options" | column -t -s'\'
return
}
function init_args()
{
REQ_ARGS=( "password" )
# get command line arguments
POSITIONAL=()
# set default arguments
url="http://localhost"
username="minds_cypress_tests"
_video=false
while [[ $# -gt 0 ]]
do
key="$1"
case $key in
-url|--url)
url="$2"
shift 2
;;
-u|--username)
username="$2"
shift 2
;;
-p|--password)
password="$2"
shift 2
;;
-v|---video)
_video="$2"
shift 2
;;
*)
POSITIONAL+=("$1") # saves unknown option in array
shift
;;
esac
done
for i in "${REQ_ARGS[@]}"; do
# $i is the string of the variable name
# ${!i} is a parameter expression to get the value
# of the variable whose name is i.
req_var=${!i}
if [ "$req_var" = "" ]
then
usage "" "--$i"
exit
fi
done
}
init_args $@
# cd to project root.
while [[ $PWD != '/' && ${PWD##*/} != 'front' ]]; do cd ..; done
#run cypress with args.
./node_modules/cypress/bin/cypress open --config baseUrl=$url,video=$_video --env username=$username,password=$password
......@@ -13,6 +13,7 @@ context('Blogs', () => {
beforeEach(()=> {
cy.preserveCookies();
cy.server();
});
it('should not be able to create a new blog if no title or banner are specified', () => {
......@@ -89,7 +90,6 @@ context('Blogs', () => {
cy.get('.m-mature-info a').click();
cy.get('.m-mature-info a span').contains('Mature content');
cy.server();
cy.route("POST", "**/api/v1/blog/new").as("postBlog");
cy.route("GET", "**/api/v1/blog/**").as("getBlog");
......@@ -120,6 +120,111 @@ context('Blogs', () => {
cy.get('m-post-menu button.minds-more').click();
cy.get('m-post-menu ul.minds-dropdown-menu li').contains('Delete').click();
cy.get('m-post-menu m-modal-confirm .mdl-button--colored').click();
});
})
it('should be able to create a new scheduled blog', () => {
// upload avatar first
cy.visit(`/${Cypress.env().username}`);
cy.get('minds-newsfeed-poster').then((poster) => {
if (poster.find('.m-poster-date-selector__input').length > 0) {
cy.get('.m-channel--name .minds-button-edit button:first-child').click();
cy.wait(100);
cy.uploadFile('.minds-avatar input[type=file]', '../fixtures/avatar.jpeg', 'image/jpg');
cy.get('.m-channel--name .minds-button-edit button:last-child').click();
// create blog
cy.visit('/blog/edit/new');
cy.uploadFile('minds-banner #file', '../fixtures/international-space-station-1776401_1920.jpg', 'image/jpg');
cy.get('minds-textarea .m-editor').type('Title');
cy.get('m-inline-editor .medium-editor-element').type('Content\n');
// click on plus button
cy.get('.medium-editor-element > .medium-insert-buttons > button.medium-insert-buttons-show').click();
// click on camera
cy.get('ul.medium-insert-buttons-addons > li > button.medium-insert-action:first-child').contains('photo_camera').click();
// upload the image
cy.uploadFile('.medium-media-file-input', '../fixtures/international-space-station-1776401_1920.jpg', 'image/jpg');
// open license dropdown & select first license
cy.get('.m-license-info select').select('All rights reserved');
// click on hashtags dropdown
cy.get('.m-category-info m-hashtags-selector .m-dropdown--label-container').click();
// select #ART
cy.get('.m-category-info m-dropdown m-form-tags-input > div > span').contains('#art').click();
// type in another hashtag manually
cy.get('.m-category-info m-hashtags-selector m-form-tags-input input').type('hashtag{enter}').click();
// click away
cy.get('.m-category-info m-hashtags-selector .minds-bg-overlay').click();
// select visibility
cy.get('.m-visibility-info select').select('Loggedin');
// open metadata form
cy.get('.m-blog-edit--toggle-wrapper .m-blog-edit--toggle').contains('Metadata').click();
// set url slug
cy.get('.m-blog-edit--field input[name=slug]').type('123');
// set meta title
cy.get('.m-blog-edit--field input[name=custom_meta_title]').type('Test');
// set meta description
cy.get('.m-blog-edit--field textarea[name=custom_meta_description]').type('This is a test blog');
// set meta author
cy.get('.m-blog-edit--field input[name=custom_meta_author]').type('Minds Test');
// set as nsfw
cy.get('.m-mature-info a').click();
cy.get('.m-mature-info a span').contains('Mature content');
// set scheduled date
cy.get('.m-poster-date-selector__input').click();
cy.get('td.c-datepicker__day-body.c-datepicker__day--selected + td').click();
cy.get('a.c-btn.c-btn--flat.js-ok').click();
// get setted date to compare
let scheduledDate;
cy.get('div.m-poster-date-selector__input div.m-tooltip--bubble')
.invoke('text').then((text) => {
scheduledDate = text;
});
cy.wait(1000);
cy.get('.m-button--submit').click({ force: true }); // TODO: Investigate why disabled flag is being detected
cy.location('pathname', { timeout: 30000 })
.should('contains', `/${Cypress.env().username}/blog`);
cy.get('.m-blog--title').contains('Title');
cy.get('.minds-blog-body p').contains('Content');
cy.get('.m-license-info span').contains('all-rights-reserved');
cy.wait(1000);
// compare setted date with time_created
cy.get('div.m-blog-container div.mdl-grid div.minds-body span')
.invoke('text').then((text) => {
const time_created = new Date(text).getTime();
scheduledDate = new Date(scheduledDate).getTime();
expect(scheduledDate).to.equal(time_created);
});
// cleanup
//open dropdown
cy.get('m-post-menu button.minds-more').click();
cy.get('m-post-menu ul.minds-dropdown-menu li').contains('Delete').click();
cy.get('m-post-menu m-modal-confirm .mdl-button--colored').click();
}
});
});
})
/**
* @author Ben Hayward
* @desc E2E testing for Minds Boost Console pages.
*/
import generateRandomId from '../../support/utilities';
context('Boost Console', () => {
const postContent = "Test boost, please reject..." + Math.random().toString(36);
const postContent = "Test boost, please reject..." + generateRandomId();
before(() => {
cy.getCookie('minds_sess')
......@@ -8,27 +14,24 @@ context('Boost Console', () => {
return cy.login(true);
}
});
newBoost(postContent, 100);
});
beforeEach(() => {
cy.server();
cy.route("POST", '**/api/v2/boost/**').as('boostPost');
cy.preserveCookies();
cy.visit('/newsfeed/subscribed');
newBoost(postContent, 100);
cy.visit('/boost/console/newsfeed/history');
});
it('should show a new boost in the console', () => {
cy.visit('/boost/console/newsfeed/history');
cy.get('m-boost-console-card:nth-child(1) div.m-boost-card--manager-item.m-boost-card--state')
.should('not.contain', 'revoked');
cy.get('m-boost-console-card:nth-child(1) .m-boost-card--manager-item--buttons > button')
.click();
cy.get('m-boost-console-card:nth-child(1) .m-mature-message span')
.contains(postContent);
});
it('should allow a revoke a boost', () => {
navToConsole();
cy.get('m-boost-console-card:nth-child(1) div.m-boost-card--manager-item.m-boost-card--state')
.should('not.contain', 'revoked');
......@@ -39,15 +42,42 @@ context('Boost Console', () => {
.contains('revoked');
});
function navToConsole() {
cy.visit('/boost/console/newsfeed/history');
cy.location('pathname')
.should('eq', `/boost/console/newsfeed/history`);
}
it('should load show the user content for newsfeed boosts', () => {
cy.route("GET", "**/feeds/container/*/activities**").as("activities");
cy.contains('Create a Boost')
.click()
.location('pathname')
.should('eq', `/boost/console/newsfeed/create`)
.wait('@activities').then((xhr) => {
expect(xhr.status).to.equal(200);
});
})
it('should load show the user content for sidebar boosts', () => {
cy.route("GET", "**/api/v2/feeds/container/*/all**").as("all");
cy.visit('/boost/console/content/create')
.location('pathname')
.should('eq', `/boost/console/content/create`)
.wait('@all').then((xhr) => {
expect(xhr.status).to.equal(200);
});
})
it('should load show the user content for offers', () => {
cy.route("GET", "**/api/v2/feeds/container/*/activities**").as("all");
cy.visit('/boost/console/offers/create')
.location('pathname')
.should('eq', `/boost/console/offers/create`)
.wait('@all').then((xhr) => {
expect(xhr.status).to.equal(200);
});
})
function newBoost(text, views) {
cy.server();
cy.route("POST", '**/api/v2/boost/**').as('boostPost');
cy.visit('/newsfeed/subscribed');
cy.post(text);
cy.get('#boost-actions')
......@@ -61,7 +91,6 @@ context('Boost Console', () => {
.click();
cy.wait('@boostPost').then((xhr) => {
cy.log(xhr);
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.deep.equal("success");
});
......
context('Boost Creation', () => {
const duplicateError = "There's already an ongoing boost for this entity";
const postContent = "Test boost, please reject..." + Math.random().toString(36).substring(8);
const nonParticipationError = 'Boost target should participate in the Rewards program.'
beforeEach(() => {
cy.server()
.route("GET", '**/api/v2/boost/prepare/**').as('prepare')
.route("POST", '**/api/v2/boost/activity/**').as('activity')
.route("GET", '**/api/v2/blockchain/wallet/balance*').as('balance')
.route("GET", '**/api/v2/search/suggest/**').as('suggest');
cy.getCookie('minds_sess')
.then((sessionCookie) => {
if (sessionCookie === null) {
return cy.login(true);
}
});
cy.visit('/newsfeed/subscriptions')
.location('pathname')
.should('eq', `/newsfeed/subscriptions`);
});
it('should redirect a user to buy tokens when clicked', () => {
openTopModal();
cy.get('m-boost--creator-payment-methods li h5 span')
.contains('Buy Tokens')
.click();
cy.location('pathname', { timeout: 30000 })
.should('eq', `/token`);
});
it('should allow a user to make an offchain boost for 5000 tokens', () => {
cy.post(postContent);
openTopModal();
cy.get('.m-boost--creator-section-amount input')
.type(5000);
cy.get('m-overlay-modal > div.m-overlay-modal > m-boost--creator button')
.click()
.wait('@prepare').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.deep.equal("success");
}).wait('@activity').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.deep.equal("success");
});
cy.get('.m-overlay-modal')
.should('not.be.visible')
});
it('should error if the boost is a duplicate', () => {
openTopModal();
cy.get('.m-boost--creator-section-amount input')
.type(5000);
cy.get('m-overlay-modal > div.m-overlay-modal > m-boost--creator button')
.click()
.wait('@prepare').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.deep.equal("success");
}).wait('@activity').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.deep.equal("error");
});
cy.get('[data-cy=data-minds-boost-creation-error]')
.contains(duplicateError);
});
it('should display an error if boost offer receiver has not signed up for rewards', () => {
openTopModal();
cy.get('h4')
.contains('Offers')
.click();
cy.get('m-boost--creator-p2p-search .m-boost--creator-wide-input input')
.type("minds").wait('@suggest').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.deep.equal("success");
});
cy.get('.m-boost--creator-autocomplete--results .m-boost--creator-autocomplete--result-content')
.first()
.click({force: true});
cy.get('[data-cy=data-minds-boost-creation-error]')
.contains(nonParticipationError);
});
function openTopModal() {
cy.get('#boost-actions')
.first()
.click()
.wait('@balance').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.deep.equal("success");
});
}
})
context('Boost Impressions', () => {
context.skip('Boost Impressions', () => {
before(() => {
cy.getCookie('minds_sess')
......@@ -7,37 +7,43 @@ context('Boost Impressions', () => {
return cy.login(true);
}
});
cy.visit('/newsfeed/subscriptions');
cy.location('pathname')
.should('eq', `/newsfeed/subscriptions`);
});
beforeEach(()=> {
cy.server();
cy.route("POST", "**api/v2/analytics/views/boost/*").as("analytics");
cy.route("GET", "**/api/v2/feeds/subscribed/activities**").as("activities");
cy.preserveCookies();
cy.visit('/newsfeed/subscriptions')
.location('pathname')
.should('eq', `/newsfeed/subscriptions`)
.wait('@activities').then((xhr) => {
expect(xhr.status).to.equal(200);
});
});
afterEach(()=> {
cy.reload();
})
// Cannot test until env behaves consistently.
// See: https://gitlab.com/minds/front/issues/1912
it('should register views on scroll', () => {
//stub endpoint
cy.server();
cy.route("POST", "**/api/v2/analytics/views/activity/*").as("analytics");
//load, scroll, wait to trigger analytics
cy.scrollTo(0, 500);
//smooth scroll
cy.scrollTo('0', '1%', { duration: 100 });
//assert
cy.wait('@analytics').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body).to.deep.equal({ status: 'success' });
});
});
it('should register views on boost rotate', () => {
//stub endpoint
cy.server();
cy.route("POST", "**/api/v2/analytics/views/boost/*").as("analytics");
//rotate forward and wait to trigger analytics
cy.get('m-newsfeed--boost-rotator > div > ul > li:nth-child(3) > i')
cy.get('m-newsfeed--boost-rotator')
.find('chevron_right')
.click();
//assert
......@@ -47,7 +53,8 @@ context('Boost Impressions', () => {
});
//rotate forward and wait to trigger analytics
cy.get('m-newsfeed--boost-rotator > div > ul > li:nth-child(2) > i')
cy.get('m-newsfeed--boost-rotator')
.find('chevron_left')
.click();
//assert
......
context('Channel image upload', () => {
before(() => {
cy.getCookie('minds_sess')
.then((sessionCookie) => {
if (sessionCookie === null) {
return cy.login(true);
}
});
});
beforeEach(()=> {
cy.preserveCookies();
cy.server();
cy.route("POST", "**/api/v1/newsfeed").as("newsfeedPOST");
cy.route("POST", "**/api/v1/media").as("mediaPOST");
});
it('should post an activity with an image attachment', () => {
cy.get('minds-newsfeed-poster').should('be.visible');
cy.get('minds-newsfeed-poster textarea').type('This is a post with an image');
cy.uploadFile('#attachment-input-poster', '../fixtures/international-space-station-1776401_1920.jpg', 'image/jpg');
//upload image
cy.wait('@mediaPOST');
cy.get('.m-posterActionBar__PostButton').click();
//await response for activity
cy.wait('@newsfeedPOST').then((xhr) => {
expect(xhr.status).to.equal(200);
const uploadedImageGuid = xhr.response.body.activity.entity_guid
const activityGuid = xhr.response.body.guid;
cy.get('.minds-list > minds-activity:first-child .message').contains('This is a post with an image');
// assert image
cy.get('.minds-list > minds-activity:first-child .item-image img').should('be.visible');
cy.visit(`/${Cypress.env().username}`);
let mediaHref = `/media/${uploadedImageGuid}`;
cy.get("m-channels--sorted-module[title='Images']")
.find(`a[href='${mediaHref}']`);
cy.get(`[data-minds-activity-guid='${activityGuid}']`)
.find('m-post-menu .minds-more')
.click();
cy.get(`[data-minds-activity-guid='${activityGuid}']`)
.find("li:contains('Delete')")
.click();
cy.get(`[data-minds-activity-guid='${activityGuid}'] m-post-menu m-modal-confirm .mdl-button--colored`).click();
});
});
});
context('Channel', () => {
// skipped until feat release
context.skip('Channel', () => {
before(() => {
cy.getCookie('minds_sess')
.then((sessionCookie) => {
......
context('Comment Permissions', () => {
const postMenu = 'minds-activity:first > div > m-post-menu';
const deletePostOption = "m-post-menu > ul > li:visible:contains('Delete')";
const deletePostButton = ".m-modal-confirm-buttons > button:contains('Delete')";
before(() => {
//make a post new.
cy.getCookie('minds_sess')
.then((sessionCookie) => {
if (sessionCookie === null) {
return cy.login(true);
}
});
cy.visit('/newsfeed/subscriptions');
cy.location('pathname')
.should('eq', `/newsfeed/subscriptions`);
});
afterEach(() => {
//delete the post
cy.get(postMenu).click();
cy.get(deletePostOption).click();
cy.get(deletePostButton).click();
});
beforeEach(()=> {
cy.preserveCookies();
cy.post('test post');
});
it('should disable comments', () => {
cy.server();
cy.route("POST", "**/api/v2/permissions/comments/**").as("commentToggle");
cy.get(postMenu)
.click()
.find("li:visible:contains('Disable Comments')")
.click();
cy.wait('@commentToggle').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.equal("success");
expect(xhr.response.body.allowed).to.equal(false);
});
//close menu
cy.get(postMenu)
.click();
cy.get('minds-activity:first')
.find("i:contains('speaker_notes_off')")
.click();
});
it('should allow comments', () => {
cy.server();
cy.route("POST", "**/api/v2/permissions/comments/**").as("commentToggle");
cy.get(postMenu)
.click()
.find("li:visible:contains('Disable Comments')")
.click();
cy.wait('@commentToggle').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.equal("success");
expect(xhr.response.body.allowed).to.equal(false);
});
//Menu stays open
cy.get("li:visible:contains('Allow Comments')")
.click();
cy.wait('@commentToggle').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.equal("success");
expect(xhr.response.body.allowed).to.equal(true);
});
//close menu
cy.get(postMenu)
.click();
cy.get('minds-activity:first')
.find("i:contains('chat_bubble')");
});
});
\ No newline at end of file
/**
* @author Ben Hayward
* @desc Spec tests for comment threads.
*/
import generateRandomId from '../support/utilities';
context('Messenger', () => {
const targetUser = 'minds';
const messagePassword = 'Passw0rd!';
const messageContent = 'this is a test message!';
const undecryptedMessage = ''
const testUsername = generateRandomId();
const testPassword = generateRandomId()+'X#';
const openMessenger = '.m-messenger--dockpane-tab';
const userSearch = '.m-messenger--userlist-search > input[type=text]';
const userList = (i) => `.m-messenger--userlist-conversations > div:nth-child(${i}) > span.m-conversation-label`;
const passwordInput = (i) => `input[type=password]:nth-child(${i})`;
const submitPassword = 'm-messenger--encryption > div > button';
const messageInput = '.m-messenger--conversation-composer > textarea';
const sendButton = '[data-cy=data-minds-conversation-send]';
const messageBubble = '.m-messenger--conversation-message-bubble';
const settingsButton = '[data-cy=data-minds-conversation-options]';
const closeButton = '[data-cy=data-minds-conversation-close]';
const destroyButton = '[data-cy=data-minds-conversation-destroy]';
before(() => {
cy.newUser(testUsername, testPassword);
});
beforeEach(() => {
cy.preserveCookies();
cy.server();
cy.route('GET', '**/api/v2/messenger/search?*').as('search');
cy.route('GET', '**/api/v2/messenger/conversations/**').as('conversations');
cy.route('POST', '**/api/v2/messenger/conversations/**').as('send');
cy.route('POST', '**/api/v2/messenger/keys/setup**').as('keys')
cy.get(openMessenger)
.click();
});
afterEach(() => {
cy.get(closeButton)
.click({multiple: true});
cy.get(openMessenger)
.click({multiple: true});
});
after(() => {
cy.deleteUser(testUsername, testPassword);
});
it('should allow a new user to set a password and send a message', () => {
cy.get(userSearch)
.type(Cypress.env().username)
.wait('@search').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.equal("success");
});
cy.get(userList(1))
.click();
cy.get(passwordInput(3))
.type(messagePassword)
cy.get(passwordInput(4))
.type(messagePassword)
cy.get(submitPassword)
.click();
cy.get(messageInput)
.type(messageContent);
cy.get(sendButton)
.click()
.wait('@send').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.equal("success");
});
});
it('should allow a user to destroy their chat content', () => {
cy.get(userSearch)
.clear()
.type(Cypress.env().username)
.wait('@search').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.equal("success");
});
cy.get(userList(1))
.click();
cy.get(passwordInput(3))
.type(messagePassword)
cy.get(passwordInput(4))
.type(messagePassword)
cy.get(submitPassword)
.click()
.wait('@keys').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.equal("success");
})
.wait('@conversations').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.equal("success");
});
cy.get(settingsButton)
.click();
cy.get(destroyButton)
.first()
.click();
cy.get(messageBubble)
.should('not.exist');
});
});
......@@ -51,6 +51,98 @@ context('Newsfeed', () => {
cy.get('.minds-list > minds-activity:first-child m-post-menu m-modal-confirm .mdl-button--colored').click();
})
it('should be able to post an activity picking a scheduled date and the edit it', () => {
cy.get('minds-newsfeed-poster').then((poster) => {
if (poster.find('.m-poster-date-selector__input').length > 0) {
cy.get('minds-newsfeed-poster textarea').type('This is a post');
// set scheduled date
cy.get('.m-poster-date-selector__input').click();
cy.get('button.c-datepicker__next').click();
cy.get('tr.c-datepicker__days-row:nth-child(2) td.c-datepicker__day-body:first-child').click();
cy.get('a.c-btn.c-btn--flat.js-ok').click();
// get setted date to compare
let scheduledDate;
cy.get('div.m-poster-date-selector__input div.m-tooltip--bubble')
.invoke('text').then((text) => {
scheduledDate = text;
});
cy.get('.m-posterActionBar__PostButton').click();
cy.wait(100);
// compare setted date with time_created
cy.get('.minds-list > minds-activity:first-child div.mdl-card__supporting-text > div.body > a.permalink > span')
.invoke('text').then((text) => {
const time_created = new Date(text).getTime();
scheduledDate = new Date(scheduledDate).getTime();
expect(scheduledDate).to.equal(time_created);
});
// prepare to listen
cy.server();
cy.route("POST", '**/api/v1/newsfeed/**').as("saveEdited");
// edit the activity
cy.get('.minds-list > minds-activity:first-child m-post-menu > button.minds-more').click();
cy.get('.minds-list > minds-activity:first-child li.mdl-menu__item:first-child').click();
cy.get('.minds-list > minds-activity:first-child .m-poster-date-selector__input').click();
cy.get('button.c-datepicker__next').click();
cy.get('tr.c-datepicker__days-row:nth-child(3) td.c-datepicker__day-body:first-child').click();
cy.get('a.c-btn.c-btn--flat.js-ok').click();
// get setted date to compare
cy.get('.minds-list > minds-activity:first-child div.m-poster-date-selector__input div.m-tooltip--bubble')
.invoke('text').then((text) => {
scheduledDate = text;
});
// compare setted date with time_created
cy.get('.minds-list > minds-activity:first-child div.mdl-card__supporting-text > div.body > a.permalink > span')
.invoke('text').then((text) => {
const time_created = new Date(text).getTime();
scheduledDate = new Date(scheduledDate).getTime();
expect(scheduledDate).to.equal(time_created);
});
// Save
cy.get('.minds-list > minds-activity:first-child button.mdl-button.mdl-button--colored').click();
cy.wait('@saveEdited', { requestTimeout: 5000 }).then((xhr) => {
expect(xhr.status).to.equal(200, '**/api/v1/newsfeed/** request status');
});
// cleanup
cy.get('.minds-list > minds-activity:first-child m-post-menu .minds-more').click();
cy.get('.minds-list > minds-activity:first-child m-post-menu .minds-dropdown-menu .mdl-menu__item:nth-child(4)').click();
cy.get('.minds-list > minds-activity:first-child m-post-menu m-modal-confirm .mdl-button--colored').click();
}
});
})
it('should list scheduled activies', () => {
cy.get('minds-newsfeed-poster').then((poster) => {
if (poster.find('.m-poster-date-selector__input').length > 0) {
cy.server();
cy.route("GET", '**/api/v2/feeds/scheduled/**/count?').as("scheduledCount");
cy.route("GET", '**/api/v2/feeds/scheduled/**/activities?**').as("scheduledActivities");
cy.visit(`/${Cypress.env().username}`);
cy.wait('@scheduledCount', { requestTimeout: 2000 }).then((xhr) => {
expect(xhr.status).to.equal(200, 'feeds/scheduled/**/count request status');
});
cy.get('div.m-mindsListTools__scheduled').click();
cy.wait('@scheduledActivities', { requestTimeout: 2000 }).then((xhr) => {
expect(xhr.status).to.equal(200, 'feeds/scheduled/**/activities request status');
});
}
});
})
it('should post an activity with an image attachment', () => {
cy.get('minds-newsfeed-poster').should('be.visible');
......
......@@ -4,7 +4,10 @@
*/
import generateRandomId from '../support/utilities';
context('Notification', () => {
// Skipped until notifications are fixed on sandboxes
// See https://gitlab.com/minds/engine/issues/732
context.skip('Notification', () => {
//secondary user for testing.
let username = '';
......
import generateRandomId from '../support/utilities';
context('Registration', () => {
const username = generateRandomId();
const password = `${generateRandomId()}0oA!`;
const email = 'test@minds.com';
const noSymbolPass = 'Passw0rd';
const welcomeText = "Welcome to Minds!";
const passwordDontMatch = "Passwords must match.";
const passwordInvalid = " Password must have more than 8 characters. Including uppercase, numbers, special characters (ie. !,#,@), and cannot have spaces. ";
const usernameField = 'minds-form-register #username';
const emailField = 'minds-form-register #email';
const passwordField = 'minds-form-register #password';
const password2Field = 'minds-form-register #password2';
const checkbox = '[data-cy=data-minds-accept-tos-input]';
const submitButton = 'minds-form-register .mdl-card__actions button';
beforeEach(() => {
cy.visit('/login');
cy.location('pathname').should('eq', '/login');
cy.server();
cy.route("POST", "**/api/v1/register").as("register");
});
after(() => {
cy.visit('/login');
cy.location('pathname').should('eq', '/login');
cy.login(false, username, password);
cy.deleteUser(username, password);
})
it('should allow a user to register', () => {
//type values
cy.get(usernameField)
.focus()
.type(username);
cy.get(emailField)
.focus()
.type(email);
cy.get(passwordField)
.focus()
.type(password);
cy.wait(500);
cy.get(password2Field)
.focus()
.type(password);
cy.get(checkbox)
.click({force: true});
//submit
cy.get(submitButton)
.click()
.wait('@register').then((xhr) => {
expect(xhr.status).to.equal(200);
});
//onboarding modal shown
cy.contains(welcomeText);
});
it('should display an error if password is invalid', () => {
cy.get(usernameField)
.focus()
.type(generateRandomId());
cy.get(emailField)
.focus()
.type(email);
cy.get(passwordField)
.focus()
.type(noSymbolPass);
cy.wait(500);
cy.get(password2Field)
.focus()
.type(noSymbolPass);
cy.get(checkbox)
.click({force: true});
//submit
cy.get(submitButton)
.click()
.wait('@register').then((xhr) => {
expect(xhr.status).to.equal(200);
});
cy.scrollTo('top');
cy.contains(passwordInvalid);
});
it('should display an error if passwords do not match', () => {
cy.get(usernameField)
.focus()
.type(generateRandomId());
cy.get(emailField)
.focus()
.type(email);
cy.get('minds-form-register #password')
.focus()
.type(password);
cy.wait(500);
cy.get(password2Field)
.focus()
.type(password + '!');
cy.get(checkbox)
.click({force: true});
//submit
cy.get(submitButton).click();
cy.scrollTo('top');
cy.contains(passwordDontMatch);
});
})
context('Subscription', () => {
const user = 'minds';
const subscribeButton = 'minds-button-subscribe > button';
const messageButton = 'm-messenger--channel-button > button';
const userDropdown = 'minds-button-user-dropdown > button';
beforeEach(()=> {
cy.login(true);
cy.location('pathname', { timeout: 30000 })
.should('eq', `/newsfeed/subscriptions`);
cy.visit(`/${user}`);
})
it('should allow a user to subscribe to another', () => {
subscribe();
});
it('should allow a user to unsubscribe',() => {
unsubscribe();
})
function subscribe() {
cy.get(subscribeButton).click();
cy.get(messageButton).should('be.visible');
}
function unsubscribe() {
cy.get(userDropdown).click();
cy.contains('Unsubscribe').click();
cy.get(subscribeButton).should('be.visible');
}
});
......@@ -18,6 +18,7 @@ import { FeaturesService } from './services/features.service';
import { ThemeService } from './common/services/theme.service';
import { BannedService } from './modules/report/banned/banned.service';
import { DiagnosticsService } from './services/diagnostics.service';
import { RouterHistoryService } from './common/services/router-history.service';
@Component({
moduleId: module.id,
......@@ -52,7 +53,8 @@ export class Minds {
public featuresService: FeaturesService,
public themeService: ThemeService,
private bannedService: BannedService,
private diagnostics: DiagnosticsService
private diagnostics: DiagnosticsService,
private routerHistoryService: RouterHistoryService
) {
this.name = 'Minds';
}
......
......@@ -83,6 +83,7 @@ export class SentryErrorHandler implements ErrorHandler {
handleError(error) {
// const eventId = Sentry.captureException(error.originalError || error);
// Sentry.showReportDialog({ eventId });
console.error(error);
}
}
......
import { NgModule } from '@angular/core';
import { CommonModule as NgCommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { RouterModule, Router } from '@angular/router';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MINDS_PIPES } from './pipes/pipes';
......@@ -102,8 +102,10 @@ import { SettingsService } from '../modules/settings/settings.service';
import { ThemeService } from './services/theme.service';
import { HorizontalInfiniteScroll } from './components/infinite-scroll/horizontal-infinite-scroll.component';
import { ReferralsLinksComponent } from '../modules/wallet/tokens/referrals/links/links.component';
import { PosterDateSelectorComponent } from './components/poster-date-selector/selector.component';
import { ChannelModeSelectorComponent } from './components/channel-mode-selector/channel-mode-selector.component';
import { ShareModalComponent } from '../modules/modals/share/share';
import { RouterHistoryService } from './services/router-history.service';
@NgModule({
imports: [NgCommonModule, RouterModule, FormsModule, ReactiveFormsModule],
......@@ -194,6 +196,8 @@ import { ShareModalComponent } from '../modules/modals/share/share';
SwitchComponent,
FeaturedContentComponent,
PosterDateSelectorComponent,
],
exports: [
MINDS_PIPES,
......@@ -278,6 +282,7 @@ import { ShareModalComponent } from '../modules/modals/share/share';
SwitchComponent,
NSFWSelectorComponent,
FeaturedContentComponent,
PosterDateSelectorComponent,
ChannelModeSelectorComponent,
],
providers: [
......@@ -338,6 +343,11 @@ import { ShareModalComponent } from '../modules/modals/share/share';
new FeaturedContentService(boostedContentService),
deps: [FeedsService],
},
{
provide: RouterHistoryService,
useFactory: router => new RouterHistoryService(router),
deps: [Router],
},
],
entryComponents: [
NotificationsToasterComponent,
......