Minor: Fix playwright circular dependencies (#17228)

* Fix circular dependencies in playwright test files

* Fix the type error
This commit is contained in:
Aniket Katkar 2024-07-30 15:05:56 +05:30 committed by GitHub
parent 84ad2062b8
commit 7f6fc5321e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 230 additions and 142 deletions

View File

@ -17,11 +17,10 @@ import {
checkDescriptionInEditModal,
deleteFeedComments,
} from '../../utils/activityFeed';
import { performAdminLogin } from '../../utils/admin';
import {
createNewPage,
descriptionBox,
performAdminLogin,
performUserLogin,
redirectToHomePage,
toastNotification,
visitUserProfilePage,
@ -33,6 +32,7 @@ import {
createTagTask,
TaskDetails,
} from '../../utils/task';
import { performUserLogin } from '../../utils/user';
const entity = new TableClass();
const entity2 = new TableClass();

View File

@ -20,13 +20,13 @@ import { SearchIndexClass } from '../../support/entity/SearchIndexClass';
import { TableClass } from '../../support/entity/TableClass';
import { TopicClass } from '../../support/entity/TopicClass';
import { UserClass } from '../../support/user/UserClass';
import { performAdminLogin } from '../../utils/admin';
import {
getEntityTypeSearchIndexMapping,
performAdminLogin,
performUserLogin,
redirectToHomePage,
} from '../../utils/common';
import { checkDataAssetWidget } from '../../utils/entity';
import { performUserLogin } from '../../utils/user';
const entities = [
TableClass,

View File

@ -14,8 +14,11 @@ import test from '@playwright/test';
import { SidebarItem } from '../../constant/sidebar';
import { Domain } from '../../support/domain/Domain';
import { TableClass } from '../../support/entity/TableClass';
import { createNewPage, redirectToHomePage } from '../../utils/common';
import { assignDomain } from '../../utils/domain';
import {
assignDomain,
createNewPage,
redirectToHomePage,
} from '../../utils/common';
import { assignTag } from '../../utils/entity';
import { searchAndClickOnOption, selectNullOption } from '../../utils/explore';
import { sidebarClick } from '../../utils/sidebar';

View File

@ -19,9 +19,9 @@ import { Glossary } from '../../support/glossary/Glossary';
import { GlossaryTerm } from '../../support/glossary/GlossaryTerm';
import { TeamClass } from '../../support/team/TeamClass';
import { UserClass } from '../../support/user/UserClass';
import { performAdminLogin } from '../../utils/admin';
import {
performAdminLogin,
performUserLogin,
getRandomLastName,
redirectToHomePage,
toastNotification,
uuid,
@ -39,7 +39,7 @@ import {
verifyGlossaryTermAssets,
} from '../../utils/glossary';
import { sidebarClick } from '../../utils/sidebar';
import { getRandomLastName } from '../../utils/user';
import { performUserLogin } from '../../utils/user';
const user1 = new UserClass();
const user2 = new UserClass();

View File

@ -18,7 +18,8 @@ import {
import { SidebarItem } from '../../constant/sidebar';
import { AdminClass } from '../../support/user/AdminClass';
import { UserClass } from '../../support/user/UserClass';
import { performAdminLogin, redirectToHomePage } from '../../utils/common';
import { performAdminLogin } from '../../utils/admin';
import { redirectToHomePage } from '../../utils/common';
import { sidebarClick } from '../../utils/sidebar';
const user = new UserClass();

View File

@ -12,13 +12,13 @@
*/
import { APIRequestContext, Page } from '@playwright/test';
import { CustomPropertySupportedEntityList } from '../../constant/customProperty';
import { assignDomain, removeDomain, updateDomain } from '../../utils/common';
import {
createCustomPropertyForEntity,
CustomProperty,
setValueForProperty,
validateValueForProperty,
} from '../../utils/customProperty';
import { assignDomain, removeDomain, updateDomain } from '../../utils/domain';
import {
addMultiOwner,
addOwner,

View File

@ -0,0 +1,67 @@
/*
* 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.
*/
export type GlossaryResponseDataType = {
name: string;
displayName: string;
description: string;
reviewers: unknown[];
tags: unknown[];
mutuallyExclusive: boolean;
id: string;
fullyQualifiedName: string;
};
export type UserTeamRef = {
name: string;
type: string;
};
export type GlossaryData = {
name: string;
displayName: string;
description: string;
reviewers: UserTeamRef[];
tags: string[];
mutuallyExclusive: boolean;
terms: { data: GlossaryTermData }[];
owners: UserTeamRef[];
fullyQualifiedName: string;
};
export type GlossaryTermResponseDataType = {
name: string;
displayName: string;
description: string;
reviewers: unknown[];
relatedTerms: unknown[];
synonyms: unknown[];
mutuallyExclusive: boolean;
tags: unknown[];
glossary: Record<string, string>;
id: string;
fullyQualifiedName: string;
};
export type GlossaryTermData = {
name: string;
displayName: string;
description: string;
mutuallyExclusive: boolean;
glossary: string;
synonyms: string;
icon?: string;
color?: string;
owners?: UserTeamRef[];
fullyQualifiedName: string;
reviewers: UserTeamRef[];
};

View File

@ -12,38 +12,12 @@
*/
import { APIRequestContext, expect, Page } from '@playwright/test';
import { omit } from 'lodash';
import { uuid } from '../../utils/common';
import { visitGlossaryPage } from '../../utils/glossary';
import { getRandomFirstName } from '../../utils/user';
import { GlossaryTerm } from './GlossaryTerm';
type ResponseDataType = {
name: string;
displayName: string;
description: string;
reviewers: unknown[];
tags: unknown[];
mutuallyExclusive: boolean;
id: string;
fullyQualifiedName: string;
};
export type UserTeamRef = {
name: string;
type: string;
};
export type GlossaryData = {
name: string;
displayName: string;
description: string;
reviewers: UserTeamRef[];
tags: string[];
mutuallyExclusive: boolean;
terms: GlossaryTerm[];
owners: UserTeamRef[];
fullyQualifiedName: string;
};
import {
getRandomFirstName,
uuid,
visitGlossaryPage,
} from '../../utils/common';
import { GlossaryData, GlossaryResponseDataType } from './Glossary.interface';
export class Glossary {
randomName = getRandomFirstName();
@ -62,7 +36,7 @@ export class Glossary {
fullyQualifiedName: `\"PW%${this.randomId}.${this.randomName}\"`,
};
responseData: ResponseDataType;
responseData: GlossaryResponseDataType;
constructor(name?: string) {
this.data.name = name ?? this.data.name;

View File

@ -12,38 +12,12 @@
*/
import { APIRequestContext, expect, Page } from '@playwright/test';
import { omit } from 'lodash';
import { uuid } from '../../utils/common';
import { visitGlossaryPage } from '../../utils/glossary';
import { getRandomLastName } from '../../utils/user';
import { Glossary, UserTeamRef } from './Glossary';
type ResponseDataType = {
name: string;
displayName: string;
description: string;
reviewers: unknown[];
relatedTerms: unknown[];
synonyms: unknown[];
mutuallyExclusive: boolean;
tags: unknown[];
glossary: Record<string, string>;
id: string;
fullyQualifiedName: string;
};
export type GlossaryTermData = {
name: string;
displayName: string;
description: string;
mutuallyExclusive: boolean;
glossary: string;
synonyms: string;
icon?: string;
color?: string;
owner?: UserTeamRef;
fullyQualifiedName: string;
reviewers: UserTeamRef[];
};
import { getRandomLastName, uuid, visitGlossaryPage } from '../../utils/common';
import { Glossary } from './Glossary';
import {
GlossaryTermData,
GlossaryTermResponseDataType,
} from './Glossary.interface';
export class GlossaryTerm {
randomName = getRandomLastName();
@ -58,7 +32,7 @@ export class GlossaryTerm {
reviewers: [],
};
responseData: ResponseDataType;
responseData: GlossaryTermResponseDataType;
constructor(glossary: Glossary, name?: string) {
this.data.glossary = glossary.data.name;

View File

@ -11,8 +11,8 @@
* limitations under the License.
*/
import { APIRequestContext, Page } from '@playwright/test';
import { getRandomLastName } from '../../utils/common';
import { visitClassificationPage } from '../../utils/tag';
import { getRandomLastName } from '../../utils/user';
type ResponseDataType = {
style?: {

View File

@ -12,7 +12,7 @@
*/
import { APIRequestContext, Page } from '@playwright/test';
import { Operation } from 'fast-json-patch';
import { generateRandomUsername } from '../../utils/user';
import { generateRandomUsername } from '../../utils/common';
type ResponseDataType = {
name: string;

View File

@ -0,0 +1,29 @@
/*
* 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 { AdminClass } from '../support/user/AdminClass';
import { getAuthContext, getToken, redirectToHomePage } from './common';
export const performAdminLogin = async (browser) => {
const admin = new AdminClass();
const page = await browser.newPage();
await admin.login(page);
await redirectToHomePage(page);
const token = await getToken(page);
const apiContext = await getAuthContext(token);
const afterAction = async () => {
await apiContext.dispose();
await page.close();
};
return { page, apiContext, afterAction };
};

View File

@ -12,8 +12,9 @@
*/
import { Browser, expect, Page, request } from '@playwright/test';
import { randomUUID } from 'crypto';
import { AdminClass } from '../support/user/AdminClass';
import { UserClass } from '../support/user/UserClass';
import { SidebarItem } from '../constant/sidebar';
import { adjectives, nouns } from '../constant/user';
import { sidebarClick } from './sidebar';
export const uuid = () => randomUUID().split('-')[0];
@ -102,34 +103,6 @@ export const getEntityTypeSearchIndexMapping = (entityType: string) => {
return entityMapping[entityType];
};
export const performAdminLogin = async (browser) => {
const admin = new AdminClass();
const page = await browser.newPage();
await admin.login(page);
await redirectToHomePage(page);
const token = await getToken(page);
const apiContext = await getAuthContext(token);
const afterAction = async () => {
await apiContext.dispose();
await page.close();
};
return { page, apiContext, afterAction };
};
export const performUserLogin = async (browser, user: UserClass) => {
const page = await browser.newPage();
await user.login(page);
const token = await getToken(page);
const apiContext = await getAuthContext(token);
const afterAction = async () => {
await apiContext.dispose();
await page.close();
};
return { page, apiContext, afterAction };
};
export const toastNotification = async (
page: Page,
message: string | RegExp
@ -161,3 +134,84 @@ export const visitUserProfilePage = async (page: Page) => {
await userResponse;
await clickOutside(page);
};
export const assignDomain = async (
page: Page,
domain: { name: string; displayName: string }
) => {
await page.getByTestId('add-domain').click();
await page.waitForSelector('[data-testid="loader"]', { state: 'detached' });
await page
.getByTestId('selectable-list')
.getByTestId('searchbar')
.fill(domain.name);
await page.waitForResponse(
`/api/v1/search/query?q=*${encodeURIComponent(domain.name)}*`
);
await page.getByRole('listitem', { name: domain.displayName }).click();
await expect(page.getByTestId('domain-link')).toContainText(
domain.displayName
);
};
export const updateDomain = async (
page: Page,
domain: { name: string; displayName: string }
) => {
await page.getByTestId('add-domain').click();
await page.waitForSelector('[data-testid="loader"]', { state: 'detached' });
await page.getByTestId('selectable-list').getByTestId('searchbar').clear();
await page
.getByTestId('selectable-list')
.getByTestId('searchbar')
.fill(domain.name);
await page.waitForResponse(
`/api/v1/search/query?q=*${encodeURIComponent(domain.name)}*`
);
await page.getByRole('listitem', { name: domain.displayName }).click();
await expect(page.getByTestId('domain-link')).toContainText(
domain.displayName
);
};
export const removeDomain = async (page: Page) => {
await page.getByTestId('add-domain').click();
await page.waitForSelector('[data-testid="loader"]', { state: 'detached' });
await expect(page.getByTestId('remove-owner').locator('path')).toBeVisible();
await page.getByTestId('remove-owner').locator('svg').click();
await expect(page.getByTestId('no-domain-text')).toContainText('No Domain');
};
export const visitGlossaryPage = async (page: Page, glossaryName: string) => {
await redirectToHomePage(page);
const glossaryResponse = page.waitForResponse('/api/v1/glossaries?fields=*');
await sidebarClick(page, SidebarItem.GLOSSARY);
await glossaryResponse;
await page.getByRole('menuitem', { name: glossaryName }).click();
};
export const getRandomFirstName = () => {
return `${
adjectives[Math.floor(Math.random() * adjectives.length)]
}${uuid()}`;
};
export const getRandomLastName = () => {
return `${nouns[Math.floor(Math.random() * nouns.length)]}${uuid()}`;
};
export const generateRandomUsername = () => {
const firstName = getRandomFirstName();
const lastName = getRandomLastName();
return {
firstName,
lastName,
email: `${firstName}.${lastName}@example.com`,
password: 'User@OMD123',
};
};

View File

@ -11,18 +11,19 @@
* limitations under the License.
*/
import { expect, Page } from '@playwright/test';
import { get } from 'lodash';
import { get, isUndefined } from 'lodash';
import { SidebarItem } from '../constant/sidebar';
import { GLOSSARY_TERM_PATCH_PAYLOAD } from '../constant/version';
import { DashboardClass } from '../support/entity/DashboardClass';
import { EntityTypeEndpoint } from '../support/entity/Entity.interface';
import { TableClass } from '../support/entity/TableClass';
import { TopicClass } from '../support/entity/TopicClass';
import { Glossary, GlossaryData } from '../support/glossary/Glossary';
import { Glossary } from '../support/glossary/Glossary';
import {
GlossaryTerm,
GlossaryData,
GlossaryTermData,
} from '../support/glossary/GlossaryTerm';
} from '../support/glossary/Glossary.interface';
import { GlossaryTerm } from '../support/glossary/GlossaryTerm';
import {
getApiContext,
INVALID_NAMES,
@ -36,14 +37,6 @@ import { sidebarClick } from './sidebar';
export const descriptionBox =
'.toastui-editor-md-container > .toastui-editor > .ProseMirror';
export const visitGlossaryPage = async (page: Page, glossaryName: string) => {
await redirectToHomePage(page);
const glossaryResponse = page.waitForResponse('/api/v1/glossaries?fields=*');
await sidebarClick(page, SidebarItem.GLOSSARY);
await glossaryResponse;
await page.getByRole('menuitem', { name: glossaryName }).click();
};
export const checkDisplayName = async (page: Page, displayName: string) => {
await expect(page.getByTestId('entity-header-display-name')).toHaveText(
displayName
@ -449,10 +442,10 @@ export const fillGlossaryTermDetails = async (
await page.locator('[data-testid="color-color-input"]').fill(term.color);
}
if (term.owner) {
if (!isUndefined(term.owners)) {
await addMultiOwner({
page,
ownerNames: term.owner.name,
ownerNames: term.owners.map((owner) => owner.name),
activatorBtnDataTestId: 'add-owner',
resultTestId: 'owner-container',
endpoint: EntityTypeEndpoint.GlossaryTerm,

View File

@ -12,27 +12,20 @@
*/
import { expect, Page } from '@playwright/test';
import { adjectives, nouns } from '../constant/user';
import { toastNotification, uuid } from './common';
import { UserClass } from '../support/user/UserClass';
import { getAuthContext, getToken, toastNotification } from './common';
export const getRandomFirstName = () => {
return `${
adjectives[Math.floor(Math.random() * adjectives.length)]
}${uuid()}`;
};
export const getRandomLastName = () => {
return `${nouns[Math.floor(Math.random() * nouns.length)]}${uuid()}`;
};
export const generateRandomUsername = () => {
const firstName = getRandomFirstName();
const lastName = getRandomLastName();
return {
firstName,
lastName,
email: `${firstName}.${lastName}@example.com`,
password: 'User@OMD123',
export const performUserLogin = async (browser, user: UserClass) => {
const page = await browser.newPage();
await user.login(page);
const token = await getToken(page);
const apiContext = await getAuthContext(token);
const afterAction = async () => {
await apiContext.dispose();
await page.close();
};
return { page, apiContext, afterAction };
};
export const nonDeletedUserChecks = async (page: Page) => {