Skip to content
Commits on Source (10)
......@@ -48,12 +48,14 @@ qa:e2e:
- >
if [ "$CI_BUILD_REF_NAME" == "master" ]; then
export E2E_DOMAIN=https://www.minds.com
export PRODUCTION=true
else
export E2E_DOMAIN=https://$CI_BUILD_REF_SLUG.$KUBE_INGRESS_BASE_DOMAIN
export PRODUCTION=false
fi
- export CYPRESS_baseUrl=$E2E_DOMAIN
- echo "E2E tests for $CI_BUILD_REF_NAME running against $E2E_DOMAIN with user $CYPRESS_username"
- $(npm bin)/cypress run --browser chrome --record --key $CYPRESS_RECORD_ID --config CYPRESS_baseUrl=$E2E_DOMAIN
- $(npm bin)/cypress run --browser chrome --record --key $CYPRESS_RECORD_ID --config CYPRESS_baseUrl=$E2E_DOMAIN,production=$PRODUCTION
artifacts:
when: always
paths:
......
......@@ -12,16 +12,19 @@ function usage()
local help="Usage: e2e.sh [OPTIONS]
Intended to serve as an interaction wrapper around Cypress.
Intended to serve as an interaction wrapper around Cypress. Ensure that you run from within the project.
Example: ./e2e.sh -u nemofin -p password123 -v true -url http://www.minds.com/
Example: ./e2e.sh -u nemofin -p password123 -v true -h 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.
\-h ,\--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.
\-pu ,\--pro_username \<Parameter>\ The pro users username.
\-pp ,\--pro_password \<Parameter>\ The pro users password
\-v ,\---video \<Parameter>\ true if you want video providing.
\-e, \--env \<Parameter>\ add additional env variables e.g. production=true
"
if [ "$missing_required" != "" ]
......@@ -53,14 +56,16 @@ POSITIONAL=()
# set default arguments
url="http://localhost"
username="minds_cypress_tests"
pro_username="minds_pro_cypress_tests"
pro_password=""
env=""
_video=false
while [[ $# -gt 0 ]]
do
key="$1"
case $key in
-url|--url)
-h|--url)
url="$2"
shift 2
;;
......@@ -72,10 +77,22 @@ case $key in
password="$2"
shift 2
;;
-v|---video)
-v|--video)
_video="$2"
shift 2
;;
-pu|--pro-username)
pro_username="$2"
shift 2
;;
-pp|--pro-password)
pro_password="$2"
shift 2
;;
-e|--env)
env=",$2"
shift 2
;;
*)
POSITIONAL+=("$1") # saves unknown option in array
shift
......@@ -103,4 +120,5 @@ init_args $@
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
echo $(npm bin)/cypress open --config baseUrl=$url,video=$_video --env username=$username,password=$password,pro_username=$pro_username,pro_password=$pro_password$env $POSITIONAL
$(npm bin)/cypress open --config baseUrl=$url,video=$_video --env username=$username,password=$password,pro_username=$pro_username,pro_password=$pro_password$env $POSITIONAL
......@@ -2,24 +2,29 @@
context('Blogs', () => {
before(() => {
cy.clearCookies();
cy.getCookie('minds_sess').then(sessionCookie => {
if (sessionCookie === null) {
return cy.login(true);
}
});
cy.getCookie('minds_sess')
.then((sessionCookie) => {
if (sessionCookie === null) {
return cy.login(true);
}
});
});
beforeEach(() => {
cy.preserveCookies();
cy.server();
cy.route('POST', '**/api/v1/blog/new').as('postBlog');
cy.route('POST', '**/api/v1/media**').as('postMedia');
cy.route('GET', '**/api/v1/blog/**').as('getBlog');
cy.route('DELETE', '**/api/v1/blog/**').as('deleteBlog');
cy.visit('/newsfeed/global/top')
.location('pathname')
.should('eq', '/newsfeed/global/top');
});
const uploadAvatar = () => {
cy.visit(`/${Cypress.env().username}`, { timeout: 30000 });
cy.visit(`/${Cypress.env().username}`);
cy.get('.m-channel--name .minds-button-edit button:first-child').click();
cy.uploadFile(
'.minds-avatar input[type=file]',
......@@ -30,7 +35,7 @@ context('Blogs', () => {
};
const createBlogPost = (title, body, nsfw = false, schedule = false) => {
cy.visit('/blog/edit/new', { timeout: 30000 });
cy.visit('/blog/edit/new');
cy.uploadFile(
'.minds-banner input[type=file]',
......@@ -41,12 +46,17 @@ context('Blogs', () => {
cy.get('minds-textarea .m-editor').type(title);
cy.get('m-inline-editor .medium-editor-element').type(body);
// 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();
// // 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');
cy.uploadFile('.medium-media-file-input', '../fixtures/international-space-station-1776401_1920.jpg', 'image/jpg')
.wait('@postMedia').then(xhr => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.equal('success');
});
// open license dropdown & select first license
cy.get('.m-license-info select').select('All rights reserved');
......@@ -108,23 +118,20 @@ context('Blogs', () => {
});
}
cy.get('.m-button--submit', { timeout: 5000 }).click({ force: true }); // TODO: Investigate why disabled flag is being detected
cy.wait('@postBlog').then(xhr => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.equal('success');
cy.wait('@getBlog').then(xhr => {
cy.get('.m-button--submit')
.click({ force: true }) // TODO: Investigate why disabled flag is being detected
.wait('@postBlog').then(xhr => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.equal('success');
})
.wait('@getBlog').then(xhr => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.equal('success');
expect(xhr.response.body).to.have.property('blog');
});
});
cy.location('pathname', { timeout: 30000 }).should(
'contains',
`/${Cypress.env().username}/blog`
);
cy.location('pathname')
.should('contains', `/${Cypress.env().username}/blog`);
cy.get('.m-blog--title').contains(title);
cy.get('.minds-blog-body p').contains(body);
......@@ -191,14 +198,8 @@ context('Blogs', () => {
cy.get('.minds-blog-body p').contains(body);
};
it('should be able to create a new scheduled blog', () => {
uploadAvatar();
createBlogPost('Title', 'Content', true, true);
deleteBlogPost();
});
it('should not be able to create a new blog if no title or banner are specified', () => {
cy.visit('/blog/edit/new', { timeout: 30000 });
cy.visit('/blog/edit/new');
cy.get('.m-button--submit').click();
cy.get('.m-blog--edit--error').contains('Error: You must provide a title');
cy.get('minds-textarea .m-editor').type('Title');
......@@ -215,7 +216,21 @@ context('Blogs', () => {
deleteBlogPost();
});
it('should create an activity for the blog post', () => {
/**
* Skipping until the scheduling options are visible on sandboxes
* currently they are not, missing setting perhaps?
*/
it.skip('should be able to create a new scheduled blog', () => {
uploadAvatar();
createBlogPost('Title', 'Content', true, true);
deleteBlogPost();
});
/**
* Skipping until sandbox behaves consistently as currently when posting,
* on the sandbox it does not update the newsfeed and channel straight away as it does on prod.
*/
it.skip('should create an activity for the blog post', () => {
const identifier = Math.floor(Math.random() * 100);
const title = 'Test Post for Activity ' + identifier;
const body = 'Some content here ' + identifier;
......@@ -244,7 +259,11 @@ context('Blogs', () => {
);
});
it('should update the activity when blog is updated', () => {
/**
* Skipping until sandbox behaves consistently as currently when posting,
* on the sandbox it does not update the newsfeed and channel straight away as it does on prod.
*/
it.skip('should update the activity when blog is updated', () => {
const identifier = Math.floor(Math.random() * 100);
const title = 'Test Post for Activity ' + identifier;
const body = 'Some content here ' + identifier;
......
......@@ -14,13 +14,13 @@ context('Boost Console', () => {
return cy.login(true);
}
});
newBoost(postContent, 100);
newBoost(postContent, 500);
});
beforeEach(() => {
cy.preserveCookies();
cy.server();
cy.route("POST", '**/api/v2/boost/**').as('boostPost');
cy.preserveCookies();
cy.visit('/boost/console/newsfeed/history');
});
......
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.'
/**
* @author Ben Hayward
* @desc E2E testing for Minds Boost Console pages.
*/
import generateRandomId from '../../support/utilities';
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');
context('Boost Console', () => {
const postContent = "Test boost, please reject..." + generateRandomId();
before(() => {
cy.getCookie('minds_sess')
.then((sessionCookie) => {
if (sessionCookie === null) {
return cy.login(true);
}
});
newBoost(postContent, 500);
});
cy.visit('/newsfeed/subscriptions')
.location('pathname')
.should('eq', `/newsfeed/subscriptions`);
beforeEach(() => {
cy.server();
cy.route("POST", '**/api/v2/boost/**').as('boostPost');
cy.preserveCookies();
cy.visit('/boost/console/newsfeed/history');
});
after(() => {
cy.clearCookies();
});
it('should redirect a user to buy tokens when clicked', () => {
openTopModal();
it('should show a new boost in the console', () => {
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-mature-message span')
.contains(postContent);
});
cy.get('m-boost--creator-payment-methods li h5 span')
.contains('Buy Tokens')
it('should allow a revoke a boost', () => {
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.location('pathname', { timeout: 30000 })
.should('eq', `/token`);
cy.get('m-boost-console-card:nth-child(1) div.m-boost-card--manager-item.m-boost-card--state')
.contains('revoked');
});
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')
it('should load show the user content for newsfeed boosts', () => {
cy.route("GET", "**/feeds/container/*/activities**").as("activities");
cy.contains('Create a Boost')
.click()
.wait('@prepare').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.deep.equal("success");
}).wait('@activity').then((xhr) => {
.location('pathname')
.should('eq', `/boost/console/newsfeed/create`)
.wait('@activities').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) => {
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);
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) => {
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);
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 newBoost(text, views) {
cy.server();
cy.route("POST", '**/api/v2/boost/**').as('boostPost');
cy.visit('/newsfeed/subscribed');
cy.post(text);
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");
});
.click();
cy.get('.m-boost--creator-section-amount input')
.type(views);
cy.get('m-overlay-modal > div.m-overlay-modal > m-boost--creator button')
.click();
cy.wait('@boostPost').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')
}
})
// Cannot test until env behaves consistently else,
// the test will frequently error when it cant see a boost.
context.skip('Boost Impressions', () => {
before(() => {
cy.getCookie('minds_sess')
.then((sessionCookie) => {
......@@ -27,9 +28,6 @@ context.skip('Boost Impressions', () => {
cy.reload();
})
// Cannot test until env behaves consistently.
// See: https://gitlab.com/minds/front/issues/1912
it('should register views on scroll', () => {
//smooth scroll
cy.scrollTo('0', '1%', { duration: 100 });
......
context('Channel image upload', () => {
/**
* Skipping until sandbox behaves consistently as currently when posting,
* on the sandboxes it does not show your latest image after you have posted it.
* The below code should be functioning correctly once this is resolved.
*/
context.skip('Channel image upload', () => {
before(() => {
cy.getCookie('minds_sess')
.then((sessionCookie) => {
if (sessionCookie === null) {
return cy.login(true);
return cy.login(true);
}
});
});
cy.visit('/newsfeed/subscriptions')
.location('pathname')
.should('eq', '/newsfeed/subscriptions');
});
beforeEach(()=> {
cy.preserveCookies();
cy.server();
......
context('Comment Permissions', () => {
// skipped until feat release
context.skip('Comment Permissions', () => {
const postMenu = 'minds-activity:first > div > m-post-menu';
const deletePostOption = "m-post-menu > ul > li:visible:contains('Delete')";
......@@ -87,4 +87,4 @@ context('Comment Permissions', () => {
cy.get('minds-activity:first')
.find("i:contains('chat_bubble')");
});
});
\ No newline at end of file
});
......@@ -6,7 +6,9 @@ context('Discovery', () => {
return cy.login(true);
}
});
cy.visit('/newsfeed/global/top');
cy.visit('/newsfeed/global/top')
.location('pathname')
.should('eq', '/newsfeed/global/top');
});
beforeEach(()=> {
......
......@@ -32,17 +32,21 @@ context('Groups', () => {
// click on hashtags dropdown
cy.get('m-hashtags-selector .m-dropdown--label-container').click();
// select #ART
cy.get('m-hashtags-selector m-dropdown m-form-tags-input > div > span').contains('#art').click();
cy.get('m-hashtags-selector m-dropdown m-form-tags-input > div > span').contains('art').click();
// type in another hashtag manually
cy.get('m-hashtags-selector m-form-tags-input input').type('hashtag{enter}').click();
// click away
cy.get('m-hashtags-selector .minds-bg-overlay').click();
cy.get('.m-groups-save > button').contains('Create').click();
cy.route("POST", "**/api/v1/groups/group/*/banner*").as("postBanner");
cy.wait('@postGroup').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.equal('success');
}).wait('@postBanner').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.equal('success');
});
cy.get('.m-groupInfo__name').contains('test');
......
......@@ -52,6 +52,7 @@ context('Messenger', () => {
after(() => {
cy.deleteUser(testUsername, testPassword);
cy.clearCookies({log: true})
});
it('should allow a new user to set a password and send a message', () => {
......
......@@ -14,6 +14,10 @@ context('Newsfeed', () => {
cy.route('POST', '**/api/v1/media').as('mediaPOST');
cy.route('POST', '**/api/v1/newsfeed/**').as('newsfeedEDIT');
cy.route('POST', '**/api/v1/media/**').as('mediaEDIT');
cy.visit('/newsfeed/subscriptions')
.location('pathname')
.should('eq', '/newsfeed/subscriptions');
});
const deleteActivityFromNewsfeed = () => {
......@@ -93,63 +97,6 @@ context('Newsfeed', () => {
cy.location('pathname', { timeout: 20000 }).should('contains', 'media');
};
it('editing media post propagates to activity', () => {
const identifier = Math.floor(Math.random() * 100);
const content = 'This is a post with an image ' + identifier;
newActivityContent(content);
attachImageToActivity();
postActivityAndAwaitResponse(200);
cy.get('.minds-list > minds-activity:first .message').contains(content);
navigateToMediaPageFromNewsfeed();
cy.get('.m-media-content--heading', { timeout: 10000 }).contains(content);
cy.get('.minds-button-edit').click();
const newContent = content + ' changed';
cy.get('minds-textarea .m-editor')
.clear()
.type(newContent);
cy.get('.m-button--submit').click();
cy.wait('@mediaEDIT').then(xhr => {
expect(xhr.status).to.equal(200);
});
navigateToNewsfeed();
cy.get('.minds-list > minds-activity:first .message').contains(newContent);
deleteActivityFromNewsfeed();
});
it('editing a media activity propagates to media post', () => {
const identifier = Math.floor(Math.random() * 100);
const content = 'This is a post with an image ' + identifier;
newActivityContent(content);
attachImageToActivity();
postActivityAndAwaitResponse(200);
cy.get('.minds-list > minds-activity:first .message').contains(content);
cy.get('.minds-list > minds-activity:first .item-image img').should(
'be.visible'
);
const newContent = content + ' changed';
editActivityContent(newContent);
cy.get('.minds-list > minds-activity:first .message').contains(content);
navigateToMediaPageFromNewsfeed();
cy.get('.m-media-content--heading', { timeout: 10000 }).contains(newContent);
navigateToNewsfeed();
deleteActivityFromNewsfeed();
});
it('should post an activity picking hashtags from the dropdown', () => {
newActivityContent('This is a post');
......@@ -199,6 +146,9 @@ context('Newsfeed', () => {
deleteActivityFromNewsfeed();
});
/**
* Commenting out until scheduling is enabled properly on sandboxes
*/
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) {
......@@ -494,4 +444,71 @@ context('Newsfeed', () => {
cy.location('pathname').should('eq', '/groups/create');
});
/**
* Skipping until sandbox behaves consistently as currently when posting,
* on the sandbox it does not update the newsfeed and channel straight away as it does on prod.
*/
it.skip('editing media post propagates to activity', () => {
const identifier = Math.floor(Math.random() * 100);
const content = 'This is a post with an image ' + identifier;
newActivityContent(content);
attachImageToActivity();
postActivityAndAwaitResponse(200);
cy.get('.minds-list > minds-activity:first .message').contains(content);
navigateToMediaPageFromNewsfeed();
cy.get('.m-media-content--heading', { timeout: 10000 }).contains(content);
cy.get('.minds-button-edit').click();
const newContent = content + ' changed';
cy.get('minds-textarea .m-editor')
.clear()
.type(newContent);
cy.get('.m-button--submit').click();
cy.wait('@mediaEDIT').then(xhr => {
expect(xhr.status).to.equal(200);
});
navigateToNewsfeed();
cy.get('.minds-list > minds-activity:first .message').contains(newContent);
deleteActivityFromNewsfeed();
});
/**
* Skipping until sandbox behaves consistently as currently when posting,
* on the sandbox it does not update the newsfeed and channel straight away as it does on prod.
*/
it.skip('editing a media activity propagates to media post', () => {
const identifier = Math.floor(Math.random() * 100);
const content = 'This is a post with an image ' + identifier;
newActivityContent(content);
attachImageToActivity();
postActivityAndAwaitResponse(200);
cy.contains(content);
cy.get('.minds-list > minds-activity:first .item-image img').should(
'be.visible'
);
const newContent = content + ' changed';
editActivityContent(newContent);
cy.contains(content);
navigateToMediaPageFromNewsfeed();
cy.get('.m-media-content--heading', { timeout: 10000 }).contains(newContent);
navigateToNewsfeed();
deleteActivityFromNewsfeed();
});
});
......@@ -4,31 +4,25 @@
*/
import generateRandomId from '../support/utilities';
// Skipped until notifications are fixed on sandboxes
// See https://gitlab.com/minds/engine/issues/732
context.skip('Notification', () => {
//secondary user for testing.
let username = '';
let password = '';
const username = generateRandomId();
const password = generateRandomId()+'X#';
const commentText = 'test comment';
const postText = 'test comment'
const commentText = generateRandomId();
const postText = generateRandomId();
const postCommentButton = 'm-comment__poster > div > div.minds-body > div > div > a.m-post-button';
const commentButton = 'minds-activity > div.tabs > minds-button-comment > a';
const commentInput = 'm-comment__poster minds-textarea > div';
const commentContent ='.m-comment__bubble > p';
const notificationBell = 'm-notifications--topbar-toggle > a > i';
const notification = 'minds-notification';
/**
* Before all, generate username and password, login as the new user and log out.
* Next login to env user, make a post, and log out.
*/
before(() => {
username = generateRandomId();
password = generateRandomId()+'X#';
cy.newUser(username, password);
cy.logout();
......@@ -42,7 +36,9 @@ context.skip('Notification', () => {
*/
after(() => {
cy.clearCookies();
cy.login(true, username, password);
cy.visit(`/${Cypress.env().username}`);
cy.deleteUser(username, password);
});
......@@ -52,6 +48,8 @@ context.skip('Notification', () => {
* then switch users and check for the notification.
*/
beforeEach(() => {
cy.route("GET", '**/api/v1/notifications/all**').as('notifications');
cy.clearCookies();
cy.login(false, username, password);
......@@ -73,13 +71,16 @@ context.skip('Notification', () => {
cy.login();
// Open their notifications
cy.get(notificationBell).click();
cy.get(notificationBell).click()
.wait('@notifications').then((xhr) => {
expect(xhr.status).to.equal(200);
});
/**
* Notifications not working on test env.
* TODO: Check for notification - follow it
* through and check it leads to the post with postText.
*/
cy.get(notification)
.first()
.click();
cy.contains(commentText);
});
})
......@@ -43,28 +43,22 @@ context('Onboarding', () => {
.contains(welcomeText);
});
it('should allow a user to register', () => {
//select topics
cy.get(getTopic(3)).click().should('have.class', 'selected')
cy.get(getTopic(4)).click().should('have.class', 'selected')
cy.get(getTopic(5)).click().should('have.class', 'selected')
it('should allow a user to run through onboarding modals', () => {
//select topics
cy.get(getTopic(3)).click().should('have.class', 'selected')
cy.get(getTopic(4)).click().should('have.class', 'selected')
cy.get(getTopic(5)).click().should('have.class', 'selected')
//click
cy.get(nextButton).click();
});
it('should skip over subscribed channels', () => {
//click
cy.get(nextButton).click();
//TODO: Skipped over for now as subscribed channels is not working on staging environment.
cy.get(nextButton).click();
});
it('should let a user change their display name and description', () => {
cy.get(nameField).clear().type(name);
cy.get(descriptionfield).type(description);
cy.get(nextButton).click();
});
it('should allow a user to select their country', () => {
//set dialcode
cy.get(countryDropdown).click();
cy.get(ukOption).click();
......
......@@ -3,197 +3,191 @@
* @desc E2E testing for Minds Pro's pages.
*/
context('Pro Page', () => {
if (Cypress.env().pro_password) { // required to run tests against pro user only.
const topBar = '.m-proChannel__topbar';
const topBar = '.m-proChannel__topbar';
let categories = [
{ label: 'Technology', tag: '#technology' },
{ label: 'Food', tag: '#food' },
{ label: 'News', tag: '#news' }
];
let categories = [
{ label: 'Technology', tag: '#technology' },
{ label: 'Food', tag: '#food' },
{ label: 'News', tag: '#news' }
];
let footerLinks = [
{ label: 'Minds', link: 'https://www.minds.com/' },
{ label: 'Careers', link: 'https://www.minds.com/careers' },
];
const proButton = 'data-minds-sidebar-admin-pro-button';
let footerLinks = [
{ label: 'Minds', link: 'https://www.minds.com/' },
{ label: 'Careers', link: 'https://www.minds.com/careers' },
];
function resetSettings() {
cy.visit(`/pro/settings`);
function resetSettings() {
cy.visit(`/pro/settings`);
cy.route("POST", "**/api/v2/pro/settings").as("settings");
cy.route("POST", "**/api/v2/pro/settings").as("settings");
cy.get('#title').focus().clear().type('Title');
cy.get('#headline').focus().clear().type('This is a headline');
cy.get('#title').focus().clear().type('Title');
cy.get('#headline').focus().clear().type('This is a headline');
cy.contains('Hashtags')
.click();
cy.contains('Hashtags')
.click();
// remove all hashtags
removeInputs();
// remove all hashtags
removeInputs();
for (let i = 0; i < categories.length; i++) {
let cat = categories[i];
addTag(cat.label, cat.tag, i);
}
cy.contains('Footer')
.click();
for (let i = 0; i < categories.length; i++) {
let cat = categories[i];
addTag(cat.label, cat.tag, i);
}
cy.contains('Footer')
.click();
cy.get('#footer_text')
.clear()
.type('This is the footer text');
cy.get('#footer_text')
.clear()
.type('This is the footer text');
// remove all footer links
removeInputs();
// remove all footer links
removeInputs();
for (let i = 0; i < footerLinks.length; i++) {
let link = footerLinks[i];
addFooterLink(link.label, link.link, i);
}
for (let i = 0; i < footerLinks.length; i++) {
let link = footerLinks[i];
addFooterLink(link.label, link.link, i);
cy.contains('Save')
.click()
.wait('@settings').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body).to.deep.equal({ status: 'success' });
}
);
}
cy.contains('Save')
.click()
.wait('@settings').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body).to.deep.equal({ status: 'success' });
}
);
}
function removeInputs() {
cy.get('.m-draggableList__list .m-proSettings__field .m-proSettings__flexInputs').should('be.visible').within($el => {
for (let i = $el.length - 1; i >= 0; i--) { // flexInput. Start from the last one
let c = $el[i];
for (let j = 0; j < c.children.length; j++) { // inputs and the X button
let cc = c.children[j];
if (cc.nodeName === 'I') { // if it's the X button, click on it
cy.wrap(cc).click();
function removeInputs() {
cy.get('.m-draggableList__list .m-proSettings__field .m-proSettings__flexInputs').should('be.visible').within($el => {
for (let i = $el.length - 1; i >= 0; i--) { // flexInput. Start from the last one
let c = $el[i];
for (let j = 0; j < c.children.length; j++) { // inputs and the X button
let cc = c.children[j];
if (cc.nodeName === 'I') { // if it's the X button, click on it
cy.wrap(cc).click();
}
}
}
}
});
}
});
}
function addTag(label, tag, index) {
cy.contains('+ Add Tag')
.click();
function addTag(label, tag, index) {
cy.contains('+ Add Tag')
.click();
cy.get(`#tag-label-${index}`)
.clear()
.type(label);
cy.get(`#tag-label-${index}`)
.clear()
.type(label);
cy.get(`#tag-tag-${index}`)
.clear()
.type(tag);
}
cy.get(`#tag-tag-${index}`)
.clear()
.type(tag);
}
function addFooterLink(label, link, index) {
cy.contains('Add Link')
.click();
function addFooterLink(label, link, index) {
cy.contains('Add Link')
.click();
cy.get(`#footer_link-title-${index}`)
.clear()
.type(label);
cy.get(`#footer_link-title-${index}`)
.clear()
.type(label);
cy.get(`#footer_link-href-${index}`)
.clear()
.type(link);
}
cy.get(`#footer_link-href-${index}`)
.clear()
.type(link);
}
before(() => {
cy.clearCookies();
cy.getCookie('minds_sess')
.then((sessionCookie) => {
if (sessionCookie === null) {
return cy.login(true);
}
});
before(() => {
cy.login(true, Cypress.env().pro_username, Cypress.env().pro_password);
// after logging in, we need to get to settings and set everything up
resetSettings();
// go to pro page
cy.visit(`/pro/${Cypress.env().pro_username}`);
cy.get(topBar);
});
// after logging in, we need to get to settings and set everything up
resetSettings();
beforeEach(() => {
cy.server();
cy.preserveCookies();
});
// go to pro page
cy.visit(`/pro/${Cypress.env().username}`);
it('should load the feed tab', () => {
cy.route("GET", "**/api/v2/pro/content/*/activities/top**").as("activities");
cy.contains('Feed')
.click()
.wait('@activities').then((xhr) => {
expect(xhr.status).to.equal(200);
});
})
cy.get(topBar);
});
it('should load the videos tab', () => {
cy.route("GET", "**/api/v2/pro/content/*/videos/top**").as("videos");
cy.contains('Videos')
.click()
.wait('@videos').then((xhr) => {
expect(xhr.status).to.equal(200);
});
})
beforeEach(() => {
cy.server();
cy.preserveCookies();
});
it('should load the images tab', () => {
cy.route("GET", "**/api/v2/pro/content/*/images/top**").as("images");
cy.contains('Images')
.click()
.wait('@images').then((xhr) => {
expect(xhr.status).to.equal(200);
});
it('should load the feed tab', () => {
cy.route("GET", "**/api/v2/pro/content/*/activities/top**").as("activities");
cy.contains('Feed')
.click()
.wait('@activities').then((xhr) => {
expect(xhr.status).to.equal(200);
});
})
it('should load the videos tab', () => {
cy.route("GET", "**/api/v2/pro/content/*/videos/top**").as("videos");
cy.contains('Videos')
.click()
.wait('@videos').then((xhr) => {
expect(xhr.status).to.equal(200);
});
})
it('should load the images tab', () => {
cy.route("GET", "**/api/v2/pro/content/*/images/top**").as("images");
cy.contains('Images')
.click()
.wait('@images').then((xhr) => {
expect(xhr.status).to.equal(200);
});
// should have sub-categories
cy.get('m-pro--channel--categories > .m-proChannel__category').each(($el, $index) => {
let c = categories.slice(0);
c.unshift({ label: 'All', tag: '#all' });
expect($el.text()).to.contain(c[$index].label);
});
// should have sub-categories
cy.get('m-pro--channel--categories > .m-proChannel__category').each(($el, $index) => {
let c = categories.slice(0);
c.unshift({ label: 'All', tag: '#all' });
expect($el.text()).to.contain(c[$index].label);
});
cy.get('m-pro--channel .m-overlay-modal').should('not.be.visible');
cy.get('m-pro--channel .m-overlay-modal').should('not.be.visible');
// click on tile
cy.get('.m-proChannelListContent__list li:first-child m-pro--channel-tile').click();
cy.wait(200);
// click on tile
cy.get('.m-proChannelListContent__list li:first-child m-pro--channel-tile').click();
cy.wait(200);
// media modal should appear
cy.get('m-pro--channel .m-overlay-modal').should('be.visible');
// media modal should appear
cy.get('m-pro--channel .m-overlay-modal').should('be.visible');
// close media modal
cy.get('m-pro--channel .m-overlay-modal--close').click();
})
// close media modal
cy.get('m-pro--channel .m-overlay-modal--close').click();
})
it('should load the articles tab', () => {
cy.route("GET", "**/api/v2/pro/content/*/blogs/top**").as("blogs");
cy.contains('Articles')
.click()
.wait('@blogs').then((xhr) => {
expect(xhr.status).to.equal(200);
});
})
it('should load the articles tab', () => {
cy.route("GET", "**/api/v2/pro/content/*/blogs/top**").as("blogs");
cy.contains('Articles')
.click()
.wait('@blogs').then((xhr) => {
expect(xhr.status).to.equal(200);
});
})
it('should load the groups tab', () => {
cy.route("GET", "**/api/v2/pro/content/*/groups/top**").as("groups");
cy.contains('Groups')
.click()
.wait('@groups').then((xhr) => {
expect(xhr.status).to.equal(200);
});
})
it('should load the groups tab', () => {
cy.route("GET", "**/api/v2/pro/content/*/groups/top**").as("groups");
cy.contains('Groups')
.click()
.wait('@groups').then((xhr) => {
expect(xhr.status).to.equal(200);
});
})
it('should have a footer', () => {
// should have a footer text
cy.get('.m-proChannelFooter__text').contains('This is the footer text');
it('should have a footer', () => {
// should have a footer text
cy.get('.m-proChannelFooter__text').contains('This is the footer text');
// should have footer links
cy.get('.m-proChannel__footer .m-proChannelFooter .m-proChannelFooter__link').should('be.visible').each(($el, $index) => {
expect($el.text()).to.contain(footerLinks[$index].label);
expect($el.attr('href')).to.contain(footerLinks[$index].link);
});
})
// should have footer links
cy.get('.m-proChannel__footer .m-proChannelFooter .m-proChannelFooter__link').should('be.visible').each(($el, $index) => {
expect($el.text()).to.contain(footerLinks[$index].label);
expect($el.attr('href')).to.contain(footerLinks[$index].link);
});
})
}
})
......@@ -3,242 +3,237 @@
* @desc E2E testing for Minds Pro's settings.
*/
context('Pro Settings', () => {
if (Cypress.env().pro_password) { // required to run tests against pro user only.
const title = '#title';
const headline = '#headline';
const previewButton = '.m-proSettings__previewBtn';
const activityContainer = 'minds-activity';
const footerText = '#footer_text';
const theme = {
primaryColor: '#primary_color',
plainBackgroundColor: '#plain_background_color',
schemeLight: '#scheme_light',
schemeDark: '#scheme_dark',
aspectRatio: {
169: '#tile_ratio_16\:9', // 16:9
1610: '#tile_ratio_16\:10', // 16:10
43: '#tile_ratio_4\:3', // 4:3
11: '#tile_ratio_1\:1' , // 1:1
},
logoGuid: '#logo_guid',
}
const hashtags = {
labelInput0: '#tag-label-0',
hashtagInput0: '#tag-tag-0',
labelInput1: '#tag-label-1',
hashtagInput1: '#tag-tag-1',
label1: 'label1',
label2: 'label2',
label3: 'label3',
hashtag1: '#hashtag1',
hashtag2: '#hashtag2',
hashtag3: '#hashtag3',
}
const footer = {
hrefInput: `#footer_link-href-0`,
titleInput: `#footer_link-title-0`,
}
const strings = {
title: "Minds Pro E2E",
headline: "This headline is a test",
footer: "This is a footer",
footerTitle: "Minds",
footerHref: 'https://www.minds.com/',
}
before(() => {
cy.login(true, Cypress.env().pro_username, Cypress.env().pro_password);
});
after(() => {
cy.visit("/pro/settings")
.location('pathname')
.should('eq', '/pro/settings');
clearHashtags();
});
beforeEach(()=> {
cy.preserveCookies();
cy.server();
cy.route("POST", "**/api/v2/pro/settings").as("settings");
cy.visit("/pro/settings")
.location('pathname')
.should('eq', '/pro/settings');
});
it('should update the title and headline', () => {
//enter data
cy.get(title)
.focus()
.clear()
.type(strings.title);
cy.get(headline)
.focus()
.clear()
.type(strings.headline);
const title = '#title';
const headline = '#headline';
const previewButton = '.m-proSettings__previewBtn';
const activityContainer = 'minds-activity';
const footerText = '#footer_text';
const theme = {
primaryColor: '#primary_color',
plainBackgroundColor: '#plain_background_color',
schemeLight: '#scheme_light',
schemeDark: '#scheme_dark',
aspectRatio: {
169: '#tile_ratio_16\:9', // 16:9
1610: '#tile_ratio_16\:10', // 16:10
43: '#tile_ratio_4\:3', // 4:3
11: '#tile_ratio_1\:1' , // 1:1
},
logoGuid: '#logo_guid',
}
const hashtags = {
labelInput0: '#tag-label-0',
hashtagInput0: '#tag-tag-0',
labelInput1: '#tag-label-1',
hashtagInput1: '#tag-tag-1',
label1: 'label1',
label2: 'label2',
label3: 'label3',
hashtag1: '#hashtag1',
hashtag2: '#hashtag2',
hashtag3: '#hashtag3',
}
const footer = {
hrefInput: `#footer_link-href-0`,
titleInput: `#footer_link-title-0`,
}
const strings = {
title: "Minds Pro E2E",
headline: "This headline is a test",
footer: "This is a footer",
footerTitle: "Minds",
footerHref: 'https://www.minds.com/',
}
before(() => {
cy.clearCookies();
cy.getCookie('minds_sess')
.then((sessionCookie) => {
if (sessionCookie === null) {
return cy.login(true);
}
});
});
after(() => {
cy.visit("/pro/settings")
.location('pathname')
.should('eq', '/pro/settings');
clearHashtags();
});
beforeEach(()=> {
cy.preserveCookies();
cy.server();
cy.route("POST", "**/api/v2/pro/settings").as("settings");
cy.visit("/pro/settings")
.location('pathname')
.should('eq', '/pro/settings');
});
it('should update the title and headline', () => {
//enter data
cy.get(title)
.focus()
.clear()
.type(strings.title);
cy.get(headline)
.focus()
.clear()
.type(strings.headline);
saveAndPreview();
//check tab title.
cy.title()
.should('eq', strings.title+' - '+strings.headline+" | Minds");
});
// Need to find a way around the color input in Cypress.
it('should allow the user to set a dark theme for posts', () => {
cy.contains('Theme')
.click();
cy.get(theme.schemeDark)
.click();
saveAndPreview();
cy.contains('Feed')
.click();
saveAndPreview();
//check tab title.
cy.title()
.should('eq', strings.title+' - '+strings.headline+" | Minds");
});
cy.get(activityContainer)
.should('have.css', 'background-color')
.and('eq', 'rgb(35, 35, 35)');
});
// Need to find a way around the color input in Cypress.
it('should allow the user to set a light theme for posts', () => {
cy.contains('Theme')
.click();
it('should allow the user to set a dark theme for posts', () => {
cy.contains('Theme')
.click();
cy.get(theme.schemeLight)
.click();
cy.get(theme.schemeDark)
.click();
saveAndPreview();
cy.contains('Feed')
.click();
saveAndPreview();
cy.contains('Feed')
.click();
cy.get(activityContainer)
cy.get(activityContainer)
.should('have.css', 'background-color')
.and('eq', 'rgb(255, 255, 255)');
});
.and('eq', 'rgb(35, 35, 35)');
});
it('should allow the user to set category hashtags', () => {
cy.contains('Hashtags')
.click();
it('should allow the user to set a light theme for posts', () => {
cy.contains('Theme')
.click();
cy.contains('+ Add Tag')
.click();
cy.get(hashtags.labelInput0)
.clear()
.type(hashtags.label1);
cy.get(theme.schemeLight)
.click();
cy.get(hashtags.hashtagInput0)
.clear()
.type(hashtags.hashtag1);
cy.contains('+ Add Tag')
.click();
cy.get(hashtags.labelInput1)
.first()
.clear()
.type(hashtags.label2);
cy.get(hashtags.hashtagInput1)
.first()
.clear()
.type(hashtags.hashtag2);
saveAndPreview();
//check the labels are present and clickable.
cy.contains('label1');
cy.contains('label2');
});
it('should allow the user to set footer', () => {
cy.contains('Footer')
.click();
cy.get(footerText)
.clear()
.type(strings.footer);
cy.contains('Add Link')
.click();
cy.get(footer.hrefInput)
.clear()
.type(strings.footerHref);
saveAndPreview();
cy.contains('Feed')
.click();
cy.get(activityContainer)
.should('have.css', 'background-color')
.and('eq', 'rgb(255, 255, 255)');
});
it('should allow the user to set category hashtags', () => {
cy.contains('Hashtags')
.click();
cy.contains('+ Add Tag')
.click();
cy.get(hashtags.labelInput0)
.clear()
.type(hashtags.label1);
cy.get(hashtags.hashtagInput0)
.clear()
.type(hashtags.hashtag1);
cy.contains('+ Add Tag')
.click();
cy.get(hashtags.labelInput1)
.first()
.clear()
.type(hashtags.label2);
cy.get(hashtags.hashtagInput1)
.first()
.clear()
.type(hashtags.hashtag2);
cy.get(footer.titleInput)
.clear()
.type(strings.footerTitle);
saveAndPreview();
cy.contains(strings.footerTitle)
.should('have.attr', 'href')
.should('contain', strings.footerHref);
});
//save, await response, preview.
function saveAndPreview() {
//save and await response
cy.contains('Save')
.click()
.wait('@settings').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body).to.deep.equal({ status: 'success' });
});
//go to pro page
cy.get(previewButton)
.click();
}
saveAndPreview();
//check the labels are present and clickable.
cy.contains('label1');
cy.contains('label2');
});
it('should allow the user to set footer', () => {
cy.contains('Footer')
.click();
cy.get(footerText)
.clear()
.type(strings.footer);
cy.contains('Add Link')
.click();
cy.get(footer.hrefInput)
.clear()
.type(strings.footerHref);
cy.get(footer.titleInput)
.clear()
.type(strings.footerTitle);
function clearHashtags() {
cy.contains('Hashtags')
.click();
cy.contains('+ Add Tag')
.click();
cy.contains('clear')
.click({multiple: true});
saveAndPreview();
}
//
// it.only('should update the theme', () => {
// // nav to theme tab
// cy.contains('Theme')
// .click();
cy.contains(strings.footerTitle)
.should('have.attr', 'href')
.should('contain', strings.footerHref);
});
//save, await response, preview.
function saveAndPreview() {
//save and await response
cy.contains('Save')
.click()
.wait('@settings').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body).to.deep.equal({ status: 'success' });
});
//go to pro page
cy.get(previewButton)
.click();
}
function clearHashtags() {
cy.contains('Hashtags')
.click();
// cy.get(theme.plainBackgroundColor).then(elem => {
// elem.val('#00dd00');
// //save and await response
// cy.contains('Save')
// .click()
// .wait('@settings').then((xhr) => {
// expect(xhr.status).to.equal(200);
// expect(xhr.response.body).to.deep.equal({ status: 'success' });
// });
// //go to pro page
// cy.get(previewButton)
// .click();
// });
// })
cy.contains('+ Add Tag')
.click();
cy.contains('clear')
.click({multiple: true});
saveAndPreview();
}
//
// it.only('should update the theme', () => {
// // nav to theme tab
// cy.contains('Theme')
// .click();
// cy.get(theme.plainBackgroundColor).then(elem => {
// elem.val('#00dd00');
// //save and await response
// cy.contains('Save')
// .click()
// .wait('@settings').then((xhr) => {
// expect(xhr.status).to.equal(200);
// expect(xhr.response.body).to.deep.equal({ status: 'success' });
// });
// //go to pro page
// cy.get(previewButton)
// .click();
// });
// })
}
})
......@@ -19,6 +19,7 @@ context('Registration', () => {
const submitButton = 'minds-form-register .mdl-card__actions button';
beforeEach(() => {
cy.clearCookies();
cy.visit('/login');
cy.location('pathname').should('eq', '/login');
cy.server();
......@@ -30,6 +31,7 @@ context('Registration', () => {
cy.location('pathname').should('eq', '/login');
cy.login(false, username, password);
cy.deleteUser(username, password);
cy.clearCookies();
})
it('should allow a user to register', () => {
......
......@@ -14,11 +14,11 @@ context('Remind', () => {
beforeEach(() => {
cy.preserveCookies();
cy.server();
cy.route("POST", "**/api/v2/newsfeed/remind/*").as("postRemind");
});
it('should allow a user to remind their post', () => {
cy.server();
cy.route("POST", "**/api/v2/newsfeed/remind/*").as("postRemind");
//post
cy.post("test!!");
......@@ -29,13 +29,14 @@ context('Remind', () => {
//fill out text box in modal
cy.get('.m-modal-remind-composer textarea')
.focus()
.clear()
.type(remindText);
//post remind.
cy.get('.m-modal-remind-composer-send i')
.click();
cy.wait('@postRemind').then((xhr) => {
.click()
.wait('@postRemind').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.equal("success");
});
......
......@@ -5,14 +5,25 @@ context('Subscription', () => {
const messageButton = 'm-messenger--channel-button > button';
const userDropdown = 'minds-button-user-dropdown > button';
beforeEach(()=> {
cy.login(true);
before(() => {
cy.getCookie('minds_sess')
.then((sessionCookie) => {
if (sessionCookie === null) {
return cy.login(true);
}
});
});
beforeEach(() => {
cy.preserveCookies();
cy.server();
cy.route("POST", "**/api/v1/subscribe/*").as("subscribe");
cy.route("DELETE", "**/api/v1/subscribe/*").as("unsubscribe");
cy.location('pathname', { timeout: 30000 })
.should('eq', `/newsfeed/subscriptions`);
cy.visit(`/${user}`);
})
cy.visit(`/${user}/`);
cy.location('pathname')
.should('eq', `/${user}/`);
});
it('should allow a user to subscribe to another', () => {
subscribe();
......@@ -20,16 +31,26 @@ context('Subscription', () => {
it('should allow a user to unsubscribe',() => {
unsubscribe();
})
});
function subscribe() {
cy.get(subscribeButton).click();
cy.get(messageButton).should('be.visible');
cy.get(subscribeButton)
.click()
.wait('@subscribe').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.equal("success");
});
cy.get(messageButton).should('be.visible')
}
function unsubscribe() {
cy.get(userDropdown).click();
cy.contains('Unsubscribe').click();
cy.contains('Unsubscribe')
.click()
.wait('@unsubscribe').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.equal("success");
});
cy.get(subscribeButton).should('be.visible');
}
......
......@@ -20,7 +20,7 @@ context('Topbar', () => {
.contains('View Channel')
.click();
cy.location('pathname').should('eq', `/${Cypress.env().username}`);
cy.location('pathname').should('eq', `/${Cypress.env().username}/`);
});
it('clicking on the dropdown on the right should allow to go to settings', () => {
......