mirror of
https://github.com/nocodb/nocodb.git
synced 2026-04-25 03:05:47 +00:00
feat(testing): Added quicktest(not complete)
This commit is contained in:
@@ -94,7 +94,7 @@ export class FormPage extends BasePage {
|
||||
}
|
||||
|
||||
getFormFields() {
|
||||
return this.get().locator('[data-pw="nc-form-field"]');
|
||||
return this.get().locator('[data-pw="nc-form-fields"]');
|
||||
}
|
||||
|
||||
getDragNDropToHide() {
|
||||
@@ -120,6 +120,22 @@ export class FormPage extends BasePage {
|
||||
///////////////////////////
|
||||
// Form Actions
|
||||
|
||||
async verifyFormFieldLabel({ index, label }: { index: number; label: string }) {
|
||||
await expect(await this.getFormFields().nth(index).locator('[data-pw="nc-form-input-label"]')).toContainText(label);
|
||||
}
|
||||
|
||||
async verifyFormFieldHelpText({ index, helpText }: { index: number; helpText: string }) {
|
||||
await expect(await this.getFormFields().nth(index).locator('[pw-data="nc-form-input-help-text-label"]')).toContainText(helpText);
|
||||
}
|
||||
|
||||
async verifyFieldsIsEditable({ index }: { index: number }) {
|
||||
await expect(await this.getFormFields().nth(index)).toHaveClass(/nc-editable/);
|
||||
}
|
||||
|
||||
async verifyAfterSubmitMsg({ msg }: { msg: string }) {
|
||||
await expect((await this.afterSubmitMsg.inputValue()).includes(msg)).toBeTruthy()
|
||||
}
|
||||
|
||||
async verifyFormViewFieldsOrder({ fields }: { fields: string[] }) {
|
||||
let fieldLabels = await this.get().locator(
|
||||
'[data-pw="nc-form-input-label"]'
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import { expect } from "@playwright/test";
|
||||
import { CellPageObject } from ".";
|
||||
import BasePage from "../../../Base";
|
||||
|
||||
export class CheckboxCellPageObject extends BasePage {
|
||||
readonly cell: CellPageObject;
|
||||
|
||||
constructor(cell: CellPageObject) {
|
||||
super(cell.rootPage);
|
||||
this.cell = cell;
|
||||
}
|
||||
|
||||
get({index, columnHeader}: {index?: number, columnHeader: string}) {
|
||||
return this.cell.get({index, columnHeader});
|
||||
}
|
||||
|
||||
async click({ index, columnHeader }: { index?: number, columnHeader: string }) {
|
||||
return this.get({index, columnHeader}).locator('.nc-cell').click();
|
||||
}
|
||||
|
||||
async isChecked({ index, columnHeader }: { index?: number, columnHeader: string }) {
|
||||
return this.get({index, columnHeader}).locator('.nc-cell-hover-show').isVisible();
|
||||
}
|
||||
|
||||
async verifyChecked({ index, columnHeader }: { index?: number, columnHeader: string }) {
|
||||
expect(await this.get({index, columnHeader}).locator('.nc-cell-hover-show').isVisible()).toBe(false);
|
||||
}
|
||||
|
||||
async verifyUnchecked({ index, columnHeader }: { index?: number, columnHeader: string }) {
|
||||
expect(await this.get({index, columnHeader}).locator('.nc-cell-hover-show').isVisible()).toBe(true);
|
||||
}
|
||||
}
|
||||
21
scripts/playwright/pages/Dashboard/common/Cell/RatingCell.ts
Normal file
21
scripts/playwright/pages/Dashboard/common/Cell/RatingCell.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { expect } from "@playwright/test";
|
||||
import { CellPageObject } from ".";
|
||||
import BasePage from "../../../Base";
|
||||
|
||||
export class RatingCellPageObject extends BasePage {
|
||||
readonly cell: CellPageObject;
|
||||
|
||||
constructor(cell: CellPageObject) {
|
||||
super(cell.rootPage);
|
||||
this.cell = cell;
|
||||
}
|
||||
|
||||
get({index, columnHeader}: {index?: number, columnHeader: string}) {
|
||||
return this.cell.get({index, columnHeader});
|
||||
}
|
||||
|
||||
async verify({index, columnHeader, rating}: {index?: number, columnHeader: string, rating: number}) {
|
||||
expect(await this.get({index, columnHeader}).locator(`div[role="radio"][aria-checked="true"]`).count()).toBe(rating);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,17 +4,22 @@ import BasePage from "../../../Base";
|
||||
import { AttachmentCellPageObject } from "./AttachmentCell";
|
||||
import { SelectOptionCellPageObject } from "./SelectOptionCell";
|
||||
import { SharedFormPage } from "../../../SharedForm";
|
||||
import { CheckboxCellPageObject } from "./CheckboxCell";
|
||||
import { RatingCellPageObject } from "./RatingCell";
|
||||
|
||||
export class CellPageObject extends BasePage {
|
||||
readonly parent: GridPage | SharedFormPage;
|
||||
readonly selectOption: SelectOptionCellPageObject;
|
||||
readonly attachment: AttachmentCellPageObject;
|
||||
|
||||
readonly checkbox: CheckboxCellPageObject;
|
||||
readonly rating: RatingCellPageObject;
|
||||
constructor(parent: GridPage | SharedFormPage) {
|
||||
super(parent.rootPage);
|
||||
this.parent = parent;
|
||||
this.selectOption = new SelectOptionCellPageObject(this);
|
||||
this.attachment = new AttachmentCellPageObject(this);
|
||||
this.checkbox = new CheckboxCellPageObject(this);
|
||||
this.rating = new RatingCellPageObject(this);
|
||||
}
|
||||
|
||||
get({
|
||||
@@ -127,6 +132,7 @@ export class CellPageObject extends BasePage {
|
||||
}
|
||||
}
|
||||
|
||||
// todo: Improve param names (i.e value => values)
|
||||
// verifyVirtualCell
|
||||
// : virtual relational cell- HM, BT, MM
|
||||
// : verify link count & cell value
|
||||
@@ -139,7 +145,7 @@ export class CellPageObject extends BasePage {
|
||||
}: {
|
||||
index: number;
|
||||
columnHeader: string;
|
||||
count: number;
|
||||
count?: number;
|
||||
value: string[];
|
||||
}) {
|
||||
// const count = value.length;
|
||||
@@ -148,7 +154,7 @@ export class CellPageObject extends BasePage {
|
||||
const chipCount = await chips.count();
|
||||
|
||||
// verify chip count & contents
|
||||
expect(chipCount).toEqual(count);
|
||||
if(count) expect(chipCount).toEqual(count);
|
||||
|
||||
// verify only the elements that are passed in
|
||||
for (let i = 0; i < value.length; ++i) {
|
||||
|
||||
33
scripts/playwright/pages/LoginPage/index.ts
Normal file
33
scripts/playwright/pages/LoginPage/index.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
// playwright-dev-page.ts
|
||||
import { expect, Page } from "@playwright/test";
|
||||
import BasePage from "../Base";
|
||||
|
||||
export class LoginPage extends BasePage {
|
||||
|
||||
constructor(rootPage: Page) {
|
||||
super(rootPage);
|
||||
}
|
||||
|
||||
goto() {
|
||||
return this.rootPage.goto('/#/signin');
|
||||
}
|
||||
|
||||
get() {
|
||||
return this.rootPage.locator("html");
|
||||
}
|
||||
|
||||
async fillEmail(email: string) {
|
||||
await this.get().locator(`[pw-data="nc-form-signin__email"]`).fill(email);
|
||||
}
|
||||
|
||||
async fillPassword(password: string) {
|
||||
await this.get().locator(`[pw-data="nc-form-signin__password"]`).fill(password);
|
||||
}
|
||||
|
||||
async submit() {
|
||||
await this.get().locator(`[pw-data="nc-form-signin__submit"]`).click();
|
||||
|
||||
await expect(this.rootPage).toHaveURL('http://localhost:3000/#/');
|
||||
}
|
||||
|
||||
}
|
||||
44
scripts/playwright/pages/ProjectsPage/index.ts
Normal file
44
scripts/playwright/pages/ProjectsPage/index.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
// playwright-dev-page.ts
|
||||
import { expect, Page } from "@playwright/test";
|
||||
import BasePage from "../Base";
|
||||
|
||||
export class ProjectsPage extends BasePage {
|
||||
constructor(rootPage: Page) {
|
||||
super(rootPage);
|
||||
}
|
||||
|
||||
get() {
|
||||
return this.rootPage.locator("html");
|
||||
}
|
||||
|
||||
async selectAndGetProject(projectName: string) {
|
||||
let project: any;
|
||||
|
||||
await Promise.all([
|
||||
this.rootPage.waitForResponse(async (res) => {
|
||||
let json:any = {}
|
||||
try{
|
||||
json = await res.json()
|
||||
} catch(e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const isRequiredResponse = res.request().url().includes('/api/v1/db/meta/projects') &&
|
||||
['GET'].includes(res.request().method()) &&
|
||||
json?.title === projectName;
|
||||
|
||||
if(isRequiredResponse){
|
||||
project = json;
|
||||
}
|
||||
|
||||
return isRequiredResponse;
|
||||
}),
|
||||
this.get().locator(`.ant-table-cell`,{
|
||||
hasText: projectName
|
||||
}).click()
|
||||
]);
|
||||
|
||||
return project;
|
||||
}
|
||||
|
||||
}
|
||||
136
scripts/playwright/quickTests/quickTests.spec.ts
Normal file
136
scripts/playwright/quickTests/quickTests.spec.ts
Normal file
@@ -0,0 +1,136 @@
|
||||
|
||||
import { expect, test } from "@playwright/test";
|
||||
import { DashboardPage } from "../pages/Dashboard";
|
||||
import { LoginPage } from "../pages/LoginPage";
|
||||
import { ProjectsPage } from "../pages/ProjectsPage";
|
||||
|
||||
// normal fields
|
||||
let recordCells = {
|
||||
Name: "Movie-1",
|
||||
Notes: "Good",
|
||||
Status: "Todo",
|
||||
Tags: "Jan",
|
||||
Phone: "123123123",
|
||||
Email: "a@b.com",
|
||||
URL: "www.a.com",
|
||||
Number: "1",
|
||||
Value: "$1.00",
|
||||
Percent: "0.01",
|
||||
};
|
||||
|
||||
// links/ computed fields
|
||||
let recordsVirtualCells = {
|
||||
Duration: "00:01",
|
||||
Done: true,
|
||||
Date: "2022-05-31",
|
||||
Rating: 1,
|
||||
Actor: ["Actor1", "Actor2"],
|
||||
"Status (from Actor)": ["Todo", "In progress"],
|
||||
RollUp: "128",
|
||||
Computation: "4.04",
|
||||
Producer: ["P1", "P2"],
|
||||
};
|
||||
|
||||
let tn = ["Film", "Actor", "Producer"];
|
||||
|
||||
let cn = [
|
||||
"Name",
|
||||
"Notes",
|
||||
"Status",
|
||||
"Tags",
|
||||
"Done",
|
||||
"Date",
|
||||
"Phone",
|
||||
"Email",
|
||||
"URL",
|
||||
"Number",
|
||||
"Percent",
|
||||
"Duration",
|
||||
"Rating",
|
||||
"Actor",
|
||||
"Status (from Actor)",
|
||||
"RollUp",
|
||||
"Computation",
|
||||
"Producer",
|
||||
];
|
||||
|
||||
test.describe("Quick tests", () => {
|
||||
let dashboard: DashboardPage;
|
||||
|
||||
// test.beforeEach(async ({ page }) => {
|
||||
// });
|
||||
|
||||
test("Quick tests test", async ({page}) => {
|
||||
let cellIndex = 0;
|
||||
let columnCount = cn.length;
|
||||
|
||||
const loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.fillEmail("user@nocodb.com");
|
||||
await loginPage.fillPassword("Password123.");
|
||||
await loginPage.submit();
|
||||
|
||||
const projectsPage = new ProjectsPage(page);
|
||||
const project = await projectsPage.selectAndGetProject("sample");
|
||||
dashboard = new DashboardPage(page, project);
|
||||
|
||||
// verify if all tables exist
|
||||
for (let i = 0; i < tn.length; i++) {
|
||||
await dashboard.treeView.verifyTable({ title: tn[i] });
|
||||
}
|
||||
|
||||
await dashboard.treeView.openTable({ title: "Film" });
|
||||
// for Film table, verify columns
|
||||
for (let i = 0; i < columnCount; i++) {
|
||||
await dashboard.grid.column.verify({ title: cn[i] });
|
||||
}
|
||||
|
||||
// normal cells
|
||||
for (let [key, value] of Object.entries(recordCells)) {
|
||||
await dashboard.grid.cell.verify({ index: cellIndex, columnHeader: key, value });
|
||||
}
|
||||
|
||||
// checkbox
|
||||
await dashboard.grid.cell.checkbox.verifyChecked({ index: cellIndex, columnHeader: "Done" });
|
||||
|
||||
// duration
|
||||
await dashboard.grid.cell.verify({ index: cellIndex, columnHeader: "Duration", value: recordsVirtualCells.Duration });
|
||||
|
||||
// rating
|
||||
await dashboard.grid.cell.rating.verify({ index: cellIndex, columnHeader: "Rating", rating: recordsVirtualCells.Rating });
|
||||
|
||||
// LinkToAnotherRecord
|
||||
await dashboard.grid.cell.verifyVirtualCell({ index: cellIndex, columnHeader: "Actor", value: recordsVirtualCells.Actor });
|
||||
|
||||
// Status (from Actor)
|
||||
// todo: Find a way to verify only the elements that are passed in
|
||||
// await dashboard.grid.cell.verify({ index: cellIndex, columnHeader: "Status (from Actor)", value: recordsVirtualCells["Status (from Actor)"][0] });
|
||||
|
||||
// RollUp
|
||||
await dashboard.grid.cell.verify({ index: cellIndex, columnHeader: "RollUp", value: recordsVirtualCells.RollUp });
|
||||
|
||||
// Computation
|
||||
await dashboard.grid.cell.verify({ index: cellIndex, columnHeader: "Computation", value: recordsVirtualCells.Computation });
|
||||
|
||||
// LinkToAnotherRecord
|
||||
await dashboard.grid.cell.verifyVirtualCell({ index: cellIndex, columnHeader: "Producer", value: recordsVirtualCells.Producer });
|
||||
|
||||
|
||||
// Verify form
|
||||
await dashboard.viewSidebar.openView({ title: "FormTitle" });
|
||||
await dashboard.form.verifyHeader({ title: "FormTitle", subtitle: "FormDescription" });
|
||||
await dashboard.form.verifyFormFieldLabel({ index: 0, label: "DisplayName" });
|
||||
await dashboard.form.verifyFormFieldHelpText({ index: 0, helpText: "HelpText" });
|
||||
await dashboard.form.verifyFieldsIsEditable({ index: 0 });
|
||||
await dashboard.form.verifyAfterSubmitMsg({ msg: "Thank you for submitting the form!" });
|
||||
await dashboard.form.verifyAfterSubmitMenuState({
|
||||
emailMe: false,
|
||||
showBlankForm: true,
|
||||
submitAnotherForm: true,
|
||||
});
|
||||
|
||||
// Verify webhooks
|
||||
await dashboard.treeView.openTable({ title: "Actor" });
|
||||
// await dashboard.webhookForm.open({})
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user