mirror of https://github.com/nocodb/nocodb
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
333 lines
10 KiB
333 lines
10 KiB
// playwright-dev-page.ts |
|
import { Locator, Page, expect } from "@playwright/test"; |
|
import BasePage from "../Base"; |
|
import { GridPage } from "./Grid"; |
|
import { FormPage } from "./Form"; |
|
import { ExpandedFormPage } from "./ExpandedForm"; |
|
import { ChildList } from "./Grid/Column/LTAR/ChildList"; |
|
import { LinkRecord } from "./Grid/Column/LTAR/LinkRecord"; |
|
import { TreeViewPage } from "./TreeView"; |
|
import { SettingsPage } from "./Settings"; |
|
import { ViewSidebarPage } from "./ViewSidebar"; |
|
import { GalleryPage } from "./Gallery"; |
|
import { KanbanPage } from "./Kanban"; |
|
import { ToolbarPage } from "./common/Toolbar"; |
|
import { ImportAirtablePage } from "./Import/Airtable"; |
|
import { ImportTemplatePage } from "./Import/ImportTemplate"; |
|
import { WebhookFormPage } from "./WebhookForm"; |
|
|
|
export class DashboardPage extends BasePage { |
|
readonly project: any; |
|
readonly tablesSideBar: Locator; |
|
readonly tabBar: Locator; |
|
readonly treeView: TreeViewPage; |
|
readonly grid: GridPage; |
|
readonly gallery: GalleryPage; |
|
readonly form: FormPage; |
|
readonly kanban: KanbanPage; |
|
readonly expandedForm: ExpandedFormPage; |
|
readonly webhookForm: WebhookFormPage; |
|
readonly childList: ChildList; |
|
readonly linkRecord: LinkRecord; |
|
readonly settings: SettingsPage; |
|
readonly viewSidebar: ViewSidebarPage; |
|
readonly importAirtable: ImportAirtablePage; |
|
readonly importTemplate = new ImportTemplatePage(this); |
|
|
|
constructor(rootPage: Page, project: any) { |
|
super(rootPage); |
|
this.project = project; |
|
this.tablesSideBar = rootPage.locator(".nc-treeview-container"); |
|
this.tabBar = rootPage.locator(".nc-tab-bar"); |
|
this.treeView = new TreeViewPage(this, project); |
|
this.grid = new GridPage(this); |
|
this.gallery = new GalleryPage(this); |
|
this.form = new FormPage(this); |
|
this.kanban = new KanbanPage(this); |
|
this.expandedForm = new ExpandedFormPage(this); |
|
this.webhookForm = new WebhookFormPage(this); |
|
this.childList = new ChildList(this); |
|
this.linkRecord = new LinkRecord(this); |
|
this.settings = new SettingsPage(this); |
|
this.viewSidebar = new ViewSidebarPage(this); |
|
this.importAirtable = new ImportAirtablePage(this); |
|
} |
|
|
|
get() { |
|
return this.rootPage.locator("html"); |
|
} |
|
|
|
async goto() { |
|
await this.rootPage.goto(`/#/nc/${this.project.id}/auth`); |
|
} |
|
|
|
async gotoSettings() { |
|
await this.rootPage.locator('[pw-data="nc-project-menu"]').click(); |
|
await this.rootPage |
|
.locator('div.nc-project-menu-item:has-text(" Team & Settings")') |
|
.click(); |
|
} |
|
|
|
async verifyInTabBar({ title }: { title: string }) { |
|
await this.tabBar |
|
.textContent() |
|
.then((text) => expect(text).toContain(title)); |
|
} |
|
|
|
async closeTab({ title }: { title: string }) { |
|
let tab = await this.tabBar.locator(`.ant-tabs-tab:has-text("${title}")`); |
|
await tab.locator("button.ant-tabs-tab-remove").click(); |
|
|
|
// fix me! |
|
// await tab.waitFor({ state: "detached" }); |
|
await this.rootPage.waitForTimeout(2000); |
|
} |
|
|
|
async clickHome() { |
|
await this.rootPage.locator('[data-cy="nc-noco-brand-icon"]').click(); |
|
} |
|
|
|
async waitForTabRender({ |
|
title, |
|
mode = "standard", |
|
}: { |
|
title: string; |
|
mode?: string; |
|
}) { |
|
await this.get().locator('[pw-data="grid-id-column"]').waitFor(); |
|
|
|
await this.tabBar |
|
.locator(`.ant-tabs-tab-active:has-text("${title}")`) |
|
.waitFor(); |
|
|
|
// wait active tab animation to finish |
|
await expect |
|
.poll(async () => { |
|
return await this.tabBar |
|
.locator(`[data-pw="nc-root-tabs-${title}"]`) |
|
.evaluate((el) => { |
|
return window.getComputedStyle(el).getPropertyValue("color"); |
|
}); |
|
}) |
|
.toBe("rgb(67, 81, 232)"); // active tab text color |
|
|
|
await this.get() |
|
.locator('[pw-data="grid-load-spinner"]') |
|
.waitFor({ state: "hidden" }); |
|
|
|
if (mode === "standard") { |
|
await expect(this.rootPage).toHaveURL( |
|
`/#/nc/${this.project.id}/table/${title}` |
|
); |
|
} |
|
} |
|
|
|
// Project page language menu |
|
async openLanguageMenu() { |
|
await this.rootPage.locator(".nc-menu-translate").click(); |
|
} |
|
|
|
async openPasswordChangeModal() { |
|
// open change password portal |
|
await this.rootPage.locator(".nc-menu-accounts").click(); |
|
await this.rootPage |
|
.locator( |
|
`.nc-dropdown-user-accounts-menu >> [data-cy="nc-menu-accounts__user-settings"]` |
|
) |
|
.click(); |
|
} |
|
|
|
async changePassword({ |
|
oldPass, |
|
newPass, |
|
repeatPass, |
|
}: { |
|
oldPass: string; |
|
newPass: string; |
|
repeatPass: string; |
|
}) { |
|
// change password |
|
const currentPassword = await this.rootPage.locator( |
|
'input[data-cy="nc-user-settings-form__current-password"]' |
|
); |
|
const newPassword = await this.rootPage.locator( |
|
'input[data-cy="nc-user-settings-form__new-password"]' |
|
); |
|
const confirmPassword = await this.rootPage.locator( |
|
'input[data-cy="nc-user-settings-form__new-password-repeat"]' |
|
); |
|
|
|
await currentPassword.fill(oldPass); |
|
await newPassword.fill(newPass); |
|
await confirmPassword.fill(repeatPass); |
|
|
|
await this.rootPage |
|
.locator('button[data-cy="nc-user-settings-form__submit"]') |
|
.click(); |
|
} |
|
|
|
async selectLanguage({ index }: { index: number }) { |
|
let modal = await this.rootPage.locator(".nc-dropdown-menu-translate"); |
|
await modal.locator(`.ant-dropdown-menu-item`).nth(index).click(); |
|
|
|
// fix me! |
|
// allow time for language to change |
|
await this.rootPage.waitForTimeout(1000); |
|
} |
|
|
|
async verifyLanguage(param: { json: any }) { |
|
let title = await this.rootPage |
|
.locator(`.nc-project-page-title`) |
|
.textContent(); |
|
let menu = await this.rootPage |
|
.locator(`.nc-new-project-menu`) |
|
.textContent(); |
|
expect(title).toContain(param.json.title.myProject); |
|
expect(menu).toContain(param.json.title.newProj); |
|
await this.rootPage |
|
.locator(`[placeholder="${param.json.activity.searchProject}"]`) |
|
.waitFor(); |
|
} |
|
|
|
// create project |
|
async createProject({ |
|
name = "sample", |
|
type = "xcdb", |
|
}: { |
|
name?: string; |
|
type?: string; |
|
}) { |
|
// fix me! wait for page to be rendered completely |
|
await this.rootPage.waitForTimeout(1000); |
|
await this.rootPage.locator(".nc-new-project-menu").click(); |
|
|
|
const createProjectMenu = await this.rootPage.locator( |
|
".nc-dropdown-create-project" |
|
); |
|
if (type === "xcdb") { |
|
await createProjectMenu |
|
.locator(`.ant-dropdown-menu-title-content`) |
|
.nth(0) |
|
.click(); |
|
} else { |
|
await createProjectMenu |
|
.locator(`.ant-dropdown-menu-title-content`) |
|
.nth(1) |
|
.click(); |
|
} |
|
|
|
await this.rootPage.locator(`.nc-metadb-project-name`).waitFor(); |
|
await this.rootPage.locator(`input.nc-metadb-project-name`).fill(name); |
|
await this.rootPage.locator(`input.nc-metadb-project-name`).press("Enter"); |
|
} |
|
|
|
async signOut() { |
|
await this.rootPage.locator('[pw-data="nc-project-menu"]').click(); |
|
let projMenu = await this.rootPage.locator(".nc-dropdown-project-menu"); |
|
await projMenu.locator('[data-menu-id="account"]:visible').click(); |
|
await this.rootPage |
|
.locator('div.nc-project-menu-item:has-text("Sign Out"):visible') |
|
.click(); |
|
await this.rootPage.locator('[data-cy="nc-form-signin"]:visible').waitFor(); |
|
} |
|
|
|
async signUp({ email, password }: { email: string; password: string }) { |
|
const signUp = this.rootPage; |
|
await signUp.locator('button:has-text("SIGN UP")').waitFor(); |
|
|
|
await signUp |
|
.locator(`input[placeholder="Enter your work email"]`) |
|
.fill(email); |
|
await signUp |
|
.locator(`input[placeholder="Enter your password"]`) |
|
.fill(password); |
|
await signUp.locator(`button:has-text("SIGN UP")`).click(); |
|
} |
|
|
|
async openProject({ title }: { title?: string }) { |
|
const project = this.rootPage; |
|
await project.locator(`td.ant-table-cell:has-text("${title}")`).click(); |
|
} |
|
|
|
async renameProject({ |
|
title, |
|
newTitle, |
|
}: { |
|
title?: string; |
|
newTitle?: string; |
|
}) { |
|
const project = this.rootPage; |
|
const projRow = await project.locator(`tr`, { |
|
has: project.locator(`td.ant-table-cell:has-text("${title}")`), |
|
}); |
|
await projRow.locator(".nc-action-btn").nth(0).click(); |
|
await project.locator("input.nc-metadb-project-name").fill(newTitle); |
|
// press enter to save |
|
await project.locator("input.nc-metadb-project-name").press("Enter"); |
|
} |
|
|
|
async deleteProject({ title }: { title?: string }) { |
|
const project = this.rootPage; |
|
const projRow = await project.locator(`tr`, { |
|
has: project.locator(`td.ant-table-cell:has-text("${title}")`), |
|
}); |
|
await projRow.locator(".nc-action-btn").nth(1).click(); |
|
const deleteModal = await project.locator(".nc-modal-project-delete"); |
|
await deleteModal.locator('button:has-text("Yes")').click(); |
|
|
|
await this.rootPage.waitForTimeout(1000); |
|
|
|
expect( |
|
await project.locator(`td.ant-table-cell:has-text("${title}")`).count() |
|
).toBe(0); |
|
} |
|
|
|
async validateProjectMenu(param: { role: string; mode?: string }) { |
|
await this.rootPage.locator('[pw-data="nc-project-menu"]').click(); |
|
let pMenu = this.rootPage.locator(`.nc-dropdown-project-menu:visible`); |
|
|
|
// menu items |
|
let menuItems = { |
|
creator: [ |
|
"Copy Project Info", |
|
"Swagger: REST APIs", |
|
"Copy Auth Token", |
|
"Team & Settings", |
|
"Themes", |
|
"Preview as", |
|
"Language", |
|
"Account", |
|
], |
|
editor: [ |
|
"Copy Project Info", |
|
"Swagger: REST APIs", |
|
"Copy Auth Token", |
|
"Language", |
|
"Account", |
|
], |
|
commenter: [ |
|
"Copy Project Info", |
|
"Copy Auth Token", |
|
"Language", |
|
"Account", |
|
], |
|
viewer: ["Copy Project Info", "Copy Auth Token", "Language", "Account"], |
|
}; |
|
|
|
if (param?.mode === "shareBase") { |
|
menuItems = { |
|
creator: [], |
|
commenter: [], |
|
editor: ["Language"], |
|
viewer: ["Language"], |
|
}; |
|
} |
|
|
|
// common items |
|
|
|
for (let item of menuItems[param.role]) { |
|
await expect(pMenu).toContainText(item); |
|
} |
|
await this.rootPage.locator('[pw-data="nc-project-menu"]').click(); |
|
} |
|
}
|
|
|