0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-01-06 22:40:14 -05:00
ghost/apps/comments-ui/test/e2e/actions.test.ts
Kevin Ansfield 2bca5efcec Added reply button to comment replies
closes https://linear.app/tryghost/issue/PLG-221

- added `toggleParentReplyMode()` to comment component's props so clicking Reply on a reply opens the reply form on the top-level parent to emphasise we only support 1-level deep replies and avoid unexpected nesting
- adjusted conditional so "Reply" button is shown in `<CommentMenu>` when a parent is present (behind labs flag)
- updated `useLabs()` to always return an object so we don't need to add nullish checks everywhere

# Conflicts:
#	apps/comments-ui/test/e2e/actions.test.ts
2024-09-25 15:49:56 +01:00

215 lines
7.2 KiB
TypeScript

import {MockedApi, initialize, waitEditorFocused} from '../utils/e2e';
import {expect, test} from '@playwright/test';
test.describe('Actions', async () => {
let mockedApi: MockedApi;
test.beforeEach(async () => {
mockedApi = new MockedApi({});
mockedApi.setMember({});
});
test('Can like and unlike a comment', async ({page}) => {
mockedApi.addComment({
html: '<p>This is comment 1</p>'
});
mockedApi.addComment({
html: '<p>This is comment 2</p>',
liked: true,
count: {
likes: 52
}
});
mockedApi.addComment({
html: '<p>This is comment 3</p>'
});
const {frame} = await initialize({
mockedApi,
page,
publication: 'Publisher Weekly'
});
// Check like button is not filled yet
const comment = frame.getByTestId('comment-component').nth(0);
const likeButton = comment.getByTestId('like-button');
await expect(likeButton).toHaveCount(1);
const icon = likeButton.locator('svg');
await expect(icon).not.toHaveClass(/fill/);
await expect(likeButton).toHaveText('0');
// Click button
await likeButton.click();
// Check not filled
await expect(icon).toHaveClass(/fill/);
await expect(likeButton).toHaveText('1');
// Click button again
await likeButton.click();
await expect(icon).not.toHaveClass(/fill/);
await expect(likeButton).toHaveText('0');
// Check state for already liked comment
const secondComment = frame.getByTestId('comment-component').nth(1);
const likeButton2 = secondComment.getByTestId('like-button');
await expect(likeButton2).toHaveCount(1);
const icon2 = likeButton2.locator('svg');
await expect(icon2).toHaveClass(/fill/);
await expect(likeButton2).toHaveText('52');
});
test('Can reply to a comment', async ({page}) => {
mockedApi.addComment({
html: '<p>This is comment 1</p>'
});
mockedApi.addComment({
html: '<p>This is comment 2</p>',
liked: true,
count: {
likes: 52
}
});
mockedApi.addComment({
html: '<p>This is comment 3</p>'
});
const {frame} = await initialize({
mockedApi,
page,
publication: 'Publisher Weekly'
});
// Check like button is not filled yet
const comment = frame.getByTestId('comment-component').nth(0);
const replyButton = comment.getByTestId('reply-button');
await expect(replyButton).toHaveCount(1);
// Click button
await replyButton.click();
const editor = frame.getByTestId('form-editor');
await expect(editor).toBeVisible();
// Wait for focused
await waitEditorFocused(editor);
// Type some text
await page.keyboard.type('This is a reply 123');
await expect(editor).toHaveText('This is a reply 123');
// Click reply button
const submitButton = comment.getByTestId('submit-form-button');
await submitButton.click();
// Check total amount of comments increased
await expect(frame.getByTestId('comment-component')).toHaveCount(4);
await expect(frame.getByText('This is a reply 123')).toHaveCount(1);
});
test('Reply-to-reply action not shown without labs flag', async ({page}) => {
mockedApi.addComment({
html: '<p>This is comment 1</p>',
replies: [
mockedApi.buildReply({
html: '<p>This is a reply to 1</p>'
})
]
});
const {frame} = await initialize({
mockedApi,
page,
publication: 'Publisher Weekly'
});
const parentComment = frame.getByTestId('comment-component').nth(0);
const replyComment = parentComment.getByTestId('comment-component').nth(0);
expect(replyComment.getByTestId('reply-button')).not.toBeVisible();
});
test('Can reply to a reply', async ({page}) => {
mockedApi.addComment({
html: '<p>This is comment 1</p>',
replies: [
mockedApi.buildReply({
html: '<p>This is a reply to 1</p>'
})
]
});
const {frame} = await initialize({
mockedApi,
page,
publication: 'Publisher Weekly',
labs: {
commentImprovements: true
}
});
const parentComment = frame.getByTestId('comment-component').nth(0);
const replyComment = parentComment.getByTestId('comment-component').nth(0);
const replyReplyButton = replyComment.getByTestId('reply-button');
await replyReplyButton.click();
const editor = frame.getByTestId('form-editor');
await expect(editor).toBeVisible();
await waitEditorFocused(editor);
await page.keyboard.type('This is a reply to a reply');
const submitButton = parentComment.getByTestId('submit-form-button');
await submitButton.click();
await expect(frame.getByTestId('comment-component')).toHaveCount(3);
await expect(frame.getByText('This is a reply to a reply')).toHaveCount(1);
});
test('Can add expertise', async ({page}) => {
mockedApi.setMember({name: 'John Doe', expertise: null});
mockedApi.addComment({
html: '<p>This is comment 1</p>'
});
const {frame} = await initialize({
mockedApi,
page,
publication: 'Publisher Weekly'
});
const editor = frame.getByTestId('form-editor');
await editor.click({force: true});
await waitEditorFocused(editor);
const expertiseButton = frame.getByTestId('expertise-button');
await expect(expertiseButton).toBeVisible();
await expect(expertiseButton).toHaveText('·Add your expertise');
await expertiseButton.click();
const detailsFrame = page.frameLocator('iframe[title="addDetailsPopup"]');
const profileModal = detailsFrame.getByTestId('profile-modal');
await expect(profileModal).toBeVisible();
await expect(detailsFrame.getByTestId('name-input')).toHaveValue('John Doe');
await expect(detailsFrame.getByTestId('expertise-input')).toHaveValue('');
await detailsFrame.getByTestId('name-input').fill('Testy McTest');
await detailsFrame.getByTestId('expertise-input').fill('Software development');
await detailsFrame.getByTestId('save-button').click();
await expect(profileModal).not.toBeVisible();
// playwright can lose focus on the editor which hides the member details,
// re-clicking here brings the member details back into view
await editor.click({force: true});
await waitEditorFocused(editor);
await expect(frame.getByTestId('member-name')).toHaveText('Testy McTest');
await expect(frame.getByTestId('expertise-button')).toHaveText('·Software development');
});
});