Skip to content
Commits on Source (27)
......@@ -31,6 +31,8 @@ tmtags
Thumbs.db
Desktop.ini
node_modules
cypress/screenshots
cypress/videos
# don't ignore travis config
!/.travis.yml
!/.drone.yml
......
......@@ -16,8 +16,8 @@ stages:
variables:
CYPRESS_INSTALL_BINARY: 0 # Speeds up the install process
npm_config_cache: "$CI_PROJECT_DIR/.npm"
CYPRESS_CACHE_FOLDER: "$CI_PROJECT_DIR/cache/Cypress"
npm_config_cache: '$CI_PROJECT_DIR/.npm'
CYPRESS_CACHE_FOLDER: '$CI_PROJECT_DIR/cache/Cypress'
test:
image: circleci/node:8-browsers
......@@ -68,14 +68,14 @@ e2e:chrome:
build:review:
stage: build
before_script:
- sed -ri "s|\"VERSION\"|\"$CI_PIPELINE_ID\"|" src/environments/environment.prod.ts
- sed -ri "s|'VERSION'|'$CI_PIPELINE_ID'|" src/environments/environment.prod.ts
script:
- npm ci && npm install -g gulp-cli
- npm run postinstall
- gulp build.sass && gulp build.sass ##weird build needs to be run twice for now
- sh build/base-locale.sh dist
artifacts:
name: "$CI_COMMIT_REF_SLUG"
name: '$CI_COMMIT_REF_SLUG'
paths:
- dist
except:
......@@ -86,14 +86,14 @@ build:review:
build:production:en:
stage: build
before_script:
- sed -ri "s|\"VERSION\"|\"$CI_PIPELINE_ID\"|" src/environments/environment.prod.ts
- sed -ri "s|'VERSION'|'$CI_PIPELINE_ID'|" src/environments/environment.prod.ts
script:
- npm ci && npm install -g gulp-cli
- npm run postinstall
- gulp build.sass --deploy-url=https://cdn-assets.minds.com/front/dist/en && gulp build.sass --deploy-url=https://cdn-assets.minds.com/front/dist/en ##weird build needs to be run twice for now
- sh build/base-locale.sh dist https://cdn-assets.minds.com/front/dist
artifacts:
name: "$CI_COMMIT_REF_SLUG"
name: '$CI_COMMIT_REF_SLUG'
paths:
- dist/en
only:
......@@ -104,14 +104,14 @@ build:production:en:
build:production:i18n:
stage: build
before_script:
- sed -ri "s|\"VERSION\"|\"$CI_PIPELINE_ID\"|" src/environments/environment.prod.ts
- sed -ri "s|'VERSION'|'$CI_PIPELINE_ID'|" src/environments/environment.prod.ts
script:
- npm ci && npm install -g gulp-cli
- npm run postinstall
- gulp build.sass --deploy-url=https://cdn-assets.minds.com/front/dist/en && gulp build.sass --deploy-url=https://cdn-assets.minds.com/front/dist/en ##weird build needs to be run twice for now
- sh build/i18n-locales-all.sh dist https://cdn-assets.minds.com/front/dist
artifacts:
name: "$CI_COMMIT_REF_SLUG"
name: '$CI_COMMIT_REF_SLUG'
paths:
- dist/vi
only:
......@@ -138,7 +138,7 @@ prepare:review:
stage: prepare
image: minds/ci:latest
script:
- docker login -u gitlab-ci-token -p ${CI_BUILD_TOKEN} ${CI_REGISTRY}
- docker login -u gitlab-ci-token -p ${CI_BUILD_TOKEN} ${CI_REGISTRY}
- docker build -t $CI_REGISTRY_IMAGE/front-init:$CI_PIPELINE_ID -f containers/front-init/Dockerfile dist/.
- docker push $CI_REGISTRY_IMAGE/front-init:$CI_PIPELINE_ID
dependencies:
......@@ -151,7 +151,7 @@ prepare:review:
prepare:review:sentry:
<<: *sentry_prepare
variables:
SOURCEMAP_PREFIX: "~/en"
SOURCEMAP_PREFIX: '~/en'
except:
refs:
- master
......@@ -163,7 +163,7 @@ prepare:production:
stage: prepare
image: minds/ci:latest
script:
- docker login -u gitlab-ci-token -p ${CI_BUILD_TOKEN} ${CI_REGISTRY}
- docker login -u gitlab-ci-token -p ${CI_BUILD_TOKEN} ${CI_REGISTRY}
- docker build -t $CI_REGISTRY_IMAGE/front-init:$CI_PIPELINE_ID -f containers/front-init/Dockerfile dist/.
- docker push $CI_REGISTRY_IMAGE/front-init:$CI_PIPELINE_ID
only:
......@@ -177,7 +177,7 @@ prepare:production:
prepare:production:sentry:
<<: *sentry_prepare
variables:
SOURCEMAP_PREFIX: "~/front/dist/en"
SOURCEMAP_PREFIX: '~/front/dist/en'
only:
refs:
- master
......@@ -185,7 +185,7 @@ prepare:production:sentry:
dependencies:
- build:production:en
- build:production:i18n
################
# Review Stage #
################
......@@ -201,7 +201,7 @@ prepare:production:sentry:
action: stop
variables:
GIT_STRATEGY: none
except:
except:
refs:
- master
- test/gitlab-ci
......@@ -213,22 +213,22 @@ review:start:
- aws eks update-kubeconfig --name=sandbox
- git clone --branch=sandbox-wip https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/minds/helm-charts.git
- "helm upgrade \
--install \
--reuse-values \
--set frontInit.image.repository=$CI_REGISTRY_IMAGE/front-init \
--set-string frontInit.image.tag=$CI_PIPELINE_ID \
--set domain=$CI_BUILD_REF_SLUG.$KUBE_INGRESS_BASE_DOMAIN \
--set elasticsearch.clusterName=$CI_BUILD_REF_SLUG--elasticsearch \
--wait \
$CI_BUILD_REF_SLUG \
./helm-charts/minds"
--install \
--reuse-values \
--set frontInit.image.repository=$CI_REGISTRY_IMAGE/front-init \
--set-string frontInit.image.tag=$CI_PIPELINE_ID \
--set domain=$CI_BUILD_REF_SLUG.$KUBE_INGRESS_BASE_DOMAIN \
--set elasticsearch.clusterName=$CI_BUILD_REF_SLUG--elasticsearch \
--wait \
$CI_BUILD_REF_SLUG \
./helm-charts/minds"
# Update sentry
- sentry-cli releases deploys $CI_PIPELINE_ID new -e review-$CI_COMMIT_REF_SLUG
environment:
name: review/$CI_COMMIT_REF_NAME
url: https://$CI_BUILD_REF_SLUG.$KUBE_INGRESS_BASE_DOMAIN
on_stop: review:stop
except:
except:
refs:
- master
- test/gitlab-ci
......@@ -249,7 +249,7 @@ review:stop:
- aws s3 sync dist $S3_REPOSITORY_URL
- $(aws ecr get-login --no-include-email --region us-east-1)
## Update docker front-init container
- docker login -u gitlab-ci-token -p ${CI_BUILD_TOKEN} ${CI_REGISTRY}
- docker login -u gitlab-ci-token -p ${CI_BUILD_TOKEN} ${CI_REGISTRY}
- docker pull $CI_REGISTRY_IMAGE/front-init:$CI_PIPELINE_ID
- docker tag $CI_REGISTRY_IMAGE/front-init:$CI_PIPELINE_ID $ECR_REPOSITORY_URL:$IMAGE_LABEL
- docker push $ECR_REPOSITORY_URL:$IMAGE_LABEL
......@@ -269,7 +269,7 @@ staging:fpm:
<<: *deploy
stage: deploy:staging
variables:
IMAGE_LABEL: "staging"
IMAGE_LABEL: 'staging'
ECS_SERVICE: $ECS_APP_STAGING_SERVICE
environment:
name: staging
......@@ -279,7 +279,7 @@ deploy:canary:
<<: *deploy
stage: deploy:canary
variables:
IMAGE_LABEL: "canary"
IMAGE_LABEL: 'canary'
ECS_SERVICE: $ECS_APP_CANARY_SERVICE
environment:
name: canary
......@@ -291,7 +291,7 @@ deploy:production:
<<: *deploy
stage: deploy:production
variables:
IMAGE_LABEL: "production"
IMAGE_LABEL: 'production'
ECS_SERVICE: $ECS_APP_PRODUCTION_SERVICE
environment:
name: production
......@@ -306,7 +306,7 @@ deploy:production:
cleanup:review: # We stop the review site after the e2e tests have run
<<: *cleanup_review
stage: cleanup
except:
except:
refs:
- master
- test/gitlab-ci
{
"projectId": "qrjqcv",
"requestTimeout": 3600000,
"responseTimeout": 3600000,
"pageLoadTimeout": 3600000
......
// import 'cypress-file-upload';
context('Blogs', () => {
beforeEach(() => {
cy.login(true);
before(() => {
cy.clearCookies();
cy.getCookie('minds_sess')
.then((sessionCookie) => {
if (sessionCookie === null) {
return cy.login(true);
}
});
});
cy.location('pathname', { timeout: 30000 })
.should('eq', `/newsfeed/subscriptions`);
})
beforeEach(()=> {
cy.preserveCookies();
});
it('should not be able to create a new blog if no title or banner are specified', () => {
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');
......@@ -26,26 +31,6 @@ context('Blogs', () => {
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
......@@ -53,8 +38,6 @@ context('Blogs', () => {
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();
......@@ -106,14 +89,24 @@ 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");
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('@postBlog').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.equal("success");
});
cy.wait(1000);
cy.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 })
cy.location('pathname')
.should('contains', `/${Cypress.env().username}/blog`);
cy.get('.m-blog--title').contains('Title');
......
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`);
before(() => {
cy.getCookie('minds_sess')
.then((sessionCookie) => {
if (sessionCookie === null) {
return cy.login(true);
}
});
});
beforeEach(() => {
cy.preserveCookies();
cy.visit('/newsfeed/subscribed');
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);
});
......@@ -36,7 +34,6 @@ context('Boost Console', () => {
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');
......@@ -44,29 +41,31 @@ context('Boost Console', () => {
function navToConsole() {
cy.visit('/boost/console/newsfeed/history');
cy.wait(3000);
cy.location('pathname', { timeout: 30000 })
cy.location('pathname')
.should('eq', `/boost/console/newsfeed/history`);
}
function newBoost(text, views) {
cy.server();
cy.route("POST", '**/api/v2/boost/**').as('boostPost');
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.wait('@boostPost').then((xhr) => {
cy.log(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')
}
......
context('Boost Impressions', () => {
beforeEach(() => {
cy.login(true);
before(() => {
cy.getCookie('minds_sess')
.then((sessionCookie) => {
if (sessionCookie === null) {
return cy.login(true);
}
});
cy.visit('/newsfeed/subscriptions');
cy.location('pathname')
.should('eq', `/newsfeed/subscriptions`);
});
cy.location('pathname', { timeout: 30000 })
.should('eq', '/newsfeed/subscriptions');
beforeEach(()=> {
cy.preserveCookies();
});
it('should register views on scroll', () => {
......@@ -13,48 +22,36 @@ context('Boost Impressions', () => {
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) => {
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 forward', () => {
it('should register views on boost rotate', () => {
//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')
cy.get('m-newsfeed--boost-rotator > div > ul > li:nth-child(3) > i')
.click();
cy.wait(3000);
//assert
cy.wait('@analytics', { requestTimeout: 5000 }).then((xhr) => {
cy.wait('@analytics').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')
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) => {
cy.wait('@analytics').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.deep.equal("success");
});
......
context('Channel', () => {
before(() => {
cy.getCookie('minds_sess')
.then((sessionCookie) => {
if (sessionCookie === null) {
return cy.login(true);
}
});
cy.visit(`/${Cypress.env().username}`);
});
beforeEach(()=> {
cy.preserveCookies();
});
after(()=> {
cy.get('.m-channel-mode-selector--dropdown')
.click()
.find(".m-dropdown--list--item:contains('Public')")
.should('be.visible')
.click();
});
it('should change channel mode to public', () => {
cy.get('.m-channel-mode-selector--dropdown')
.click()
.find(".m-dropdown--list--item:contains('Public')")
.should('be.visible')
.click();
cy.get('.m-channel-mode-selector--dropdown')
.find('label').contains('Public');
});
it('should change channel mode to moderated', () => {
cy.get('.m-channel-mode-selector--dropdown')
.click()
.find(".m-dropdown--list--item:contains('Moderated')")
.should('be.visible')
.click();
cy.get('.m-channel-mode-selector--dropdown')
.find('label').contains('Moderated');
});
it('should change channel mode to closed', () => {
cy.get('.m-channel-mode-selector--dropdown')
.click()
.find(".m-dropdown--list--item:contains('Closed')")
.should('be.visible')
.click();
cy.get('.m-channel-mode-selector--dropdown')
.find('label').contains('Closed');
});
});
/**
* @author Ben Hayward
* @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.
......@@ -12,95 +12,90 @@ context('Comment Threads', () => {
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 postMenu = 'minds-activity:first > div > m-post-menu > button > i';
const deletePostOption = "m-post-menu > ul > li:visible:contains('Delete')";
const deletePostButton = ".m-modal-confirm-buttons > button:contains('Delete')";
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`;
const replyButton = `minds-activity:first .m-comment__toolbar > div > span`;
const commentButton = `minds-activity:first minds-button-comment`;
const commentInput = `minds-activity:first m-text-input--autocomplete-container > minds-textarea > div`;
const commentContent = `minds-activity:first m-comments__tree .m-comment__bubble > p`;
before(() => {
//make a post new.
login();
cy.getCookie('minds_sess')
.then((sessionCookie) => {
if (sessionCookie === null) {
return cy.login(true);
}
});
cy.visit('/newsfeed/subscriptions');
cy.location('pathname')
.should('eq', `/newsfeed/subscriptions`);
cy.post('test post');
//manually sign-out.
cy.get(hamburgerMenu).click();
cy.get(logoutButton).click();
});
beforeEach(()=> {
cy.preserveCookies();
});
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 post three tiers of comments', () => {
//Reveal the conversation
cy.get(commentButton).click();
it('should allow a user to post a tier 1 comment', () => {
cy.get(commentButton(2)).click();
cy.get(commentInput(2)).type(testMessage[1]);
//Add the first level of comments
cy.get(commentInput).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);
cy.get(commentContent).contains(testMessage[1]);
//there are two reply buttons now, use the last one.
cy.get(replyButton(2)).last().click();
cy.wait(1000);
//Add the second level of comments
cy.get(replyButton).click();
cy.get(commentInput)
.first()
.type(testMessage[2]);
cy.get(postCommentButton)
.first()
.click();
cy.get(commentContent).contains(testMessage[2]);
//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);
//Add the third level of comments
cy.get('minds-activity:first')
.find('m-comments__tree m-comments__thread m-comment')
.find('m-comments__thread m-comment:nth-child(2) .m-comment__toolbar > div > span')
.last()
.click();
cy.get(commentInput)
.first()
.type(testMessage[3]);
cy.get(postCommentButton)
.first()
.click();
cy.get(commentContent).contains(testMessage[3]);
//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});
cy.get('.m-comment__toolbar')
.find('minds-button-thumbs-up')
.click({multiple: true});
cy.get('.m-comment__toolbar')
.find('minds-button-thumbs-down')
.click({multiple: true});
// check the values
cy.get(thumbsUpCounters)
......@@ -109,12 +104,4 @@ context('Comment Threads', () => {
.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`);
before(() => {
cy.getCookie('minds_sess')
.then((sessionCookie) => {
if (sessionCookie === null) {
return cy.login(true);
}
});
cy.visit('/newsfeed/global/top');
});
beforeEach(()=> {
cy.preserveCookies();
});
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)')
cy.get(".m-sort-selector--algorithm-dropdown ul > li:contains('Hot')")
.click()
.should('have.css', 'color', 'rgb(70, 144, 223)'); // selected color
.should('have.class', 'm-dropdown--list--item--selected'); // selected class
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)')
cy.get(".m-sort-selector--algorithm-dropdown ul > li:contains('Top')")
.click()
.should('have.css', 'color', 'rgb(70, 144, 223)'); // selected color
.should('have.class', 'm-dropdown--list--item--selected'); // selected class
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.get(".m-sort-selector--period-dropdown ul > li:contains('30d')").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.get(".m-sort-selector--period-dropdown ul > li:contains('7d')").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.get(".m-sort-selector--period-dropdown ul > li:contains('24h')").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.get(".m-sort-selector--period-dropdown ul > li:contains('12h')").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)')
cy.get(".m-sort-selector--algorithm-dropdown ul > li:contains('Latest')")
.click()
.should('have.css', 'color', 'rgb(70, 144, 223)'); // selected color
.should('have.class', 'm-dropdown--list--item--selected'); // selected class
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.get(".m-sort-selector--custom-type-dropdown ul > li:contains('photo')")
.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.get(".m-sort-selector--custom-type-dropdown ul > li:contains('videocam')")
.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.get(".m-sort-selector--custom-type-dropdown ul > li:contains('subject')")
.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.get(".m-sort-selector--custom-type-dropdown ul > li:contains('people')")
.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.get(".m-sort-selector--custom-type-dropdown ul > li:contains('group_work')")
.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.get(".m-sort-selector--custom-type-dropdown ul > li:contains('all_inclusive')")
.click();
cy.url().should('not.include', '=images');
});
......@@ -108,21 +106,26 @@ context('Discovery', () => {
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();
cy.get("m-topbar--navigation--options ul > m-nsfw-selector ul > li:contains('Nudity')").click();
cy.get("m-topbar--navigation--options ul > m-nsfw-selector ul > li:contains('Pornography')").click();
cy.get("m-topbar--navigation--options ul > m-nsfw-selector ul > li:contains('Profanity')").click();
cy.get("m-topbar--navigation--options ul > m-nsfw-selector ul > li:contains('Violence and Gore')").click();
cy.get("m-topbar--navigation--options ul > m-nsfw-selector ul > li:contains('Race and Religion')").click();
cy.get("m-topbar--navigation--options ul > m-nsfw-selector ul > li:contains('Other')").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
cy.visit('/newsfeed/global/top');
cy.get('m-hashtagssidebarselector__item')
.first()
.click();
});
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')
cy.visit('/newsfeed/global/top');
cy.get('m-hashtagssidebarselector__item')
.first()
.find('.m-hashtagsSidebarSelectorList__visibility > i')
.click();
})
})
\ No newline at end of file
})
context('Groups', () => {
beforeEach(() => {
cy.login(true);
before(() => {
cy.getCookie('minds_sess')
.then((sessionCookie) => {
if (sessionCookie === null) {
return cy.login(true);
}
});
});
cy.location('pathname', { timeout: 30000 })
.should('eq', `/newsfeed/subscriptions`);
})
beforeEach(()=> {
cy.preserveCookies();
});
it('should create and edit a group', () => {
cy.server();
cy.route("POST", "**/api/v1/groups/group*").as("postGroup");
cy.get('m-group--sidebar-markers li:first-child').contains('New group').click();
cy.location('pathname').should('eq', '/groups/create');
......@@ -31,7 +40,10 @@ context('Groups', () => {
cy.get('.m-groups-save > button').contains('Create').click();
cy.wait(1000);
cy.wait('@postGroup').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.equal('success');
});
cy.get('.m-groupInfo__name').contains('test');
cy.get('.m-groupInfo__description').contains('This is a test');
......@@ -58,7 +70,9 @@ context('Groups', () => {
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();
cy.get("m-group--sidebar-markers li:contains('test group')")
.first()
.click();
// toggle the conversation
......@@ -71,8 +85,6 @@ context('Groups', () => {
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');
......@@ -82,9 +94,9 @@ context('Groups', () => {
})
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.get("m-group--sidebar-markers li:contains('test group')")
.first()
.click();
cy.server();
cy.route("POST", "**/api/v2/analytics/views/activity/*").as("view");
......@@ -93,8 +105,6 @@ context('Groups', () => {
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)');
......@@ -105,11 +115,9 @@ context('Groups', () => {
cy.get('.m-posterActionBar__PostButton').click();
cy.wait(200);
cy.scrollTo(0, '20px');
cy.wait('@view', { requestTimeout: 2000 }).then((xhr) => {
cy.wait('@view').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body).to.deep.equal({ status: 'success' });
});
......@@ -118,8 +126,6 @@ context('Groups', () => {
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();
......
context('Login', () => {
beforeEach(() => {
cy.clearCookies();
cy.visit('/')
})
......@@ -17,7 +18,7 @@ context('Login', () => {
cy.get('minds-form-login .m-btn--login').click();
cy.location('pathname', { timeout: 10000 })
cy.location('pathname')
.should('eq', '/newsfeed/subscriptions');
})
......
context('Newsfeed', () => {
beforeEach(() => {
cy.login(true);
cy.location('pathname', { timeout: 30000 })
.should('eq', '/newsfeed/subscriptions');
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 picking hashtags from the dropdown', () => {
cy.get('minds-newsfeed-poster').should('be.visible');
......@@ -20,14 +29,18 @@ context('Newsfeed', () => {
// 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();
// click away on arbitrary area.
cy.get('minds-newsfeed-poster m-hashtags-selector .minds-bg-overlay').click({force: true});
// define request
cy.get('.m-posterActionBar__PostButton').click();
//await response
cy.wait('@newsfeedPOST').then((xhr) => {
expect(xhr.status).to.equal(200);
});
cy.wait(100);
cy.get('.minds-list > minds-activity:first-child .message').contains('This is a post #art #hashtag');
cy.get('.mdl-card__supporting-text.message.m-mature-message > span').first().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');
......@@ -44,13 +57,18 @@ context('Newsfeed', () => {
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.wait('@mediaPOST').then((xhr) => {
expect(xhr.status).to.equal(200);
});
cy.get('.m-posterActionBar__PostButton').click();
cy.wait(300);
//await response
cy.wait('@newsfeedPOST').then((xhr) => {
expect(xhr.status).to.equal(200);
});
cy.get('.minds-list > minds-activity:first-child .message').contains('This is a post with an image');
// assert image
......@@ -77,7 +95,10 @@ context('Newsfeed', () => {
cy.get('.m-posterActionBar__PostButton').click();
cy.wait(100);
//await response
cy.wait('@newsfeedPOST').then((xhr) => {
expect(xhr.status).to.equal(200);
});
// 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');
......@@ -139,6 +160,7 @@ context('Newsfeed', () => {
})
it('should have a "Buy Tokens" button and it should redirect to /token', () => {
cy.visit('/');
cy.get('.m-page--sidebar--navigation a.m-page--sidebar--navigation--item:last-child span')
.contains('Buy Tokens');
......@@ -149,6 +171,8 @@ context('Newsfeed', () => {
})
it('"create blog" button in poster should redirect to /blog/edit/new', () => {
cy.visit('/');
cy.get('minds-newsfeed-poster .m-posterActionBar__CreateBlog')
.contains('Create blog')
.click();
......@@ -157,6 +181,8 @@ context('Newsfeed', () => {
})
it('clicking on "create blog" button in poster should prompt a confirm dialog and open a new blog with the currently inputted text', () => {
cy.visit('/');
cy.get('minds-newsfeed-poster textarea').type('thegreatmigration'); // TODO: fix UX issue when hashtag element is overlapping input
const stub = cy.stub();
......@@ -173,6 +199,8 @@ context('Newsfeed', () => {
})
it('should record a view when the user scrolls and an activity is visible', () => {
cy.visit('/');
cy.server();
cy.route("POST", "**/api/v2/analytics/views/activity/*").as("view");
// create the post
......@@ -180,13 +208,14 @@ context('Newsfeed', () => {
cy.get('.m-posterActionBar__PostButton').click();
cy.wait(200);
//await response
cy.wait('@newsfeedPOST').then((xhr) => {
expect(xhr.status).to.equal(200);
});
cy.scrollTo(0, '20px');
cy.wait(600);
cy.wait('@view', { requestTimeout: 2000 }).then((xhr) => {
cy.wait('@view').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body).to.deep.equal({ status: 'success' });
});
......
/**
* @author Ben Hayward
* @desc Spec tests for comment threads.
*/
import generateRandomId from '../support/utilities';
context('Notification', () => {
//secondary user for testing.
let username = '';
let password = '';
const commentText = 'test comment';
const postText = 'test comment'
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';
/**
* 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();
cy.login();
cy.post(postText);
cy.clearCookies();
});
/**
* After all log into new user and delete user.
*/
after(() => {
cy.clearCookies();
cy.login(true, username, password);
cy.deleteUser(username, password);
});
/**
* Before each test login, and visit env users channel.
* When testing, this means you will be ready to make a comment, remind etc,
* then switch users and check for the notification.
*/
beforeEach(() => {
cy.clearCookies();
cy.login(false, username, password);
cy.location('pathname')
.should('eq', '/newsfeed/subscriptions');
cy.visit(`/${Cypress.env().username}`);
});
it('should alert the user that a post has been commented on', () => {
// Comment on generated 2nd users post.
cy.get(commentButton).first().click();
cy.get(commentInput).first().type(commentText);
cy.get(postCommentButton).first().click();
cy.get(commentContent).first().contains(commentText);
// Logout, log into generated user.
cy.logout();
cy.login();
// Open their notifications
cy.get(notificationBell).click();
/**
* Notifications not working on test env.
* TODO: Check for notification - follow it
* through and check it leads to the post with postText.
*/
});
})
......@@ -24,6 +24,7 @@ context('Onboarding', () => {
const getTopic = (i) => `m-onboarding--topics > div > ul > li:nth-child(${i}) span`;
before(() => {
cy.clearCookies();
cy.visit('/login');
//type values
......
......@@ -2,19 +2,23 @@ context('Remind', () => {
const remindText = 'remind test text';
beforeEach(() => {
cy.login(true);
cy.location('pathname', { timeout: 30000 })
.should('eq', `/newsfeed/subscriptions`);
before(() => {
cy.getCookie('minds_sess')
.then((sessionCookie) => {
if (sessionCookie === null) {
return cy.login(true);
}
});
cy.visit(`/${Cypress.env().username}`);
});
//nav to channel
cy.get('.m-v2-topbar__Top minds-avatar div')
.click();
beforeEach(() => {
cy.preserveCookies();
});
it('should allow a user to remind their post', () => {
cy.server();
cy.route("POST", "**/api/v2/newsfeed/remind/*").as("postRemind");
//post
cy.post("test!!");
......@@ -30,54 +34,10 @@ context('Remind', () => {
//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)
cy.wait('@postRemind').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.equal("success");
});
});
/**
* 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');
})
before(() => {
cy.getCookie('minds_sess')
.then((sessionCookie) => {
if (sessionCookie === null) {
return cy.login(true);
}
});
});
beforeEach(()=> {
cy.preserveCookies();
});
it("clicking on the dropdown on the right should allow to go to the user's channel", () => {
// open the menu
......@@ -15,7 +21,7 @@ context('Topbar', () => {
.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
......@@ -26,41 +32,37 @@ context('Topbar', () => {
.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')
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');
})
cy.location('pathname').should('contain', '/boost/console/newsfeed/');
});
it('clicking on the dropdown on the right should allow to go to the boost console', () => {
it('clicking on the dropdown on the right should allow to go to the help desk', () => {
// 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')
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')
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
......@@ -68,8 +70,7 @@ context('Topbar', () => {
cy.get('body.m-theme__light').should('be.visible');
cy.get('m-user-menu .m-user-menu__Dropdown li')
.contains('Dark Mode')
cy.get("m-user-menu .m-user-menu__Dropdown li:contains('Dark Mode')")
.click();
cy.get('body.m-theme__dark').should('be.visible');
......@@ -79,7 +80,9 @@ context('Topbar', () => {
.click();
cy.get('body.m-theme__light').should('be.visible');
})
cy.get('m-user-menu .m-user-menu__Anchor').click({ force: true });
});
it('clicking on the bulb on the topbar should redirect to /newsfeed/subscriptions', () => {
cy.get('.m-v2-topbarNavItem__Logo img').should('be.visible');
......@@ -87,7 +90,7 @@ context('Topbar', () => {
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');
......@@ -102,5 +105,5 @@ context('Topbar', () => {
.click();
cy.location('pathname').should('eq', '/notifications');
})
});
})
......@@ -10,12 +10,21 @@ context('Wire', () => {
const sendButton = '.m-wire--creator-section--last > div > button';
const modal = 'm-overlay-modal > div.m-overlay-modal';
beforeEach(() => {
cy.login();
cy.wait(2000);
before(() => {
cy.getCookie('minds_sess')
.then((sessionCookie) => {
if (sessionCookie === null) {
return cy.login(true);
}
});
});
beforeEach(()=> {
cy.preserveCookies();
});
it('should allow a user to send a wire to another user', () => {
//TODO: Remove me when we get user to user wires working on the review environment
it.skip('should allow a user to send a wire to another user', () => {
// Visit users page.
cy.visit('/minds');
......
// ***********************************************
// 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'
});
import 'cypress-file-upload';
/**
* @author Marcelo, Ben and Brian
* @create date 2019-08-09 22:54:02
* @modify date 2019-08-09 22:54:02
* @desc Custom commands for access through cy.[cmd]();
*
* 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) => { ... })
*/
const onboarding = {
welcomeText: 'Welcome to Minds',
welcomeTextContainer: 'm-onboarding--topics > div > h2:nth-child(1)',
nextButton: '.m-channelOnboarding__next',
};
//Login and register
const registerForm = {
username: 'minds-form-register #username',
email: 'minds-form-register #email',
password: 'minds-form-register #password',
password2: 'minds-form-register #password2',
checkbox: 'minds-form-register label:nth-child(2) .mdl-ripple--center',
submitButton: 'minds-form-register .mdl-card__actions button',
};
const settings = {
deleteAccountButton: 'm-settings--disable-channel > div:nth-child(2) > div > button',
deleteSubmitButton: 'm-confirm-password--modal > div > form > div:nth-child(2) > button',
};
const nav = {
hamburgerMenu: '.m-v2-topbar__UserMenu > m-user-menu > div.m-user-menu.m-dropdown > a',
logoutButton: '.m-user-menu.m-dropdown > ul > li:nth-child(11) > a',
byIndex: (i) => `.m-user-menu.m-dropdown > ul > li:nth-child(${i}) > a`,
};
const defaults = {
email: 'test@minds.com',
}
const loginForm = {
password: 'minds-form-login .m-login-box .mdl-cell:last-child input',
username: 'minds-form-login .m-login-box .mdl-cell:first-child input',
submit: 'minds-form-login .m-btn--login',
}
const poster = {
textArea: 'm-text-input--autocomplete-container textarea',
postButton: '.m-posterActionBar__PostButton',
}
Cypress.Commands.add('login', (canary) => {
/**
* Logs a user in.
* @param { boolean } canary - Currently not required
* @param { string } username - The username.
* @param { string } password - The users password.
* @returns void
*/
Cypress.Commands.add('login', (canary = false, username, password) => {
username = username ? username : Cypress.env().username;
password = password ? password : Cypress.env().password;
cy.setCookie('staging', "1"); // Run in stagin mode. Note: does not impact review sites
cy.visit('/login');
cy.get('.m-btn--login').click();
cy.server();
cy.route("POST", "/api/v1/authenticate").as("postLogin");
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(loginForm.username).type(username);
cy.get(loginForm.password).type(password);
cy.get(loginForm.submit).click();
cy.get('minds-form-login .m-btn--login').click();
cy.wait('@postLogin').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.equal('success');
});
});
/**
* Logs a user out of their session using the menu.
* @returns void
*/
Cypress.Commands.add('logout', () => {
cy.get(nav.hamburgerMenu).click();
cy.get(nav.logoutButton).click();
});
/**
* Register a user, be sure to delete the user following this.
*
* ! LOG-OUT PRIOR TO CALLING !
*
* @param { string } username - The username. Note that the requested username will NOT be freed up upon deletion
* @param { string } password - The users password.
* @returns void
*/
Cypress.Commands.add('newUser', (username = '', password = '') => {
cy.visit('/login');
cy.location('pathname', { timeout: 30000 })
.should('eq', `/login`);
cy.server();
cy.route("POST", '**/api/v1/register').as('registerPOST');
cy.get(registerForm.username).focus().type(username);
cy.get(registerForm.email).focus().type(defaults.email);
cy.get(registerForm.password).focus().type(password);
cy.wait(500); // give second password field chance to appear - not tied to a request.
cy.get(registerForm.password2).focus().type(password);
cy.get(registerForm.checkbox).click({force: true});
//submit.
cy.get(registerForm.submitButton).click({force: true})
.wait('@registerPOST').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.deep.equal("success");
});
//onboarding modal shown.
cy.get(onboarding.welcomeTextContainer)
.contains(onboarding.welcomeText);
//skip onboarding.
cy.get(onboarding.nextButton).click()
cy.get(onboarding.nextButton).click()
cy.get(onboarding.nextButton).click()
cy.get(onboarding.nextButton).click()
});
Cypress.Commands.add('preserveCookies', () => {
Cypress.Cookies.preserveOnce('staging', 'minds_sess', 'mwa', 'XSRF-TOKEN');
});
/**
* Deletes a user. Use carefully on sandbox or you may lose your favorite test account.
*
* ! LOG-IN PRIOR TO CALLING !
*
* @param { string } username - The username. TODO: when both params provided log the user in too
* @param { string } password - The password.
* @returns void
*/
Cypress.Commands.add('deleteUser', (username, password) => {
cy.server();
cy.route("POST", '**/api/v2/settings/password/validate').as('validatePost');
cy.route("POST", '**/api/v2/settings/delete').as('deletePOST');
cy.visit('/settings/disable');
cy.location('pathname', { timeout: 30000 })
.should('eq', `/settings/disable`);
cy.get(settings.deleteAccountButton).click({ force: true });
cy.get('#password').focus().type(password);
cy.get(settings.deleteSubmitButton).click({ force: true })
.wait('@validatePost').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.deep.equal("success");
})
.wait('@deletePOST').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.deep.equal("success");
});
});
/**
* Uploads a file.
* @param { string } selector - The selector.
* @param { string } fileName - the file-name.
* @param { string } type - the file-type.
* @returns void
*/
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.fixture(fileName).then((content) => {
cy.log("Content", fileName);
cy.get(selector).upload({
fileContent: content,
fileName: fileName,
mimeType: type
});
});
// cy.get(selector).trigger('change', { force: true });
});
/**
* Creates a new post. Must be logged in.
* @param { string } message - The message to be posted
* @returns void
*/
Cypress.Commands.add('post', (message) => {
cy.get('m-text-input--autocomplete-container textarea').type(message);
cy.get('.m-posterActionBar__PostButton').click();
cy.server();
cy.route("POST", '**/v1/newsfeed**').as('postActivity');
cy.get(poster.textArea).type(message);
cy.get(poster.postButton).click();
cy.wait('@postActivity').then((xhr) => {
expect(xhr.status).to.equal(200);
expect(xhr.response.body.status).to.deep.equal("success");
});
});
/**
* Converts base64 to blob format
* @param { string } b64Data - The base64 data.
* @param { string } contentType - The type of content.
* @param { number } sliceSize - The size of the slice.
* @returns void
*/
function b64toBlob(b64Data, contentType, sliceSize = 512) {
const byteCharacters = atob(b64Data);
const byteArrays = [];
......
......@@ -18,3 +18,5 @@ import './commands'
// Alternatively you can use CommonJS syntax:
// require('./commands')
Cypress.Cookies.debug(true);
/**
* @author Ben Hayward
* @create date 2019-08-10 00:38:46
* @modify date 2019-08-10 00:38:46
* @desc Space to put utilities and helper functions without cluttering up commands.js
*/
/**
* @returns a random 21 character string
*/
const generateRandomId = () => {
return Math.random().toString(36).substring(2, 15)
+ Math.random().toString(36).substring(2, 15);
}
export default generateRandomId;