Commit 84f40080 authored by Mark Harding's avatar Mark Harding

(feat): move e2e to its own repo

1 merge request!506WIP: (feat): move e2e to its own repo
Pipeline #77289381 passed with stage
This diff is collapsed.
......@@ -15,9 +15,7 @@ Please see the documentation on Minds.org for instructions on how to [build the
Run `npm run test`
### Integration Tests
For integration tests you need to run:
`npm run e2e --config baseUrl=http://localhost --env username=minds,password=Pa$$w0rd`
For integration tests see the the [E2E](https://gitlab.com/minds/e2e) repository.
## Contributing
If you'd like to contribute to the Minds project, check out the [Contribution](https://www.minds.org/docs/contributing.html) section of Minds.org or head right over to the [Minds Open Source Community](https://www.minds.com/groups/profile/365903183068794880). If you've found or fixed a bug, let us know in the [Minds Help and Support Group](https://www.minds.com/groups/profile/100000000000000681/activity)!
......
{
"requestTimeout": 3600000,
"responseTimeout": 3600000,
"pageLoadTimeout": 3600000
}
cypress/fixtures/avatar.jpeg

8.1 KB

{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes"
}
\ No newline at end of file
cypress/fixtures/international-space-station-1776401_1920.jpg

696 KB

// import 'cypress-file-upload';
context('Blogs', () => {
beforeEach(() => {
cy.login(true);
cy.location('pathname', { timeout: 30000 })
.should('eq', `/newsfeed/subscriptions`);
})
it('should not be able to create a new blog if no title or banner are specified', () => {
cy.visit('/blog/edit/new');
cy.get('.m-button--submit').click();
cy.wait(100);
cy.get('.m-blog--edit--error').contains('Error: You must provide a title');
cy.get('minds-textarea .m-editor').type('Title');
cy.get('.m-button--submit').click();
cy.get('.m-blog--edit--error').contains('Error: You must upload a banner');
})
// TODO: remove the x when we run tests in new users each time
xit("should not be able to create a new blog if the channel doesn't have an avatar", () => {
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');
cy.wait(1000);
cy.server();
cy.route("POST", "**!/api/v1/blog/new").as("newBlog");
cy.get('.m-button--submit').click({ force: true }); // TODO: Investigate why disabled flag is being detected
cy.get('h1.m-blog--edit--error').contains('Error: Please ensure your channel has an avatar before creating a blog');
});
it('should be able to create a new blog', () => {
// upload avatar first
cy.visit(`/${Cypress.env().username}`);
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 input[type=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');
cy.get('.m-button--submit').click({ force: true }); // TODO: Investigate why disabled flag is being detected
cy.clock();
cy.clock().then((clock) => { clock.tick(1000); });
cy.wait(1000);
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');
// 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();
})
})
context('Boost Console', () => {
const postContent = "Test boost, please reject..." + Math.random().toString(36);
beforeEach(() => {
cy.login(true);
cy.wait(5000);
cy.visit('/newsfeed/subscriptions');
cy.wait(3000);
cy.location('pathname', { timeout: 30000 })
.should('eq', `/newsfeed/subscriptions`);
newBoost(postContent, 100);
});
it('should show a new boost in the console', () => {
cy.visit('/boost/console/newsfeed/history');
cy.wait(3000);
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.wait(1000);
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');
cy.get('m-boost-console-card:nth-child(1) .m-boost-card--manager-item--buttons > button')
.click();
cy.wait(1000);
cy.get('m-boost-console-card:nth-child(1) div.m-boost-card--manager-item.m-boost-card--state')
.contains('revoked');
});
function navToConsole() {
cy.visit('/boost/console/newsfeed/history');
cy.wait(3000);
cy.location('pathname', { timeout: 30000 })
.should('eq', `/boost/console/newsfeed/history`);
}
function newBoost(text, views) {
cy.post(text);
cy.wait(2000);
cy.get('#boost-actions')
.first()
.click();
cy.wait(5000);
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(5000);
cy.get('.m-overlay-modal')
.should('not.be.visible')
}
})
context('Boost Impressions', () => {
beforeEach(() => {
cy.login(true);
cy.location('pathname', { timeout: 30000 })
.should('eq', '/newsfeed/subscriptions');
});
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.wait(3000);
cy.scrollTo(0, 500);
cy.wait(3000);
//assert
cy.wait('@analytics', { requestTimeout: 5000 }).then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body).to.deep.equal({ status: 'success' });
});
});
it('should register views on boost rotate forward', () => {
//stub endpoint
cy.server();
cy.route("POST", "**/api/v2/analytics/views/boost/*").as("analytics");
cy.wait(3000);
//rotate forward and wait to trigger analytics
cy.get('m-newsfeed--boost-rotator > div > ul > li:nth-child(2) > i')
.click();
cy.wait(3000);
//assert
cy.wait('@analytics', { requestTimeout: 5000 }).then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.deep.equal("success");
});
});
it('should register views on boost rotate backward', () => {
//stub endpoint
cy.server();
cy.route("POST", "**/api/v2/analytics/views/boost/*").as("analytics");
cy.wait(3000);
//rotate forward and wait to trigger analytics
cy.get('m-newsfeed--boost-rotator > div > ul > li:nth-child(1) > i')
.click();
cy.wait(3000);
//assert
cy.wait('@analytics', { requestTimeout: 5000 }).then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.deep.equal("success");
});
});
});
/**
* @author Ben Hayward
* @create date 2019-08-09 14:42:51
* @modify date 2019-08-09 14:42:51
* @desc Spec tests for comment threads.
*/
context('Comment Threads', () => {
const testMessage = {
1: 'test tier 1',
2: 'test tier 2',
3: 'test tier 3',
};
const hamburgerMenu = '.m-v2-topbar__UserMenu > m-user-menu > div.m-user-menu.m-dropdown > a';
const logoutButton = '.m-user-menu.m-dropdown > ul > li:nth-child(11) > a';
const postMenu = 'minds-activity:nth-child(2) > div > m-post-menu > button > i';
const deletePostOption = 'minds-activity:nth-child(2) m-post-menu > ul > li:nth-child(4)';
const deletePostButton = 'm-modal-confirm div:nth-child(1) > div > button.mdl-button--colored';
const channelButton = '.m-v2-topbar__Top > div > a > minds-avatar > div';
const postCommentButton = 'm-comment__poster > div > div.minds-body > div > div > a.m-post-button';
const thumbsUpButtons = '.m-comment__toolbar minds-button-thumbs-up';
const thumbsDownButtons = '.m-comment__toolbar minds-button-thumbs-down';
const thumbsUpCounters = '.m-comment__toolbar > div > minds-button-thumbs-up > a > span';
const thumbsDownCounters = '.m-comment__toolbar > div > minds-button-thumbs-down > a > span';
// pass in tier / tree depth.
const replyButton = (index) => `minds-activity:nth-child(${index}) .m-comment__toolbar > div > span`;
const commentButton = (index) => `minds-activity:nth-child(${index}) minds-button-comment`;
const commentInput = (index) => `minds-activity:nth-child(${index}) m-text-input--autocomplete-container > minds-textarea > div`;
const commentContent = (index) => `minds-activity:nth-child(${index}) m-comments__tree .m-comment__bubble > p`;
before(() => {
//make a post new.
login();
cy.post('test post');
//manually sign-out.
cy.get(hamburgerMenu).click();
cy.get(logoutButton).click();
});
after(() => {
//delete the post
cy.wait(1000);
cy.get(postMenu).click();
cy.get(deletePostOption).click();
cy.get(deletePostButton).click();
});
beforeEach(() => {
login();
cy.wait(2000);
});
it('should allow a user to post a tier 1 comment', () => {
cy.get(commentButton(2)).click();
cy.get(commentInput(2)).type(testMessage[1]);
cy.get(postCommentButton).click();
cy.get(commentContent(2)).contains(testMessage[1]);
});
it('should allow a user to post a tier 2 comment', () => {
//expand top comment, then top reply button.
cy.get(commentButton(2)).click();
cy.get(replyButton(2)).click();
cy.get(commentInput(2)).first().type(testMessage[2]);
cy.get(postCommentButton).first().click();
cy.get(commentContent(2)).contains(testMessage[2]);
});
it('should allow a user to post a tier 3 comment', () => {
//expand top comment, then top reply button.
cy.get(commentButton(2)).click();
cy.get(replyButton(2)).click();
cy.wait(1000);
//there are two reply buttons now, use the last one.
cy.get(replyButton(2)).last().click();
cy.wait(1000);
//check the comments.
cy.get(commentInput(2)).first().type(testMessage[3]);
cy.get(postCommentButton).first().click();
cy.get(commentContent(2)).contains(testMessage[3]);
});
it('should allow the user to vote up and down comments', () => {
//expand top comment, then top reply button.
cy.get(commentButton(2)).click();
cy.get(replyButton(2)).click();
cy.wait(1000);
//there are two reply buttons now, use the last one.
cy.get(replyButton(2)).last().click();
cy.wait(1000);
//click thumbs up and down
cy.get(thumbsDownButtons).click({multiple: true});
cy.get(thumbsUpButtons).click({multiple: true});
// check the values
cy.get(thumbsUpCounters)
.each((counter) => expect(counter.context.innerHTML).to.eql('1'));
cy.get(thumbsDownCounters)
.each((counter) => expect(counter.context.innerHTML).to.eql('1'));
});
function login() {
cy.login(true);
cy.location('pathname', { timeout: 30000 })
.should('eq', `/newsfeed/subscriptions`);
cy.get(channelButton).click();
}
})
context('Discovery', () => {
beforeEach(() => {
cy.login(true);
cy.location('pathname', { timeout: 30000 })
.should('eq', `/newsfeed/subscriptions`);
});
it('should allow a user to post on the discovery page', () => {
cy.visit('/newsfeed/global/top');
cy.post("test!!");
});
it('should be able to filter by hot', () => {
cy.visit('/newsfeed/global/top');
cy.get('.m-sort-selector--algorithm-dropdown ul > li:nth-child(1)')
.click()
.should('have.css', 'color', 'rgb(70, 144, 223)'); // selected color
cy.url().should('include', '/hot');
});
it('should be able to filter by top', () => {
cy.visit('/newsfeed/global/hot');
cy.get('.m-sort-selector--algorithm-dropdown ul > li:nth-child(2)')
.click()
.should('have.css', 'color', 'rgb(70, 144, 223)'); // selected color
cy.url().should('include', '/top');
});
it('should be able to filter by time in the top feed', () => {
cy.visit('/newsfeed/global/top');
cy.get('.m-sort-selector--period-dropdown').click();
cy.get('.m-sort-selector--period-dropdown ul > li:nth-child(5)').click();
cy.url().should('include', '=1y');
cy.get('.m-sort-selector--period-dropdown').click();
cy.get('.m-sort-selector--period-dropdown ul > li:nth-child(4)').click();
cy.url().should('include', '=30d');
cy.get('.m-sort-selector--period-dropdown').click();
cy.get('.m-sort-selector--period-dropdown ul > li:nth-child(3)').click();
cy.url().should('include', '=7d');
cy.get('.m-sort-selector--period-dropdown').click();
cy.get('.m-sort-selector--period-dropdown ul > li:nth-child(2)').click();
cy.url().should('include', '=24h');
cy.get('.m-sort-selector--period-dropdown').click();
cy.get('.m-sort-selector--period-dropdown ul > li:nth-child(1)').click();
cy.url().should('include', '=12h');
});
it('should filter by latest', () => {
cy.visit('/newsfeed/global/hot');
cy.get('.m-sort-selector--algorithm-dropdown ul > li:nth-child(3)')
.click()
.should('have.css', 'color', 'rgb(70, 144, 223)'); // selected color
cy.url().should('include', '/latest');
});
it('should filter by image', () => {
cy.visit('/newsfeed/global/hot');
cy.get('.m-sort-selector--custom-type-dropdown').click();
cy.get('.m-sort-selector--custom-type-dropdown ul > li:nth-child(2)').click();
cy.url().should('include', '=images');
});
it('should filter by video', () => {
cy.visit('/newsfeed/global/hot');
cy.get('.m-sort-selector--custom-type-dropdown').click();
cy.get('.m-sort-selector--custom-type-dropdown ul > li:nth-child(3)').click();
cy.url().should('include', '=videos');
});
it('should filter by blog', () => {
cy.visit('/newsfeed/global/hot');
cy.get('.m-sort-selector--custom-type-dropdown').click();
cy.get('.m-sort-selector--custom-type-dropdown ul > li:nth-child(4)').click();
cy.url().should('include', '=blog');
});
it('should filter by channels', () => {
cy.visit('/newsfeed/global/hot');
cy.get('.m-sort-selector--custom-type-dropdown').click();
cy.get('.m-sort-selector--custom-type-dropdown ul > li:nth-child(5)').click();
cy.url().should('include', '=channels');
});
it('should filter by groups', () => {
cy.visit('/newsfeed/global/hot');
cy.get('.m-sort-selector--custom-type-dropdown').click();
cy.get('.m-sort-selector--custom-type-dropdown ul > li:nth-child(6)').click();
cy.url().should('include', '=groups');
});
it('should filter by all', () => {
cy.visit('/newsfeed/global/top?type=images');
cy.get('.m-sort-selector--custom-type-dropdown').click();
cy.get('.m-sort-selector--custom-type-dropdown ul > li:nth-child(1)').click();
cy.url().should('not.include', '=images');
});
it('should allow the user to toggle nsfw', () => {
cy.visit('/newsfeed/global/top?type=images');
cy.get('m-topbar--navigation--options').click();
cy.get('m-topbar--navigation--options label > span').click();
cy.get('m-topbar--navigation--options ul > m-nsfw-selector ul > li:nth-child(1)').click();
cy.get('m-topbar--navigation--options ul > m-nsfw-selector ul > li:nth-child(2)').click();
cy.get('m-topbar--navigation--options ul > m-nsfw-selector ul > li:nth-child(3)').click();
cy.get('m-topbar--navigation--options ul > m-nsfw-selector ul > li:nth-child(4)').click();
cy.get('m-topbar--navigation--options ul > m-nsfw-selector ul > li:nth-child(5)').click();
cy.get('m-topbar--navigation--options ul > m-nsfw-selector ul > li:nth-child(6)').click();
});
it('should allow the user to filter by a single hashtag', () => {
cy.get('.m-hashtagsSidebarSelector__list > ul > li:nth-child(1) .m-hashtagsSidebarSelectorList__visibility > i')
.click(); // Will fail on non-configured users
});
it('should allow the user to turn off single hashtag filter and view all posts', () => {
cy.get('.m-hashtagsSidebarSelector__list > ul > li:nth-child(1) .m-hashtagsSidebarSelectorList__visibility > i')
.click();
})
})
\ No newline at end of file
context('Groups', () => {
beforeEach(() => {
cy.login(true);
cy.location('pathname', { timeout: 30000 })
.should('eq', `/newsfeed/subscriptions`);
})
it('should create and edit a group', () => {
cy.get('m-group--sidebar-markers li:first-child').contains('New group').click();
cy.location('pathname').should('eq', '/groups/create');
// add a banner
cy.uploadFile('minds-banner #file', '../fixtures/international-space-station-1776401_1920.jpg', 'image/jpg');
// add a name
cy.get('.m-group-info-name > input').type('test');
// add a description
cy.get('.m-group-info-brief-description > textarea').type('This is a test');
// 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();
// 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.wait(1000);
cy.get('.m-groupInfo__name').contains('test');
cy.get('.m-groupInfo__description').contains('This is a test');
// open settings button
cy.get('minds-groups-settings-button > button').click();
cy.get('minds-groups-settings-button ul.minds-dropdown-menu li:first-child').contains('Edit').click();
// edit name
cy.get('.m-groupInfo__name input').type(' group');
// edit description
cy.get('.m-groupInfo__description textarea').type(' group');
// open settings button
cy.get('minds-groups-settings-button > button').click();
cy.get('minds-groups-settings-button ul.minds-dropdown-menu li:first-child').contains('Save').click();
cy.get('.m-groupInfo__name').contains('test group');
cy.get('.m-groupInfo__description').contains('This is a test group');
})
it('should be able to toggle conversation and comment on it', () => {
cy.get('m-group--sidebar-markers li:nth-child(3)').contains('test group').click();
// toggle the conversation
cy.get('.m-groupGrid__right').should('be.visible');
cy.get('.m-groupGrid__toggleBtn').click();
cy.get('.m-groupGrid__right').should('not.be.visible');
cy.get('.m-groupGrid__toggleBtn').click();
// comment
cy.get('minds-groups-profile-conversation m-comments__tree minds-textarea .m-editor').type('lvl 1 comment');
cy.get('minds-groups-profile-conversation m-comments__tree a.m-post-button').click();
cy.wait(500);
// comment should appear on the list
cy.get('minds-groups-profile-conversation m-comments__tree > m-comments__thread .m-commentBubble__message').contains('lvl 1 comment');
cy.on('window:confirm', (str) => {
return true;
});
})
it('should post an activity inside the group and record the view when scrolling', () => {
cy.get('m-group--sidebar-markers li:nth-child(3)').contains('test group').click();
cy.wait(1000);
cy.server();
cy.route("POST", "**/api/v2/analytics/views/activity/*").as("view");
cy.get('minds-newsfeed-poster textarea').type('This is a post');
cy.get('.m-posterActionBar__PostButton').click();
cy.wait(500);
// the activity should show that it was posted in this group
cy.get('.minds-list minds-activity .body a:nth-child(2)').contains('(test group)');
cy.get('.minds-list minds-activity .m-mature-message-content').contains('This is a post');
// create the post
cy.get('minds-newsfeed-poster textarea').type('This is a post that will record a view');
cy.get('.m-posterActionBar__PostButton').click();
cy.wait(200);
cy.scrollTo(0, '20px');
cy.wait('@view', { requestTimeout: 2000 }).then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body).to.deep.equal({ status: 'success' });
});
});
it('should delete a group', () => {
cy.get('m-group--sidebar-markers li:nth-child(3)').contains('test group').click();
cy.wait(1000);
// cleanup
cy.get('minds-groups-settings-button > button').click();
cy.get('minds-groups-settings-button ul.minds-dropdown-menu > li:nth-child(8)').contains('Delete Group').click();
cy.get('minds-groups-settings-button m-modal .mdl-button--raised').contains('Confirm').click();
cy.location('pathname').should('eq', '/groups/member');
})
})
context('Login', () => {
beforeEach(() => {
cy.visit('/')
})
it('should login', () => {
cy.get('.m-v2-topbar__Container__LoginWrapper > a').click();
cy.location('pathname').should('eq', '/login');
// it should have a login form
cy.get('.m-login').should('be.visible');
cy.get('minds-form-login .m-login-box .mdl-cell:first-child input').type(Cypress.env().username);
cy.get('minds-form-login .m-login-box .mdl-cell:last-child input').type(Cypress.env().password);
cy.get('minds-form-login .m-btn--login').click();
cy.location('pathname', { timeout: 10000 })
.should('eq', '/newsfeed/subscriptions');
})
it('should fail to login because of incorrect password', () => {
cy.get('.m-v2-topbar__Container__LoginWrapper > a').click();
cy.location('pathname').should('eq', '/login');
// it should have a login form
cy.get('.m-login').should('be.visible');
cy.get('minds-form-login .m-login-box .mdl-cell:first-child input').type(Cypress.env().username);
cy.get('minds-form-login .m-login-box .mdl-cell:last-child input').type(Cypress.env().password + '1');
cy.get('minds-form-login .m-btn--login').click();
cy.wait(500);
cy.get('minds-form-login .m-error-box .mdl-card__supporting-text').contains('Incorrect username/password. Please try again.');
// cy.location('pathname').should('eq', '/newsfeed/subscriptions');
})
})
context('Newsfeed', () => {
beforeEach(() => {
cy.login(true);
cy.location('pathname', { timeout: 30000 })
.should('eq', '/newsfeed/subscriptions');
})
it('should post an activity picking hashtags from the dropdown', () => {
cy.get('minds-newsfeed-poster').should('be.visible');
cy.get('minds-newsfeed-poster textarea').type('This is a post');
// click on hashtags dropdown
cy.get('minds-newsfeed-poster m-hashtags-selector .m-dropdown--label-container').click();
// select #ART
cy.get('minds-newsfeed-poster m-hashtags-selector m-dropdown m-form-tags-input > div > span').contains('#art').click();
// type in another hashtag manually
cy.get('minds-newsfeed-poster m-hashtags-selector m-form-tags-input input').type('hashtag{enter}').click();
// click away
cy.get('minds-newsfeed-poster m-hashtags-selector .minds-bg-overlay').click();
cy.get('.m-posterActionBar__PostButton').click();
cy.wait(100);
cy.get('.minds-list > minds-activity:first-child .message').contains('This is a post #art #hashtag');
cy.get('.minds-list > minds-activity:first-child .message a:first-child').contains('#art').should('have.attr', 'href', '/newsfeed/global/top;hashtag=art;period=24h');
cy.get('.minds-list > minds-activity:first-child .message a:last-child').contains('#hashtag').should('have.attr', 'href', '/newsfeed/global/top;hashtag=hashtag;period=24h');
// 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 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');
cy.wait(1000);
cy.get('.m-posterActionBar__PostButton').click();
cy.wait(300);
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.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 post a nsfw activity', () => {
cy.get('minds-newsfeed-poster').should('be.visible');
cy.get('minds-newsfeed-poster textarea').type('This is a nsfw post');
// click on nsfw dropdown
cy.get('minds-newsfeed-poster m-nsfw-selector .m-dropdown--label-container').click();
// select Nudity
cy.get('minds-newsfeed-poster m-nsfw-selector .m-dropdownList__item').contains('Nudity').click();
// click away
cy.get('minds-newsfeed-poster m-nsfw-selector .minds-bg-overlay').click();
cy.get('.m-posterActionBar__PostButton').click();
cy.wait(100);
// should have the mature text toggle
cy.get('.minds-list > minds-activity:first-child .message .m-mature-text-toggle').should('not.have.class', 'mdl-color-text--red-500');
cy.get('.minds-list > minds-activity:first-child .message .m-mature-message-content').should('have.class', 'm-mature-text');
// click the toggle
cy.get('.minds-list > minds-activity:first-child .message .m-mature-text-toggle').click();
// text should be visible now
cy.get('.minds-list > minds-activity:first-child .message .m-mature-text-toggle').should('have.class', 'mdl-color-text--red-500');
cy.get('.minds-list > minds-activity:first-child .message .m-mature-message-content').should('not.have.class', 'm-mature-text');
cy.get('.minds-list > minds-activity:first-child .message .m-mature-message-content').contains('This is a nsfw post');
// 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 vote an activity', () => {
cy.get('minds-newsfeed-poster textarea').type('This is an upvoted post');
cy.get('.m-posterActionBar__PostButton').click();
// upvote
cy.get('.minds-list > minds-activity:first-child minds-button-thumbs-up a').should('not.have.class', 'selected');
cy.get('.minds-list > minds-activity:first-child minds-button-thumbs-up a').click();
cy.get('.minds-list > minds-activity:first-child minds-button-thumbs-up a').should('have.class', 'selected');
cy.get('.minds-list > minds-activity:first-child minds-button-thumbs-up span').contains('1');
cy.get('.minds-list > minds-activity:first-child minds-button-thumbs-up a').click();
cy.get('.minds-list > minds-activity:first-child minds-button-thumbs-up a').should('not.have.class', 'selected');
// downvote
cy.get('.minds-list > minds-activity:first-child minds-button-thumbs-down a').should('not.have.class', 'selected');
cy.get('.minds-list > minds-activity:first-child minds-button-thumbs-down a').click();
cy.get('.minds-list > minds-activity:first-child minds-button-thumbs-down a').should('have.class', 'selected');
cy.get('.minds-list > minds-activity:first-child minds-button-thumbs-down span').contains('1');
cy.get('.minds-list > minds-activity:first-child minds-button-thumbs-down a').click();
cy.get('.minds-list > minds-activity:first-child minds-button-thumbs-down a').should('not.have.class', 'selected');
// 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 have an "Upgrade to Plus" button and it should redirect to /plus', () => {
cy.get('.m-page--sidebar--navigation a.m-page--sidebar--navigation--item:nth-child(2) span')
.contains('Upgrade to Plus');
cy.get('.m-page--sidebar--navigation a.m-page--sidebar--navigation--item:nth-child(2)').should('have.attr', 'href', '/plus')
.click();
cy.location('pathname').should('eq', '/plus');
})
it('should have a "Buy Tokens" button and it should redirect to /token', () => {
cy.get('.m-page--sidebar--navigation a.m-page--sidebar--navigation--item:last-child span')
.contains('Buy Tokens');
cy.get('.m-page--sidebar--navigation a.m-page--sidebar--navigation--item:last-child').should('have.attr', 'href', '/tokens')
.click();
cy.location('pathname').should('eq', '/token');
})
it('"create blog" button in poster should redirect to /blog/edit/new', () => {
cy.get('minds-newsfeed-poster .m-posterActionBar__CreateBlog')
.contains('Create blog')
.click();
cy.location('pathname').should('eq', '/blog/edit/new');
})
it('clicking on "create blog" button in poster should prompt a confirm dialog and open a new blog with the currently inputted text', () => {
cy.get('minds-newsfeed-poster textarea').type('thegreatmigration'); // TODO: fix UX issue when hashtag element is overlapping input
const stub = cy.stub();
cy.on('window:confirm', stub);
cy.get('minds-newsfeed-poster .m-posterActionBar__CreateBlog')
.contains('Create blog').click()
.then(() => {
expect(stub.getCall(0)).to.be.calledWith('Are you sure? The content will be moved to the blog editor.')
});
cy.location('pathname').should('eq', '/blog/edit/new');
cy.get('m-inline-editor .medium-editor-element.medium-editor-insert-plugin p').contains('thegreatmigration');
})
it('should record a view when the user scrolls and an activity is visible', () => {
cy.server();
cy.route("POST", "**/api/v2/analytics/views/activity/*").as("view");
// create the post
cy.get('minds-newsfeed-poster textarea').type('This is a post that will record a view');
cy.get('.m-posterActionBar__PostButton').click();
cy.wait(200);
cy.scrollTo(0, '20px');
cy.wait(600);
cy.wait('@view', { requestTimeout: 2000 }).then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body).to.deep.equal({ status: 'success' });
});
// 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('clicking on the plus button on the sidebar should redirect the user to /groups/create', () => {
cy.get('m-group--sidebar-markers .m-groupSidebarMarkers__list li:first-child')
.contains('add')
.click();
cy.location('pathname').should('eq', '/groups/create');
})
})
context('Onboarding', () => {
const email = 'test@minds.com';
const password = 'Passw0rd!';
const name = "Tester";
const description = "I am a tester, with a not so lengthy description";
const welcomeText = "Welcome to Minds!";
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 nameField = '#display-name';
const descriptionfield = '#description';
const phoneNumberInput = '#phone';
const countryDropdown = 'm-phone-input--country > div';
const ukOption = 'm-phone-input--country > ul > li:nth-child(2)';
const dialcode = '.m-phone-input--dial-code';
const checkbox = 'minds-form-register label:nth-child(2) .mdl-ripple--center';
const submitButton = 'minds-form-register .mdl-card__actions button';
const nextButton = '.m-channelOnboarding__next';
const submitPhoneButton = 'm-channel--onboarding--rewards > div > div > button';
const loadingSpinner = '.mdl-spinner__gap-patch';
const getTopic = (i) => `m-onboarding--topics > div > ul > li:nth-child(${i}) span`;
before(() => {
cy.visit('/login');
//type values
cy.get(usernameField).focus().type(Math.random().toString(36).replace('0.', ''));
cy.get(emailField).focus().type(email);
cy.get(passwordField).focus().type(password);
cy.get(password2Field).focus().type(password);
cy.get(checkbox).click();
//submit
cy.get(submitButton).click();
//onboarding modal shown
cy.get('m-onboarding--topics > div > h2:nth-child(1)')
.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')
//click
cy.get(nextButton).click();
});
it('should skip over subscribed channels', () => {
//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();
cy.get(dialcode).contains('+44');
//type number
cy.get(phoneNumberInput).type('7700000000');
//submit and check loading spinner.
cy.get(submitPhoneButton).click();
cy.get(loadingSpinner).should('be.visible');
cy.get(nextButton).click();
});
});
context('Remind', () => {
const remindText = 'remind test text';
beforeEach(() => {
cy.login(true);
cy.location('pathname', { timeout: 30000 })
.should('eq', `/newsfeed/subscriptions`);
//nav to channel
cy.get('.m-v2-topbar__Top minds-avatar div')
.click();
});
it('should allow a user to remind their post', () => {
//post
cy.post("test!!");
//open remind composer
cy.get('minds-button-remind > a')
.first()
.click();
//fill out text box in modal
cy.get('.m-modal-remind-composer textarea')
.type(remindText);
//post remind.
cy.get('.m-modal-remind-composer-send i')
.click();
softReload();
cy.wait(1000);
//expect to contain text
cy.get('m-newsfeed__entity:nth-child(3) span')
.contains(remindText);
})
it('should allow a user to delete their remind', () => {
// make sure top post has the reminded text.
cy.get('m-newsfeed__entity:nth-child(3) .m-activity--message-remind span')
.contains(remindText);
//open menu.
cy.get('m-newsfeed__entity:nth-child(3) m-post-menu > button > i')
.click();
//select delete.
cy.get('m-newsfeed__entity:nth-child(3) m-post-menu ul li:nth-child(4)')
.click();
//delete confirm.
cy.get('m-newsfeed__entity:nth-child(3) m-modal-confirm div:nth-child(1) button.mdl-button.mdl-color-text--white.mdl-button--colored.mdl-button--raised')
.click();
cy.wait(2000);
//check the post is gone.
cy.get('m-newsfeed__entity:nth-child(3) .m-activity--message-remind span')
.should('not.have.value', remindText)
});
/**
* Cycles by pressing home screen then back to channel
*/
function softReload() {
cy.wait(6000); //wait to let requests finish.
cy.get('.m-v2-topbarNavItem__Logo > img')
.click();
cy.get('.m-v2-topbar__Top minds-avatar div')
.click();
cy.wait(1000); //wait to let requests finish.
}
})
context('Topbar', () => {
beforeEach(() => {
cy.login(true);
cy.location('pathname', { timeout: 30000 })
.should('eq', '/newsfeed/subscriptions');
})
it("clicking on the dropdown on the right should allow to go to the user's channel", () => {
// open the menu
cy.get('m-user-menu .m-user-menu__Anchor').click();
cy.get('m-user-menu .m-user-menu__Dropdown li')
.contains('View Channel')
.click();
cy.location('pathname').should('eq', `/${Cypress.env().username}`);
})
it('clicking on the dropdown on the right should allow to go to settings', () => {
// open the menu
cy.get('m-user-menu .m-user-menu__Anchor').click();
cy.get('m-user-menu .m-user-menu__Dropdown li')
.contains('Settings')
.click();
cy.location('pathname').should('eq', '/settings/general');
})
it('clicking on the dropdown on the right should allow to go to the boost console', () => {
// open the menu
cy.get('m-user-menu .m-user-menu__Anchor').click();
cy.get('m-user-menu .m-user-menu__Dropdown li')
.contains('Boost Console')
.click();
// TOFIX: no boost redirects to create
// cy.location('pathname').should('eq', '/boost/console/newsfeed/history');
})
it('clicking on the dropdown on the right should allow to go to the boost console', () => {
// open the menu
cy.get('m-user-menu .m-user-menu__Anchor').click();
cy.get('m-user-menu .m-user-menu__Dropdown li')
.contains('Help Desk')
.click();
cy.location('pathname').should('eq', '/help');
})
it('clicking on the dropdown on the right should redirect to /canary', () => {
// open the menu
cy.get('m-user-menu .m-user-menu__Anchor').click();
cy.get('m-user-menu .m-user-menu__Dropdown li')
.contains('Canary')
.click();
cy.location('pathname').should('eq', '/canary');
})
it('clicking on the dropdown on the right should allow to toggle Dark Mode', () => {
// open the menu
cy.get('m-user-menu .m-user-menu__Anchor').click();
cy.get('body.m-theme__light').should('be.visible');
cy.get('m-user-menu .m-user-menu__Dropdown li')
.contains('Dark Mode')
.click();
cy.get('body.m-theme__dark').should('be.visible');
cy.get('m-user-menu .m-user-menu__Dropdown li')
.contains('Light Mode')
.click();
cy.get('body.m-theme__light').should('be.visible');
})
it('clicking on the bulb on the topbar should redirect to /newsfeed/subscriptions', () => {
cy.get('.m-v2-topbarNavItem__Logo img').should('be.visible');
cy.get('.m-v2-topbarNavItem__Logo').click();
cy.location('pathname').should('eq', '/newsfeed/subscriptions');
})
it('clicking on the bell should open the notifications dropdown, and allow to view all notifications by redirecting to /notifications', () => {
cy.get('.m-v2-topbar__UserMenu m-notifications--flyout').should('not.be.visible');
cy.get('.m-v2-topbar__UserMenu a.m-notifications--topbar-toggle--icon')
.should('be.visible')
.click();
cy.get('.m-v2-topbar__UserMenu m-notifications--flyout').should('be.visible');
cy.get('.m-notifications--flyout--bottom-container a')
.click();
cy.location('pathname').should('eq', '/notifications');
})
})
/**
* @author Ben Hayward
* @create date 2019-08-11 23:46:00
* @modify date 2019-08-11 23:46:00
* @desc Spec tests for Wire transactions.
*/
context('Wire', () => {
const wireButton = 'm-wire-channel > div > button';
const sendButton = '.m-wire--creator-section--last > div > button';
const modal = 'm-overlay-modal > div.m-overlay-modal';
beforeEach(() => {
cy.login();
cy.wait(2000);
});
it('should allow a user to send a wire to another user', () => {
// Visit users page.
cy.visit('/minds');
// Click profile wire button
cy.get(wireButton).click();
cy.wait(2000);
// Click send button
cy.get(sendButton).click();
cy.wait(5000);
//Make sure modal is hidden after 5 seconds.
cy.get(modal).should('be.hidden');
});
})
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************
// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
}
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add("login", (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This is will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
// Staging requires cookie to be set
Cypress.Cookies.defaults({
whitelist: 'staging'
});
Cypress.Commands.add('login', (canary) => {
cy.setCookie('staging', "1"); // Run in stagin mode. Note: does not impact review sites
cy.visit('/login');
cy.get('.m-btn--login').click();
cy.get('minds-form-login .m-login-box .mdl-cell:first-child input').type(Cypress.env().username);
cy.get('minds-form-login .m-login-box .mdl-cell:last-child input').type(Cypress.env().password);
cy.get('minds-form-login .m-btn--login').click();
});
Cypress.Commands.add('uploadFile', (selector, fileName, type = '') => {
cy.get(selector).then((subject) => {
cy.fixture(fileName, 'base64').then((content) => {
const el = subject[0];
const blob = b64toBlob(content, type);
cy.window().then((win) => {
const testFile = new win.File([blob], fileName, { type });
const dataTransfer = new DataTransfer();
dataTransfer.items.add(testFile);
el.files = dataTransfer.files;
// return cy.wrap(subject).trigger('change', {force: true});
});
});
});
// cy.get(selector).trigger('change', { force: true });
});
Cypress.Commands.add('post', (message) => {
cy.get('m-text-input--autocomplete-container textarea').type(message);
cy.get('.m-posterActionBar__PostButton').click();
});
function b64toBlob(b64Data, contentType, sliceSize = 512) {
const byteCharacters = atob(b64Data);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, { type: contentType });
blob.lastModifiedDate = new Date();
return blob;
}
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import './commands'
// Alternatively you can use CommonJS syntax:
// require('./commands')
This diff is collapsed.
......@@ -12,8 +12,6 @@
"build-dev": "ng build --output-path dist/en --deploy-url=/en/ --watch=true --poll=800",
"test": "ng test",
"lint": "ng lint",
"e2e": "cypress run --debug",
"e2e-open": "cypress open",
"postinstall": "node patch.js"
},
"private": true,
......@@ -58,7 +56,6 @@
"@types/jasminewd2": "~2.0.4",
"@types/node": "~10.12.18",
"codelyzer": "^4.5.0",
"cypress": "^3.4.1",
"gulp": "~4.0.0",
"gulp-autoprefixer": "^6.0.0",
"gulp-css-globbing": "^0.2.2",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment