mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2024-11-30 02:56:20 -05:00
306 lines
13 KiB
JavaScript
306 lines
13 KiB
JavaScript
// These tests sign in with user #4 and user #5
|
|
|
|
import SeleniumHelper from './selenium-helpers.js';
|
|
|
|
const {
|
|
buildDriver,
|
|
clickText,
|
|
clickXpath,
|
|
containsClass,
|
|
findByXpath,
|
|
navigate,
|
|
signIn
|
|
} = new SeleniumHelper();
|
|
|
|
// Using 1 and 2 here. Hopefully this is not confusing.
|
|
const username1 = `${process.env.SMOKE_USERNAME}4`;
|
|
const username2 = `${process.env.SMOKE_USERNAME}5`;
|
|
const password = process.env.SMOKE_PASSWORD;
|
|
const rootUrl = process.env.ROOT_URL || 'https://scratch.ly';
|
|
|
|
// project for comments (owned by username2)
|
|
const projectId = process.env.COMMENT_PROJECT_ID || 1300008409;
|
|
const projectUrl = `${rootUrl}/projects/${projectId}`;
|
|
|
|
// profile for comments (username2)
|
|
const profileUrl = `${rootUrl}/users/${username2}`;
|
|
|
|
// studio for comments (hosted by username2) comments tab
|
|
const studioId = process.env.COMMENT_STUDIO_ID || 10005646;
|
|
const studioUrl = `${rootUrl}/studios/${studioId}/comments`;
|
|
|
|
// setup comments to leave
|
|
// make sure they are unique and will not be censored (avoid numbers that might look like phone numbers or other PII)
|
|
const date = new Date();
|
|
const dateString = date.toISOString();
|
|
const projectComment = `${dateString} project`;
|
|
const profileComment = `${dateString} profile`;
|
|
const studioComment = `${dateString} studio`;
|
|
|
|
const projectReply = `${projectComment} reply`;
|
|
const profileReply = `${profileComment} reply`;
|
|
const studioReply = `${studioComment} reply`;
|
|
|
|
jest.setTimeout(60000);
|
|
|
|
let driver;
|
|
|
|
describe('comment tests', () => {
|
|
beforeAll(async () => {
|
|
driver = await buildDriver('www-integration project comments');
|
|
await navigate(rootUrl);
|
|
});
|
|
|
|
afterAll(() => driver.quit());
|
|
|
|
describe('leave comments', () => {
|
|
beforeAll(async () => {
|
|
await signIn(username1, password);
|
|
await findByXpath('//span[contains(@class, "profile-name")]');
|
|
});
|
|
|
|
afterAll(async () => {
|
|
await navigate(rootUrl);
|
|
await clickXpath('//a[contains(@class, "user-info")]');
|
|
await clickText('Sign out');
|
|
});
|
|
|
|
test('leave comment on project', async () => {
|
|
await navigate(projectUrl);
|
|
|
|
// leave the comment
|
|
const commentBox = await findByXpath('//textArea[@name="compose-comment"]');
|
|
await commentBox.sendKeys(projectComment);
|
|
await findByXpath(`//textarea[contains(text(), "${projectComment}")]`);
|
|
await clickXpath('//button[@class="button compose-post"]');
|
|
|
|
// find the comment
|
|
const commentXpath = `//div[@class="comment-bubble"]/span/span[contains(text(), "${projectComment}")]`;
|
|
const postedComment = await findByXpath(commentXpath);
|
|
const commentVisible = await postedComment.isDisplayed();
|
|
expect(commentVisible).toBe(true);
|
|
});
|
|
|
|
test('leave comment on a profile', async () => {
|
|
await navigate(profileUrl);
|
|
|
|
// leave the comment
|
|
const commentXpath = '//form[@id="main-post-form"]/div/textArea';
|
|
const commentArea = await findByXpath(commentXpath);
|
|
await commentArea.sendKeys(profileComment);
|
|
await clickXpath('//div[@class="button small"]/a[contains(text(), "Post")]');
|
|
|
|
// find the comment
|
|
const newComment = await findByXpath(`//div[@class="comment "]/div/div[contains(text(),` +
|
|
` "${profileComment}")]`);
|
|
const commentVisible = await newComment.isDisplayed();
|
|
expect(commentVisible).toBe(true);
|
|
|
|
// return to homepage to sign out with www
|
|
await navigate(rootUrl);
|
|
});
|
|
|
|
test('leave comment on studio', async () => {
|
|
await navigate(studioUrl);
|
|
|
|
// leave the comment
|
|
const commentBox = await findByXpath('//textArea[@name="compose-comment"]');
|
|
await commentBox.sendKeys(studioComment);
|
|
await findByXpath(`//textarea[contains(text(), "${studioComment}")]`);
|
|
await clickXpath('//button[@class="button compose-post"]');
|
|
|
|
// find the comment
|
|
const commentXpath = `//div[@class="comment-bubble"]/span/span[contains(text(), "${studioComment}")]`;
|
|
const postedComment = await findByXpath(commentXpath);
|
|
const commentVisible = await postedComment.isDisplayed();
|
|
expect(commentVisible).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('second user tests', () => {
|
|
beforeAll(async () => {
|
|
await signIn(username2, password);
|
|
await findByXpath('//span[contains(@class, "profile-name")]');
|
|
});
|
|
|
|
// get notifications
|
|
test('get notification badge for comments', async () => {
|
|
const messages = await findByXpath('//span[@class = "message-count show"]');
|
|
const messagesVisible = await messages.isDisplayed();
|
|
expect(messagesVisible).toBe(true);
|
|
});
|
|
|
|
test('click notifications for comments', async () => {
|
|
await clickXpath('//li[@class="link right messages"]');
|
|
const messages = await findByXpath('//ul[@class="messages-social-list"]');
|
|
const messagesVisible = await messages.isDisplayed();
|
|
expect(messagesVisible).toBe(true);
|
|
});
|
|
|
|
test('project comment message visible', async () => {
|
|
await navigate(`${rootUrl}/messages`);
|
|
|
|
const projectMessageXpath = '//p[@class="emoji-text mod-comment" ' +
|
|
`and contains(text(), "${projectComment}")]`;
|
|
const projectMessage = await findByXpath(projectMessageXpath);
|
|
const projectMessageVisible = await projectMessage.isDisplayed();
|
|
expect(projectMessageVisible).toBe(true);
|
|
});
|
|
|
|
test('profile comment message visible', async () => {
|
|
await navigate(`${rootUrl}/messages`);
|
|
|
|
const profileMessageXpath = '//p[@class="emoji-text mod-comment" ' +
|
|
`and contains(text(), "${profileComment}")]`;
|
|
const profileMessage = await findByXpath(profileMessageXpath);
|
|
const profileMessageVisible = await profileMessage.isDisplayed();
|
|
expect(profileMessageVisible).toBe(true);
|
|
});
|
|
|
|
// studio comments do not send a notification
|
|
|
|
test('project message links you to project page', async () => {
|
|
const projectLinkXpath = '//p[@class="emoji-text mod-comment" ' +
|
|
`and contains(text(), "${projectComment}")]/../../../p[@class = "comment-message-info"]/span/a[2]`;
|
|
|
|
await navigate(`${rootUrl}/messages`);
|
|
await clickXpath(projectLinkXpath);
|
|
|
|
// find green flag overlay
|
|
const gfOverlay = await findByXpath('//div[@class="stage-wrapper_stage-wrapper_2bejr box_box_2jjDp"]');
|
|
await gfOverlay.isDisplayed();
|
|
});
|
|
|
|
test('project comment is on project page', async () => {
|
|
const projectLinkXpath = '//p[@class="emoji-text mod-comment" ' +
|
|
`and contains(text(), "${projectComment}")]/../../../p[@class = "comment-message-info"]/span/a[2]`;
|
|
|
|
await navigate(`${rootUrl}/messages`);
|
|
await clickXpath(projectLinkXpath);
|
|
|
|
const commentXpath = `//span[contains(text(), "${projectComment}")]`;
|
|
const singleComment = await findByXpath(commentXpath);
|
|
const commentVisible = await singleComment.isDisplayed();
|
|
expect(commentVisible).toBe(true);
|
|
});
|
|
|
|
test('project comment is highlighted', async () => {
|
|
const projectLinkXpath = '//p[@class="emoji-text mod-comment" ' +
|
|
`and contains(text(), "${projectComment}")]/../../../p[@class = "comment-message-info"]/span/a[2]`;
|
|
const containerXpath = `//span[contains(text(), "${projectComment}")]/../../../..`;
|
|
|
|
await navigate(`${rootUrl}/messages`);
|
|
await clickXpath(projectLinkXpath);
|
|
|
|
const commentContainer = await findByXpath(containerXpath);
|
|
const isHighlighted = await containsClass(commentContainer, 'highlighted-comment');
|
|
expect(isHighlighted).toBe(true);
|
|
});
|
|
|
|
test('profile message links you to profile page', async () => {
|
|
const profileLinkXpath = '//p[@class="emoji-text mod-comment" ' +
|
|
`and contains(text(), "${profileComment}")]/../../../` +
|
|
'p[@class = "comment-message-info"]/span/a[2]';
|
|
await navigate(`${rootUrl}/messages`);
|
|
await clickXpath(profileLinkXpath);
|
|
|
|
// find profile data
|
|
const profileDataXpath = '//div[@id="profile-data"]';
|
|
const pathToUsername = '/div[@class="box-head"]/div[@class="header-text"]/h2';
|
|
await findByXpath(profileDataXpath);
|
|
|
|
const header = await findByXpath(profileDataXpath + pathToUsername);
|
|
const uname = await header.getText();
|
|
expect(uname).toBe(username2);
|
|
});
|
|
|
|
test('profile comment is on profile page', async () => {
|
|
const profileLinkXpath = '//p[@class="emoji-text mod-comment" ' +
|
|
`and contains(text(), "${profileComment}")]/../../../` +
|
|
'p[@class = "comment-message-info"]/span/a[2]';
|
|
await navigate(`${rootUrl}/messages`);
|
|
await clickXpath(profileLinkXpath);
|
|
|
|
// find comment
|
|
const commentXpath = `//div[contains(text(), "${profileComment}")]`;
|
|
const leftComment = await findByXpath(commentXpath);
|
|
const commentVisible = await leftComment.isDisplayed();
|
|
expect(commentVisible).toBe(true);
|
|
|
|
});
|
|
|
|
test('profile comment is highlighted', async () => {
|
|
const profileLinkXpath = '//p[@class="emoji-text mod-comment" ' +
|
|
`and contains(text(), "${profileComment}")]/../../../` +
|
|
'p[@class = "comment-message-info"]/span/a[2]';
|
|
await navigate(`${rootUrl}/messages`);
|
|
await clickXpath(profileLinkXpath);
|
|
|
|
// comment highlighted?
|
|
const containerXpath = `//div[contains(text(), "${profileComment}")]/../../..`;
|
|
const commentContainer = await findByXpath(containerXpath);
|
|
const isHighlighted = await containsClass(commentContainer, 'highlighted');
|
|
expect(isHighlighted).toBe(true);
|
|
});
|
|
|
|
test('project: reply to comment', async () => {
|
|
await navigate(projectUrl);
|
|
const commentXpath = `//span[contains(text(), "${projectComment}")]/../..`;
|
|
const replyXpath = `${commentXpath}//span[@class = "comment-reply"]`;
|
|
await clickXpath(replyXpath);
|
|
|
|
// type reply
|
|
const replyRow = '//div[contains(@class, "comment-reply-row")]';
|
|
const replyComposeXpath = `${replyRow}//textArea[@class = "inplace-textarea"]`;
|
|
const composeBox = await findByXpath(replyComposeXpath);
|
|
await composeBox.sendKeys(projectReply);
|
|
|
|
// click post
|
|
await clickXpath(`${replyRow}//button[@class = "button compose-post"]`);
|
|
|
|
const postedReply = await findByXpath(`//span[contains(text(), "${projectReply}")]`);
|
|
const commentVisible = await postedReply.isDisplayed();
|
|
expect(commentVisible).toBe(true);
|
|
});
|
|
|
|
test('profile reply to comment', async () => {
|
|
await navigate(profileUrl);
|
|
// find the comment and click reply
|
|
const commentXpath = `//div[contains(text(), "${profileComment}")]/..`;
|
|
await clickXpath(`${commentXpath}//a[@class = "reply"]`);
|
|
|
|
// select reply box and type reply
|
|
const replyComposeBox = await findByXpath(`${commentXpath}//textArea`);
|
|
await replyComposeBox.sendKeys(profileReply);
|
|
|
|
// click post
|
|
await clickXpath(`${commentXpath}//a[contains(text(), "Post")]`);
|
|
|
|
// The reply wasn't findable by xpath after several attempts, but it seems
|
|
// better to have this much of a test
|
|
});
|
|
|
|
test('studio: reply to comment', async () => {
|
|
await navigate(studioUrl);
|
|
|
|
// find the comment and click reply
|
|
const commentXpath = `//span[contains(text(), "${studioComment}")]/../..`;
|
|
await clickXpath(`${commentXpath}//span[@class = "comment-reply"]`);
|
|
|
|
// type reply
|
|
const replyRow = '//div[contains(@class, "comment-reply-row")]';
|
|
const replyComposeXpath = `${replyRow}//textArea[@class = "inplace-textarea"]`;
|
|
const composeBox = await findByXpath(replyComposeXpath);
|
|
await composeBox.sendKeys(studioReply);
|
|
|
|
// click post
|
|
const postButton = await findByXpath(`${replyRow}//button[@class = "button compose-post"]`);
|
|
await postButton.click();
|
|
|
|
// find reply
|
|
const postedReply = await findByXpath(`//span[contains(text(), "${studioReply}")]`);
|
|
const commentVisible = await postedReply.isDisplayed();
|
|
expect(commentVisible).toBe(true);
|
|
});
|
|
});
|
|
});
|