mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-08-27 10:26:09 +00:00
migrated team-drag-drop spec in playwright (#17780)
* migrated team-drag-drop spec in playwright * remove the cypress file since the migration is done (cherry picked from commit 5cb897fc28230f99b41915999e8622116df1419e)
This commit is contained in:
parent
cee82c86eb
commit
d2812be370
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright 2024 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const dataTransfer = new DataTransfer();
|
||||
|
||||
export const dragAndDropElement = (
|
||||
dragElement: string,
|
||||
dropTarget: string,
|
||||
isHeader?: boolean
|
||||
) => {
|
||||
cy.get(`[data-row-key="${Cypress.$.escapeSelector(dragElement)}"]`)
|
||||
.invoke('attr', 'draggable')
|
||||
.should('contain', 'true');
|
||||
|
||||
cy.get(`[data-row-key="${Cypress.$.escapeSelector(dragElement)}"]`).trigger(
|
||||
'dragstart',
|
||||
{
|
||||
dataTransfer,
|
||||
}
|
||||
);
|
||||
|
||||
cy.get(
|
||||
isHeader
|
||||
? dropTarget
|
||||
: `[data-row-key="${Cypress.$.escapeSelector(dropTarget)}"]`
|
||||
)
|
||||
.trigger('drop', { dataTransfer })
|
||||
.trigger('dragend', { force: true });
|
||||
};
|
||||
|
||||
export const openDragDropDropdown = (name: string) => {
|
||||
cy.get(
|
||||
`[data-row-key=${name}] > .whitespace-nowrap > [data-testid="expand-icon"] > svg`
|
||||
).click();
|
||||
};
|
@ -1,183 +0,0 @@
|
||||
/*
|
||||
* Copyright 2024 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { interceptURL, toastNotification } from '../../common/common';
|
||||
import {
|
||||
dragAndDropElement,
|
||||
openDragDropDropdown,
|
||||
} from '../../common/Utils/DragAndDrop';
|
||||
import {
|
||||
addTeam,
|
||||
commonTeamDetails,
|
||||
confirmationDragAndDropTeam,
|
||||
deleteTeamPermanently,
|
||||
} from '../../common/Utils/Teams';
|
||||
import { uuid } from '../../constants/constants';
|
||||
import { GlobalSettingOptions } from '../../constants/settings.constant';
|
||||
|
||||
const teamNameGroup = `team-ct-test-${uuid()}`;
|
||||
const teamNameBusiness = `team-ct-test-${uuid()}`;
|
||||
const teamNameDivision = `team-ct-test-${uuid()}`;
|
||||
const teamNameDepartment = `team-ct-test-${uuid()}`;
|
||||
|
||||
const TEAM_TYPE_BY_NAME = {
|
||||
[teamNameBusiness]: 'BusinessUnit',
|
||||
[teamNameDivision]: 'Division',
|
||||
[teamNameDepartment]: 'Department',
|
||||
[teamNameGroup]: 'Group',
|
||||
};
|
||||
|
||||
const DRAG_AND_DROP_TEAM_DETAILS = [
|
||||
{
|
||||
name: teamNameBusiness,
|
||||
updatedName: `${teamNameBusiness}-updated`,
|
||||
teamType: 'BusinessUnit',
|
||||
description: `This is ${teamNameBusiness} description`,
|
||||
...commonTeamDetails,
|
||||
},
|
||||
{
|
||||
name: teamNameDivision,
|
||||
updatedName: `${teamNameDivision}-updated`,
|
||||
teamType: 'Division',
|
||||
description: `This is ${teamNameDivision} description`,
|
||||
...commonTeamDetails,
|
||||
},
|
||||
{
|
||||
name: teamNameDepartment,
|
||||
updatedName: `${teamNameDepartment}-updated`,
|
||||
teamType: 'Department',
|
||||
description: `This is ${teamNameDepartment} description`,
|
||||
...commonTeamDetails,
|
||||
},
|
||||
{
|
||||
name: teamNameGroup,
|
||||
updatedName: `${teamNameGroup}-updated`,
|
||||
teamType: 'Group',
|
||||
description: `This is ${teamNameGroup} description`,
|
||||
...commonTeamDetails,
|
||||
},
|
||||
];
|
||||
|
||||
describe(
|
||||
'Teams drag and drop should work properly',
|
||||
{ tags: 'Settings' },
|
||||
() => {
|
||||
beforeEach(() => {
|
||||
interceptURL('GET', `/api/v1/users?fields=*`, 'getUserDetails');
|
||||
interceptURL('GET', `/api/v1/permissions/team/name/*`, 'permissions');
|
||||
cy.login();
|
||||
|
||||
// Clicking on teams
|
||||
cy.settingClick(GlobalSettingOptions.TEAMS);
|
||||
});
|
||||
|
||||
before(() => {
|
||||
cy.login();
|
||||
// Clicking on teams
|
||||
cy.settingClick(GlobalSettingOptions.TEAMS);
|
||||
|
||||
DRAG_AND_DROP_TEAM_DETAILS.map((team) => {
|
||||
addTeam(team);
|
||||
cy.reload();
|
||||
// asserting the added values
|
||||
cy.get(`[data-row-key="${team.name}"]`)
|
||||
.scrollIntoView()
|
||||
.should('be.visible');
|
||||
cy.get(`[data-row-key="${team.name}"]`).should(
|
||||
'contain',
|
||||
team.description
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
cy.login();
|
||||
// Clicking on teams
|
||||
cy.settingClick(GlobalSettingOptions.TEAMS);
|
||||
|
||||
[
|
||||
teamNameBusiness,
|
||||
teamNameDivision,
|
||||
teamNameDepartment,
|
||||
teamNameGroup,
|
||||
].map((teamName) => {
|
||||
deleteTeamPermanently(teamName);
|
||||
});
|
||||
});
|
||||
|
||||
it('Should fail when drop team type is Group', () => {
|
||||
[teamNameBusiness, teamNameDepartment, teamNameDivision].map((team) => {
|
||||
dragAndDropElement(team, teamNameGroup);
|
||||
toastNotification(
|
||||
`You cannot move to this team as Team Type ${TEAM_TYPE_BY_NAME[team]} can't be Group children`
|
||||
);
|
||||
|
||||
cy.get('.Toastify__toast-body', { timeout: 10000 }).should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
it('Should fail when droppable team type is Department', () => {
|
||||
[teamNameBusiness, teamNameDivision].map((team) => {
|
||||
dragAndDropElement(team, teamNameDepartment);
|
||||
toastNotification(
|
||||
`You cannot move to this team as Team Type ${TEAM_TYPE_BY_NAME[team]} can't be Department children`
|
||||
);
|
||||
cy.get('.Toastify__toast-body', { timeout: 10000 }).should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
it('Should fail when draggable team type is BusinessUnit and droppable team type is Division', () => {
|
||||
dragAndDropElement(teamNameBusiness, teamNameDivision);
|
||||
toastNotification(
|
||||
`You cannot move to this team as Team Type BusinessUnit can't be Division children`
|
||||
);
|
||||
});
|
||||
|
||||
[teamNameBusiness, teamNameDivision, teamNameDepartment].map(
|
||||
(droppableTeamName, index) => {
|
||||
it(`Should drag and drop on ${TEAM_TYPE_BY_NAME[droppableTeamName]} team type`, () => {
|
||||
// nested team will be shown once anything is moved under it
|
||||
if (index !== 0) {
|
||||
openDragDropDropdown(
|
||||
[teamNameBusiness, teamNameDivision, teamNameDepartment][
|
||||
index - 1
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
dragAndDropElement(teamNameGroup, droppableTeamName);
|
||||
|
||||
confirmationDragAndDropTeam(teamNameGroup, droppableTeamName);
|
||||
|
||||
// verify the team is moved under the business team
|
||||
openDragDropDropdown(droppableTeamName);
|
||||
cy.get(
|
||||
`.ant-table-row-level-1[data-row-key="${teamNameGroup}"]`
|
||||
).should('be.visible');
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
it(`Should drag and drop team on table level`, () => {
|
||||
// open department team dropdown as it is moved under it from last test
|
||||
openDragDropDropdown(teamNameDepartment);
|
||||
|
||||
dragAndDropElement(teamNameGroup, '.ant-table-thead > tr', true);
|
||||
confirmationDragAndDropTeam(teamNameGroup, 'Organization');
|
||||
|
||||
// verify the team is moved under the table level
|
||||
cy.get(`.ant-table-row-level-0[data-row-key="${teamNameGroup}"]`)
|
||||
.scrollIntoView()
|
||||
.should('be.visible');
|
||||
});
|
||||
}
|
||||
);
|
@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Copyright 2024 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { expect, test } from '@playwright/test';
|
||||
import { GlobalSettingOptions } from '../../constant/settings';
|
||||
import {
|
||||
redirectToHomePage,
|
||||
toastNotification,
|
||||
uuid,
|
||||
} from '../../utils/common';
|
||||
import {
|
||||
confirmationDragAndDropTeam,
|
||||
dragAndDropElement,
|
||||
openDragDropDropdown,
|
||||
} from '../../utils/dragDrop';
|
||||
import { settingClick } from '../../utils/sidebar';
|
||||
import { addTeamHierarchy, hardDeleteTeam } from '../../utils/team';
|
||||
|
||||
// use the admin user to login
|
||||
test.use({ storageState: 'playwright/.auth/admin.json' });
|
||||
|
||||
test.describe.configure({ mode: 'serial' });
|
||||
|
||||
const commonTeamDetails = {
|
||||
username: 'Aaron Johnson',
|
||||
userId: 'aaron_johnson0',
|
||||
assetname: 'dim_address',
|
||||
email: 'team1@gmail.com',
|
||||
updatedEmail: 'updatedemail@gmail.com',
|
||||
};
|
||||
|
||||
const teamNameGroup = `team-ct-test-${uuid()}`;
|
||||
const teamNameBusiness = `team-ct-test-${uuid()}`;
|
||||
const teamNameDivision = `team-ct-test-${uuid()}`;
|
||||
const teamNameDepartment = `team-ct-test-${uuid()}`;
|
||||
|
||||
const TEAM_TYPE_BY_NAME = {
|
||||
[teamNameBusiness]: 'BusinessUnit',
|
||||
[teamNameDivision]: 'Division',
|
||||
[teamNameDepartment]: 'Department',
|
||||
[teamNameGroup]: 'Group',
|
||||
};
|
||||
|
||||
const teams = [teamNameBusiness, teamNameDivision, teamNameDepartment];
|
||||
|
||||
const DRAG_AND_DROP_TEAM_DETAILS = [
|
||||
{
|
||||
name: teamNameBusiness,
|
||||
updatedName: `${teamNameBusiness}-updated`,
|
||||
teamType: 'BusinessUnit',
|
||||
description: `This is ${teamNameBusiness} description`,
|
||||
...commonTeamDetails,
|
||||
},
|
||||
{
|
||||
name: teamNameDivision,
|
||||
updatedName: `${teamNameDivision}-updated`,
|
||||
teamType: 'Division',
|
||||
description: `This is ${teamNameDivision} description`,
|
||||
...commonTeamDetails,
|
||||
},
|
||||
{
|
||||
name: teamNameDepartment,
|
||||
updatedName: `${teamNameDepartment}-updated`,
|
||||
teamType: 'Department',
|
||||
description: `This is ${teamNameDepartment} description`,
|
||||
...commonTeamDetails,
|
||||
},
|
||||
{
|
||||
name: teamNameGroup,
|
||||
updatedName: `${teamNameGroup}-updated`,
|
||||
teamType: 'Group',
|
||||
description: `This is ${teamNameGroup} description`,
|
||||
...commonTeamDetails,
|
||||
},
|
||||
];
|
||||
|
||||
test.describe('Teams drag and drop should work properly', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await redirectToHomePage(page);
|
||||
|
||||
const getOrganizationResponse = page.waitForResponse(
|
||||
'/api/v1/teams/name/*'
|
||||
);
|
||||
const permissionResponse = page.waitForResponse(
|
||||
'/api/v1/permissions/team/name/*'
|
||||
);
|
||||
|
||||
await settingClick(page, GlobalSettingOptions.TEAMS);
|
||||
await permissionResponse;
|
||||
await getOrganizationResponse;
|
||||
});
|
||||
|
||||
test('Add teams in hierarchy', async ({ page }) => {
|
||||
for (const teamDetails of DRAG_AND_DROP_TEAM_DETAILS) {
|
||||
const getOrganizationResponse = page.waitForResponse(
|
||||
'/api/v1/teams/name/*'
|
||||
);
|
||||
await addTeamHierarchy(page, teamDetails);
|
||||
await getOrganizationResponse;
|
||||
|
||||
expect(
|
||||
page.locator(`[data-row-key="${teamDetails.name}"]`)
|
||||
).toContainText(teamDetails.description);
|
||||
}
|
||||
});
|
||||
|
||||
test('Should fail when drop team type is Group', async ({ page }) => {
|
||||
for (const team of teams) {
|
||||
await dragAndDropElement(page, team, teamNameGroup);
|
||||
await toastNotification(
|
||||
page,
|
||||
`You cannot move to this team as Team Type ${TEAM_TYPE_BY_NAME[team]} can't be Group children`
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
test('Should fail when droppable team type is Department', async ({
|
||||
page,
|
||||
}) => {
|
||||
const teams = [teamNameBusiness, teamNameDivision];
|
||||
|
||||
for (const team of teams) {
|
||||
await dragAndDropElement(page, team, teamNameDepartment);
|
||||
await toastNotification(
|
||||
page,
|
||||
`You cannot move to this team as Team Type ${TEAM_TYPE_BY_NAME[team]} can't be Department children`
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
test('Should fail when draggable team type is BusinessUnit and droppable team type is Division', async ({
|
||||
page,
|
||||
}) => {
|
||||
await dragAndDropElement(page, teamNameBusiness, teamNameDivision);
|
||||
await toastNotification(
|
||||
page,
|
||||
"You cannot move to this team as Team Type BusinessUnit can't be Division children"
|
||||
);
|
||||
});
|
||||
|
||||
for (const [index, droppableTeamName] of teams.entries()) {
|
||||
test(`Should drag and drop on ${TEAM_TYPE_BY_NAME[droppableTeamName]} team type`, async ({
|
||||
page,
|
||||
}) => {
|
||||
// Nested team will be shown once anything is moved under it
|
||||
if (index !== 0) {
|
||||
await openDragDropDropdown(page, teams[index - 1]);
|
||||
}
|
||||
|
||||
await dragAndDropElement(page, teamNameGroup, droppableTeamName);
|
||||
await confirmationDragAndDropTeam(page, teamNameGroup, droppableTeamName);
|
||||
|
||||
// Verify the team is moved under the business team
|
||||
await openDragDropDropdown(page, droppableTeamName);
|
||||
const movedTeam = page.locator(
|
||||
`.ant-table-row-level-1[data-row-key="${teamNameGroup}"]`
|
||||
);
|
||||
|
||||
await expect(movedTeam).toBeVisible();
|
||||
});
|
||||
}
|
||||
|
||||
test(`Should drag and drop team on table level`, async ({ page }) => {
|
||||
// Open department team dropdown as it is moved under it from last test
|
||||
await openDragDropDropdown(page, teamNameDepartment);
|
||||
|
||||
await dragAndDropElement(
|
||||
page,
|
||||
teamNameGroup,
|
||||
'.ant-table-thead > tr',
|
||||
true
|
||||
);
|
||||
await confirmationDragAndDropTeam(page, teamNameGroup, 'Organization');
|
||||
|
||||
// Verify the team is moved under the table level
|
||||
const movedTeam = page.locator(
|
||||
`.ant-table-row-level-0[data-row-key="${teamNameGroup}"]`
|
||||
);
|
||||
await movedTeam.scrollIntoViewIfNeeded();
|
||||
|
||||
await expect(movedTeam).toBeVisible();
|
||||
});
|
||||
|
||||
test('Delete Teams', async ({ page }) => {
|
||||
for (const teamName of [
|
||||
teamNameBusiness,
|
||||
teamNameDivision,
|
||||
teamNameDepartment,
|
||||
teamNameGroup,
|
||||
]) {
|
||||
const getTeamResponse = page.waitForResponse(
|
||||
`/api/v1/teams/name/${teamName}*`
|
||||
);
|
||||
|
||||
await page.getByRole('link', { name: teamName }).click();
|
||||
await getTeamResponse;
|
||||
|
||||
await hardDeleteTeam(page);
|
||||
|
||||
// Validate the deleted team
|
||||
await expect(page.locator('table')).not.toContainText(teamName);
|
||||
}
|
||||
});
|
||||
});
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2024 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { expect, Page } from '@playwright/test';
|
||||
import { toastNotification } from './common';
|
||||
|
||||
export const dragAndDropElement = async (
|
||||
page: Page,
|
||||
dragElement: string,
|
||||
dropTarget: string,
|
||||
isHeader?: boolean
|
||||
) => {
|
||||
const dragElementLocator = page.locator(`[data-row-key="${dragElement}"]`);
|
||||
const dropTargetLocator = isHeader
|
||||
? page.locator(dropTarget)
|
||||
: page.locator(`[data-row-key="${dropTarget}"]`);
|
||||
|
||||
// Ensure the element is draggable
|
||||
const draggable = await dragElementLocator.getAttribute('draggable');
|
||||
if (draggable !== 'true') {
|
||||
throw new Error('Element is not draggable');
|
||||
}
|
||||
|
||||
// Perform drag and drop
|
||||
await dragElementLocator.dispatchEvent('dragstart');
|
||||
await dropTargetLocator.dispatchEvent('drop');
|
||||
await dragElementLocator.dispatchEvent('dragend');
|
||||
};
|
||||
|
||||
export const openDragDropDropdown = async (page: Page, name: string) => {
|
||||
const dropdownIcon = page.locator(
|
||||
`[data-row-key=${name}] > .whitespace-nowrap > [data-testid="expand-icon"] > svg`
|
||||
);
|
||||
await dropdownIcon.click();
|
||||
};
|
||||
|
||||
export const confirmationDragAndDropTeam = async (
|
||||
page: Page,
|
||||
dragTeam: string,
|
||||
dropTeam: string
|
||||
) => {
|
||||
// Confirmation message before the transfer
|
||||
await expect(
|
||||
page.locator('[data-testid="confirmation-modal"] .ant-modal-body')
|
||||
).toContainText(
|
||||
`Click on Confirm if you’d like to move ${dragTeam} team under ${dropTeam} team.`
|
||||
);
|
||||
|
||||
const patchResponse = page.waitForResponse('/api/v1/teams/*');
|
||||
await page.locator('.ant-modal-footer > .ant-btn-primary').click();
|
||||
await patchResponse;
|
||||
|
||||
await toastNotification(page, 'Team moved successfully!');
|
||||
};
|
@ -11,7 +11,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { expect, Page } from '@playwright/test';
|
||||
import { descriptionBox, uuid } from './common';
|
||||
import { descriptionBox, toastNotification, uuid } from './common';
|
||||
import { validateFormNameFieldInput } from './form';
|
||||
|
||||
const TEAM_TYPES = ['Department', 'Division', 'Group'];
|
||||
@ -75,11 +75,7 @@ export const hardDeleteTeam = async (page: Page) => {
|
||||
|
||||
await deleteResponse;
|
||||
|
||||
await expect(page.locator('.Toastify__toast-body')).toHaveText(
|
||||
/deleted successfully!/
|
||||
);
|
||||
|
||||
await page.click('.Toastify__close-button');
|
||||
await toastNotification(page, /deleted successfully!/);
|
||||
};
|
||||
|
||||
export const getNewTeamDetails = (teamName: string) => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user