Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes approach for create e2e group, adds clean old e2e groups #1809

Merged
merged 1 commit into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions e2e/common/fixture.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import { test as base } from '@playwright/test';
import { LostChangesConfirmationModal } from 'e2e/common/pages/lost-changes-confirmation-modal';
import { Toast } from 'e2e/common/pages/toast';
import { test as groupFixtures } from '../groups/create-group-fixture';

interface CommonFixtures {
lostChangesConfirmationModal: LostChangesConfirmationModal,
toast: Toast,
}

export const test = base.extend<CommonFixtures>({
export const test = groupFixtures.extend<CommonFixtures>({
lostChangesConfirmationModal: async ({ page }, use) => {
await use(new LostChangesConfirmationModal(page));
},
toast: async ({ page }, use) => {
await use(new Toast(page));
},
});

export { expect, Page } from '@playwright/test';
15 changes: 15 additions & 0 deletions e2e/common/pages/toast.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { expect, Page } from '@playwright/test';

export class Toast {
constructor(private page: Page) {
}

async checksIsMessageVisible(message: string): Promise<void> {
const toastLocator = this.page.locator('p-toast');
const successfulLocator = toastLocator.getByText(message);
await expect.soft(successfulLocator).toBeVisible();
await expect.soft(toastLocator.getByLabel('Close')).toBeVisible();
await toastLocator.getByLabel('Close').click();
await expect.soft(successfulLocator).not.toBeVisible();
}
}
56 changes: 56 additions & 0 deletions e2e/groups/clear-groups.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { test, expect } from 'e2e/common/fixture';
import { initAsTesterUser } from 'e2e/helpers/e2e_auth';
import { HOURS } from 'src/app/utils/duration';
import { apiUrl } from 'e2e/helpers/e2e_http';
import { isNotNull } from 'src/app/utils/null-undefined-predicates';

const rootGroupId = '7035186126723551198';
const rootGroupName = 'E2E-generated-groups';

test('checks old e2e groups and remove it', { tag: '@no-parallelism' }, async ({
page,
groupMembersPage,
groupSettingsPage,
toast,
}) => {
await initAsTesterUser(page);
await Promise.all([
page.goto(`groups/by-id/${rootGroupId};p=/members`),
page.waitForResponse(`${apiUrl}/groups/${rootGroupId}/navigation`),
]);
await groupMembersPage.checksIsHeaderVisible(rootGroupName);
const leftNavRootGroup = page.locator('p-treenode').filter({ has: page.getByText(rootGroupName) });
await expect.soft(leftNavRootGroup).toBeVisible();
const regExpGroup = /E2E_\d{13}/;
const leftNavFirstChild = leftNavRootGroup.getByText(regExpGroup).first();
if (!(await leftNavFirstChild.isVisible())) return;

const groupNamesForRemove = (await Promise.all((await leftNavRootGroup.getByText(regExpGroup).all())
.map(item => item.textContent())))
.filter(isNotNull)
.filter(itemName => {
const createdAtResult = itemName.match(/\d{13}/);
if (!createdAtResult) throw new Error('Unexpected: Missed createdAtResult');
const [ createdAt ] = createdAtResult;
return Date.now() - Number(createdAt) > HOURS;
});

await leftNavFirstChild.click();

for (const groupName of groupNamesForRemove) {
const leftNavGroupLocator = page.locator('p-tree').getByText(groupName).first();
Copy link
Collaborator Author

@Iloveall Iloveall Oct 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason I'm not using group locator from collection is that the collection keeps position of element (nth(n)), and so if new group will be created during process (so left menu is updated with new positions) it will be failed. That's why need to get locator by name again

await expect.soft(leftNavGroupLocator).toBeVisible();
await leftNavGroupLocator.click();
const settingsTabLocator = page.getByRole('link', { name: 'Settings' });
await expect.soft(settingsTabLocator).toBeVisible();
await settingsTabLocator.click();
await groupSettingsPage.checksIsDeleteButtonVisible();
await groupSettingsPage.checksIsDeleteButtonEnabled();
await groupSettingsPage.deleteGroup();
await groupSettingsPage.checksIsDeleteButtonDisabled();
await Promise.all([
toast.checksIsMessageVisible(`You have deleted "${ groupName }"`),
page.waitForResponse(`${apiUrl}/groups/${rootGroupId}/navigation`),
]);
}
});
15 changes: 8 additions & 7 deletions e2e/groups/create-group-fixture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ interface CreateGroupFixtures {
}

export const test = base.extend<CreateGroupFixtures>({
createGroup: async ({ manageGroupsPage }, use) => {
createGroup: async ({ page, groupMembersPage }, use) => {
const rootGroupId = '7035186126723551198';
const rootGroupName = 'E2E-generated-groups';
const groupName = `E2E_${ Date.now() }`;
await manageGroupsPage.goto();
await manageGroupsPage.checkHeaderIsVisible();
await manageGroupsPage.waitForManagedGroupsResponse();
await manageGroupsPage.checksIsManagedGroupsTableVisible();
await manageGroupsPage.checksIsCreateGroupSectionVisible();
const groupId = await manageGroupsPage.createGroup(groupName);
await page.goto(`groups/by-id/${rootGroupId};p=/members`);
await groupMembersPage.checksIsHeaderVisible(rootGroupName);
await groupMembersPage.goToTab('Sub-groups');
await groupMembersPage.checksIsAddSubGroupsSectionVisible();
const groupId = await groupMembersPage.createChild(groupName);
if (groupId) await use({ groupName, groupId });
},
deleteGroup: async ({ groupSettingsPage, minePage, createGroup }, use) => {
Expand Down
19 changes: 19 additions & 0 deletions e2e/groups/pages/group-members-page.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Page, expect } from '@playwright/test';
import { apiUrl } from 'e2e/helpers/e2e_http';

export class GroupMembersPage {
tabsLocator = this.page.locator('alg-selection');
Expand Down Expand Up @@ -64,4 +65,22 @@ export class GroupMembersPage {
await expect.soft(this.rejectConfirmationBtnLocator).toBeVisible();
await this.rejectConfirmationBtnLocator.click();
}

async checksIsAddSubGroupsSectionVisible(): Promise<void> {
await expect.soft(this.page.getByText('Add subgroups')).toBeVisible();
}

async createChild(name: string): Promise<string | undefined> {
const inputLocator = this.page.getByPlaceholder('Enter a title to create a new child');
await expect.soft(inputLocator).toBeVisible();
await inputLocator.fill(name);
const classBtnLocator = this.page.locator('alg-add-content').getByText('Class');
await expect.soft(classBtnLocator).toBeVisible();
await classBtnLocator.click();
const response = await this.page.waitForResponse(`${apiUrl}/groups`);
await expect.soft(this.page.getByText('Group successfully added')).toBeVisible();
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const jsonResponse: { data: { id: string | undefined } | undefined } = await response.json();
return jsonResponse.data?.id;
}
}
8 changes: 8 additions & 0 deletions e2e/groups/pages/group-settings-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,14 @@ export class GroupSettingsPage {
await expect.soft(this.deleteGroupBtnLocator).toBeVisible();
}

async checksIsDeleteButtonEnabled(): Promise<void> {
await expect.soft(this.deleteGroupBtnLocator).toBeEnabled();
}

async checksIsDeleteButtonDisabled(): Promise<void> {
await expect.soft(this.deleteGroupBtnLocator).toBeDisabled();
}

async deleteGroup(): Promise<void> {
await this.deleteGroupBtnLocator.click();
await expect.soft(this.page.getByText('Confirm Action')).toBeVisible();
Expand Down
28 changes: 0 additions & 28 deletions e2e/groups/pages/manage-groups-page.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { expect, Page } from '@playwright/test';
import { apiUrl } from 'e2e/helpers/e2e_http';

export class ManageGroupsPage {

Expand Down Expand Up @@ -29,31 +28,4 @@ export class ManageGroupsPage {
this.page.getByText('You need to be logged in to manage and create groups')
).toBeVisible();
}

async waitForManagedGroupsResponse(): Promise<void> {
await this.page.waitForResponse(`${apiUrl}/current-user/managed-groups`);
}

async checksIsManagedGroupsTableVisible(): Promise<void> {
await expect.soft(this.page.locator('alg-managed-group-list').filter({ has: this.page.getByRole('table') })).toBeVisible();
}

async checksIsCreateGroupSectionVisible(): Promise<void> {
await expect.soft(this.page.getByText('Create a new group')).toBeVisible();
}

async createGroup(name: string): Promise<string | undefined> {
const inputLocator = this.page.getByPlaceholder('Enter a title to create a new group');
await expect.soft(inputLocator).toBeVisible();
await inputLocator.fill(name);
const classBtnLocator = this.page.locator('alg-add-content').getByText('Class');
await expect.soft(classBtnLocator).toBeVisible();
await classBtnLocator.click();
const response = await this.page.waitForResponse(`${apiUrl}/groups`);
await expect.soft(this.page.getByText('Group successfully created')).toBeVisible();
await expect.soft(this.page.getByRole('heading', { name })).toBeVisible();
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const jsonResponse: { data: { id: string | undefined } | undefined } = await response.json();
return jsonResponse.data?.id;
}
}