From f7136edc271cbb7f50c7dfe434d59c7e11771cd3 Mon Sep 17 00:00:00 2001 From: Cheryl Tang Date: Tue, 17 Sep 2024 10:02:37 -0700 Subject: [PATCH] LPD-22768 Add new Playwright test and test fixes --- .../js/components/TimelineDropdownMenu.js | 9 +- .../changeTrackingTimeline.spec.ts | 96 +++++++++++------- .../changeTrackingTimelineModal.spec.ts | 99 ++++++++++++++++--- 3 files changed, 150 insertions(+), 54 deletions(-) diff --git a/modules/apps/change-tracking/change-tracking-web/src/main/resources/META-INF/resources/publications/js/components/TimelineDropdownMenu.js b/modules/apps/change-tracking/change-tracking-web/src/main/resources/META-INF/resources/publications/js/components/TimelineDropdownMenu.js index 213638fd1e1fa..3e80026f7c72b 100644 --- a/modules/apps/change-tracking/change-tracking-web/src/main/resources/META-INF/resources/publications/js/components/TimelineDropdownMenu.js +++ b/modules/apps/change-tracking/change-tracking-web/src/main/resources/META-INF/resources/publications/js/components/TimelineDropdownMenu.js @@ -72,14 +72,16 @@ export function createMoveURL( export function createViewURL( ctCollectionId, namespace, - timelineItemCtEntryId + timelineClassNameId, + timelineClassPK ) { return createMVCRenderCommandURL( ctCollectionId, '/change_tracking/view_change', namespace, { - ctEntryId: timelineItemCtEntryId, + modelClassNameId: timelineClassNameId, + modelClassPK: timelineClassPK, } ); } @@ -121,7 +123,8 @@ export default function TimelineDropdownMenu({ const viewURL = createViewURL( ctCollectionId, namespace, - timelineItem.ctEntryId + timelineClassNameId, + timelineClassPK ); if ( diff --git a/modules/test/playwright/tests/change-tracking-web/changeTrackingTimeline.spec.ts b/modules/test/playwright/tests/change-tracking-web/changeTrackingTimeline.spec.ts index 06ad85f8364dd..646e4b2423290 100644 --- a/modules/test/playwright/tests/change-tracking-web/changeTrackingTimeline.spec.ts +++ b/modules/test/playwright/tests/change-tracking-web/changeTrackingTimeline.spec.ts @@ -83,22 +83,26 @@ test('LPD-25853 Edit in x publication is added in the timeline dropdown actions' await documentLibraryPage.goToEditFileEntry(title1); - await page.getByLabel('timeline-button').click(); + const timelineButton = page.getByLabel('timeline-button'); + await timelineButton.waitFor(); + await timelineButton.click(); const timelineActionsButton = page.locator('.publication-timeline button'); - await timelineActionsButton.waitFor(); - await timelineActionsButton.click(); const editButton = page.getByRole('button', { name: `Edit in ${ctCollection.name}`, }); - + await editButton.waitFor(); await expect(editButton).toBeVisible(); - await editButton.click(); + await page + .locator('.change-tracking-indicator-title') + .filter({hasText: ctCollection.name}) + .waitFor(); + await expect( page .locator('.change-tracking-indicator-title') @@ -107,6 +111,7 @@ test('LPD-25853 Edit in x publication is added in the timeline dropdown actions' }); test('LPD-25853 Review Change is added in the timeline dropdown actions', async ({ + apiHelpers, ctCollection, documentLibraryPage, page, @@ -116,20 +121,28 @@ test('LPD-25853 Review Change is added in the timeline dropdown actions', async await documentLibraryPage.goToEditFileEntry(title2); - await page.getByLabel('timeline-button').click(); + const timelineButton = page.getByLabel('timeline-button'); + await timelineButton.waitFor(); + await timelineButton.click(); const timelineActionsButton = page.locator('.publication-timeline button'); - await timelineActionsButton.waitFor(); - await timelineActionsButton.click(); - const reviewButton = page.getByRole('button', {name: 'Review Change'}); - + const reviewButton = (await apiHelpers.featureFlag.isFeatureFlagEnabled( + 'LPD-20556' + )) + ? page.getByRole('button', {name: 'Review Change'}) + : page.getByRole('button', {name: 'Review Changes'}); + await reviewButton.waitFor(); await expect(reviewButton).toBeVisible(); - await reviewButton.click(); + await page + .locator('.publication-name') + .filter({hasText: ctCollection.name}) + .waitFor(); + await expect( page.locator('.publication-name').filter({hasText: ctCollection.name}) ).toBeVisible(); @@ -146,20 +159,21 @@ test('LPD-25853 Discard Change is added in the timeline dropdown actions', async await documentLibraryPage.goToEditFileEntry(title2); - await page.getByLabel('timeline-button').click(); + const timelineButton = page.getByLabel('timeline-button'); + await timelineButton.waitFor(); + await timelineButton.click(); const timelineActionsButton = page.locator('.publication-timeline button'); - await timelineActionsButton.waitFor(); - await timelineActionsButton.click(); const discardButton = page.getByRole('button', {name: 'Discard'}); - + await discardButton.waitFor(); await expect(discardButton).toBeVisible(); - await discardButton.click(); + await page.getByText('Discard Changes').waitFor(); + await expect(page.getByText('Discard Changes')).toBeVisible(); }); @@ -172,20 +186,21 @@ test('LPD-25853 Move Change is added in the timeline dropdown actions', async ({ await documentLibraryPage.goToEditFileEntry(title2); - await page.getByLabel('timeline-button').click(); + const timelineButton = page.getByLabel('timeline-button'); + await timelineButton.waitFor(); + await timelineButton.click(); const timelineActionsButton = page.locator('.publication-timeline button'); - await timelineActionsButton.waitFor(); - await timelineActionsButton.click(); const moveButton = page.getByRole('button', {name: 'Move'}); - + await moveButton.waitFor(); await expect(moveButton).toBeVisible(); - await moveButton.click(); + await page.getByText('Move Changes').waitFor(); + await expect(page.getByText('Move Changes')).toBeVisible(); }); @@ -257,9 +272,13 @@ test('LPD-25853 Timeline actions are not visible to user without permissions', a await documentLibraryPage.goto(site.friendlyUrlPath); - await page.getByRole('link', {exact: true, name: title1}).click(); + const dlFileEntryLink = page.getByRole('link', {exact: true, name: title1}); + await dlFileEntryLink.waitFor(); + await dlFileEntryLink.click(); - await page.getByLabel('timeline-button').click(); + const timelineButton = page.getByLabel('timeline-button'); + await timelineButton.waitFor(); + await timelineButton.click(); await page.getByText(ctCollection.name).waitFor(); @@ -299,21 +318,20 @@ test('LPD-26155 Conflict warning is visible when content is edited in more than ); const timelineButton = page.locator('.change-tracking-timeline-button svg'); - + await timelineButton.waitFor(); await expect(timelineButton).toHaveCSS('color', 'rgb(255, 182, 141)'); - await timelineButton.click(); const conflictWarning = page.locator( '.publication-timeline .alert-warning' ); - + await conflictWarning.waitFor(); await expect(conflictWarning).toBeVisible(); let conflictIcon = page.locator( '.publication-timeline .change-tracking-conflict-icon-warning' ); - + await conflictIcon.first().waitFor(); await expect(conflictIcon).toHaveCount(2); await apiHelpers.featureFlag.updateFeatureFlag('LPD-20556', false); @@ -322,10 +340,12 @@ test('LPD-26155 Conflict warning is visible when content is edited in more than await documentLibraryPage.goto(site.friendlyUrlPath); - await page.getByRole('link', {exact: true, name: title3}).click(); + const dlFileEntryLink = page.getByRole('link', {exact: true, name: title3}); + await dlFileEntryLink.waitFor(); + await dlFileEntryLink.click(); conflictIcon = page.locator('.change-tracking-conflict-icon-warning'); - + await conflictIcon.first().waitFor(); await expect(conflictIcon).toBeVisible(); await apiHelpers.headlessChangeTracking.deleteCTCollection( @@ -364,12 +384,13 @@ test('LPD-26155 Production conflict info is visible when new changes have been m const prodConflictIcon = page.locator( '.change-tracking-conflict-icon-danger' ); - + await prodConflictIcon.waitFor(); await expect(prodConflictIcon).toBeVisible(); - await prodConflictIcon.click(); - await expect(page.getByText('Production Conflict')).toBeVisible(); + const prodConflictText = page.getByText('Production Conflict'); + await prodConflictText.waitFor(); + await expect(prodConflictText).toBeVisible(); await apiHelpers.featureFlag.updateFeatureFlag('LPD-20556', false); @@ -377,8 +398,11 @@ test('LPD-26155 Production conflict info is visible when new changes have been m await documentLibraryPage.goto(site.friendlyUrlPath); - await page.getByRole('link', {exact: true, name: title2}).click(); + const dlFileEntryLink = page.getByRole('link', {exact: true, name: title2}); + await dlFileEntryLink.waitFor(); + await dlFileEntryLink.click(); + await prodConflictIcon.waitFor(); await expect(prodConflictIcon).toBeVisible(); }); @@ -392,9 +416,11 @@ test('LPD-26155 No conflict icon is visible when there are no conflictsn', async await documentLibraryPage.goto(site.friendlyUrlPath); - await page.getByRole('link', {exact: true, name: title2}).click(); + const dlFileEntryLink = page.getByRole('link', {exact: true, name: title2}); + await dlFileEntryLink.waitFor(); + await dlFileEntryLink.click(); const noConflictIcon = page.locator('.change-tracking-conflict-icon'); - + await noConflictIcon.waitFor(); await expect(noConflictIcon).toBeVisible(); }); diff --git a/modules/test/playwright/tests/change-tracking-web/changeTrackingTimelineModal.spec.ts b/modules/test/playwright/tests/change-tracking-web/changeTrackingTimelineModal.spec.ts index f3a692f93c8ee..78a192912be7b 100644 --- a/modules/test/playwright/tests/change-tracking-web/changeTrackingTimelineModal.spec.ts +++ b/modules/test/playwright/tests/change-tracking-web/changeTrackingTimelineModal.spec.ts @@ -19,12 +19,13 @@ export const test = mergeTests( changeTrackingPagesTest, featureFlagsTest({ 'LPD-20556': true, + 'LPS-171364': true, }), journalPagesTest ); -const publicationCount = 8; -const ctCollections = []; +const publicationCount = 6; +let ctCollections = []; let articleTitle: string; test.beforeEach( @@ -39,6 +40,7 @@ test.beforeEach( articleTitle = 'Test ' + getRandomInt() + ' WC Article'; await journalEditArticlePage.goto(); + await page.locator('div[data-qa-id="content"]').waitFor(); await journalEditArticlePage.fillTitle(articleTitle); await page.getByRole('button', {name: 'Publish'}).click(); await waitForSuccessAlert( @@ -47,7 +49,9 @@ test.beforeEach( ); const ctCollectionNamePrefix = getRandomString(); - for (let i = 0; i < publicationCount; i++) { + ctCollections = []; + + for (let i = 0; i <= publicationCount; i++) { const ctCollectionName = ctCollectionNamePrefix + ' ' + i; const newCTCollection = @@ -59,13 +63,15 @@ test.beforeEach( await changeTrackingPage.workOnPublication(newCTCollection); - if (i !== publicationCount - 1) { + if (i !== publicationCount) { await journalPage.goto(); await page .getByRole('heading', { name: 'Web Content', }) .waitFor(); + await page.getByLabel(`Actions for ${articleTitle}`).waitFor(); + await journalPage.goToJournalArticleAction( 'Delete', articleTitle @@ -91,16 +97,26 @@ test.afterEach(async ({apiHelpers, changeTrackingPage, journalPage, page}) => { await journalPage.goto(); await page.getByRole('heading', {name: 'Web Content'}).waitFor(); await journalPage.goToJournalArticleAction('Delete', articleTitle); + await waitForSuccessAlert( + page, + `Success: The element ${articleTitle} was moved to the Recycle Bin.` + ); }); -const getEntityHistoryModalLocator = (page: Page) => { - return page.locator('.entity-history-modal'); +const getEntityHistoryTableLocator = (page: Page) => { + return page.frameLocator( + 'iframe[title="View Entity Modification History"]' + ); }; const getPublicationTimelineLocator = (page: Page) => { return page.locator('.publication-timeline'); }; +const getPublicationTimelineButton = (page: Page) => { + return page.locator('.change-tracking-timeline-button'); +}; + const goToPublicationTimelineModal = async ( page: Page, journalPage: JournalPage @@ -110,17 +126,28 @@ const goToPublicationTimelineModal = async ( await journalPage.goToJournalArticleAction('Edit', articleTitle); await page.getByRole('tab', {name: 'Properties'}).waitFor(); - await page.locator('.change-tracking-timeline-button').click(); + const timelineButton = getPublicationTimelineButton(page); + await timelineButton.waitFor(); + await timelineButton.click(); const publicationTimelineLocator = getPublicationTimelineLocator(page); - - await publicationTimelineLocator.getByText('Modified').first().waitFor(); await publicationTimelineLocator - .getByRole('button', {name: 'View More'}) - .click(); + .locator('li .dropdown-item') + .first() + .waitFor(); - await getEntityHistoryModalLocator(page) - .getByRole('heading', {name: 'View All History'}) + const timelineViewMoreButton = publicationTimelineLocator.getByRole( + 'button', + {name: 'View More'} + ); + await timelineViewMoreButton.waitFor(); + await timelineViewMoreButton.click(); + + await page + .locator( + '#_com_liferay_change_tracking_web_portlet_PublicationsPortlet_publication-timeline-history-modal' + ) + .getByRole('heading', {name: 'View Entity Modification History'}) .waitFor(); }; @@ -130,13 +157,53 @@ test('LPD-22759 Allow users to view the entire history of an entity in a popup m }) => { await goToPublicationTimelineModal(page, journalPage); + const entityHistoryModalLocator = getEntityHistoryTableLocator(page); + await entityHistoryModalLocator.getByText(ctCollections[0].name).waitFor(); + for (let i = 0; i < ctCollections.length; i++) { if (i !== ctCollections.length - 1) { await expect( - getEntityHistoryModalLocator(page).getByText( - ctCollections[i].name - ) + entityHistoryModalLocator.getByText(ctCollections[i].name) ).toBeVisible(); } } }); + +test('LPD-22768 Add options to interact with the same entity in other publications via a popup modal', async ({ + journalPage, + page, +}) => { + await goToPublicationTimelineModal(page, journalPage); + + const entityHistoryModalLocator = getEntityHistoryTableLocator(page); + await entityHistoryModalLocator.getByText(ctCollections[0].name).waitFor(); + + const firstDropdown = entityHistoryModalLocator + .locator('.item-actions .dropdown svg.lexicon-icon-ellipsis-v') + .first(); + await firstDropdown.waitFor(); + await firstDropdown.click(); + + await entityHistoryModalLocator + .locator('div.dropdown-menu.show li') + .first() + .waitFor(); + + await expect( + entityHistoryModalLocator.getByRole('menuitem', {name: 'Discard'}) + ).toBeVisible(); + + await expect( + entityHistoryModalLocator.getByRole('menuitem', { + name: 'Edit in Publication', + }) + ).toBeVisible(); + + await expect( + entityHistoryModalLocator.getByRole('menuitem', {name: 'Move Changes'}) + ).toBeVisible(); + + await expect( + entityHistoryModalLocator.getByRole('menuitem', {name: 'Review Change'}) + ).toBeVisible(); +});