Browse Source

feat(testing): Added tests for view

pull/3848/head
Muhammed Mustafa 2 years ago
parent
commit
75389f1400
  1. 5
      packages/nc-gui/components/smartsheet/sidebar/RenameableMenuItem.vue
  2. 2
      packages/nc-gui/components/smartsheet/sidebar/index.vue
  3. 22
      scripts/playwright/pages/Base.ts
  4. 12
      scripts/playwright/pages/Dashboard/Grid/Cell/index.ts
  5. 90
      scripts/playwright/pages/Dashboard/ViewSidebar/index.ts
  6. 7
      scripts/playwright/pages/Dashboard/index.ts
  7. 35
      scripts/playwright/tests/views.spec.ts

5
packages/nc-gui/components/smartsheet/sidebar/RenameableMenuItem.vue

@ -167,11 +167,12 @@ function onStopEdit() {
<template>
<a-menu-item
class="select-none group !flex !items-center !my-0 hover:(bg-primary !bg-opacity-5)"
:pw-data="`view-sidebar-view-${vModel.alias || vModel.title}`"
@dblclick.stop="onDblClick"
@click.stop="onClick"
>
<div v-e="['a:view:open', { view: vModel.type }]" class="text-xs flex items-center w-full gap-2">
<div class="flex w-auto">
<div class="flex w-auto" :pw-data="`view-sidebar-drag-handle-${vModel.alias || vModel.title}`">
<MdiDrag
class="nc-drag-icon hidden group-hover:block transition-opacity opacity-0 group-hover:opacity-100 text-gray-500 !cursor-move"
@click.stop.prevent
@ -193,7 +194,7 @@ function onStopEdit() {
<div class="flex-1" />
<template v-if="!isEditing && !isLocked && isUIAllowed('virtualViewsCreateOrEdit')">
<div class="flex items-center gap-1">
<div class="flex items-center gap-1" :pw-data="`view-sidebar-view-actions-${vModel.alias || vModel.title}`">
<a-tooltip placement="left">
<template #title>
{{ $t('activity.copyView') }}

2
packages/nc-gui/components/smartsheet/sidebar/index.vue

@ -121,7 +121,7 @@ function onOpenModal({
collapsiple
collapsed-width="0"
width="0"
class="relative shadow h-full w-full !flex-1 !min-w-0 !max-w-[150px] !w-[150px] lg:(!max-w-[250px] !w-[250px])"
class="nc-view-sidebar relative shadow h-full w-full !flex-1 !min-w-0 !max-w-[150px] !w-[150px] lg:(!max-w-[250px] !w-[250px])"
theme="light"
>
<LazySmartsheetSidebarToolbar

22
scripts/playwright/pages/Base.ts

@ -17,4 +17,26 @@ export default abstract class BasePage {
await this.rootPage.locator('.ant-message .ant-message-notice-content', {hasText: message}).last().textContent()
.then((text) => expect(text).toContain(message));
}
async assertInnerTextWithRetry({locator, text, retryCount = 5, retryInterval = 100}: {locator: Locator, text: string, retryCount?: number, retryInterval?: number}) {
for(let i = 0; i < retryCount; i++) {
const innerText = await locator.innerText();
if(innerText === text) {
break;
}
await this.rootPage.waitForTimeout(retryInterval);
}
return expect(await locator.innerText()).toBe(text);
}
async assertNotInnerTextWithRetry({locator, text, retryCount = 5, retryInterval = 100}: {locator: Locator, text: string, retryCount?: number, retryInterval?: number}) {
for(let i = 0; i < retryCount; i++) {
const innerText = await locator.innerText();
if(innerText !== text) {
break;
}
await this.rootPage.waitForTimeout(retryInterval);
}
return expect(await locator.innerText()).not.toBe(text);
}
}

12
scripts/playwright/pages/Dashboard/Grid/Cell/index.ts

@ -1,4 +1,4 @@
import { Page, Locator,expect } from "@playwright/test";
import { Locator } from "@playwright/test";
import { GridPage } from "..";
import BasePage from "../../../Base";
import { SelectOptionCellPageObject } from "./SelectOptionCell";
@ -26,14 +26,6 @@ export class CellPageObject extends BasePage {
}
async verify({index, columnHeader, value}: {index: number, columnHeader: string, value: string}) {
// todo: Move this polling logic to a different place
for(let i = 0; i < 5; i++) {
const innerText = await this.get({index, columnHeader}).innerText();
if(innerText === value) {
break;
}
await this.rootPage.waitForTimeout(100);
}
return expect(await this.get({index, columnHeader}).innerText()).toBe(value);
return await this.assertInnerTextWithRetry({locator: this.get({index, columnHeader}), text: value});
}
}

90
scripts/playwright/pages/Dashboard/ViewSidebar/index.ts

@ -0,0 +1,90 @@
// playwright-dev-page.ts
import { Locator, Page, expect } from "@playwright/test";
import { DashboardPage } from "..";
import BasePage from "../../Base";
export class ViewSidebarPage extends BasePage {
readonly project: any;
readonly dashboard: DashboardPage;
readonly createGalleryButton: Locator;
readonly createGridButton: Locator;
readonly createFormButton: Locator;
readonly createKanbanButton: Locator;
constructor(dashboard: DashboardPage) {
super(dashboard.rootPage);
this.dashboard = dashboard;
this.createGalleryButton = this.get().locator('.nc-create-gallery-view');
this.createGridButton = this.get().locator('.nc-create-grid-view');
this.createFormButton = this.get().locator('.nc-create-form-view');
this.createKanbanButton = this.get().locator('.nc-create-kanban-view');
}
get() {
return this.dashboard.get().locator('.nc-view-sidebar');
}
private async createView({ title, locator }: { title: string, locator: Locator }) {
await locator.click();
await this.rootPage.locator('input[id="form_item_title"]').fill(title);
await this.rootPage.locator('.ant-modal-content').locator('button:has-text("Submit")').click();
await this.toastWait({ message: 'View created successfully'});
}
async createGalleryView({ title }: { title: string }) {
await this.createView({ title, locator: this.createGalleryButton });
}
async createGridView({ title }: { title: string }) {
await this.createView({ title, locator: this.createGridButton });
}
async createFormView({ title }: { title: string }) {
await this.createView({ title, locator: this.createFormButton });
}
async createKanbanView({ title }: { title: string }) {
await this.createView({ title, locator: this.createKanbanButton });
}
async verifyView({ title, index }: { title: string, index: number }) {
return await this.assertInnerTextWithRetry({
locator: this.get().locator(`.nc-views-menu`).locator('.ant-menu-title-content').nth(index),
text: title,
})
}
async verifyViewNotPresent({ title, index }: { title: string, index: number }) {
const viewList = this.get().locator(`.nc-views-menu`).locator('.ant-menu-title-content');
if(await viewList.count() <= index) {
return true
}
return await this.assertNotInnerTextWithRetry({
locator: this.get().locator(`.nc-views-menu`).locator('.ant-menu-title-content').nth(index),
text: title,
})
}
async reorderViews({sourceView, destinationView}: {
sourceView: string,
destinationView: string,
}) {
await this.dashboard.get().locator(`[pw-data="view-sidebar-drag-handle-${sourceView}"]`).dragTo(
this.get().locator(`[pw-data="view-sidebar-view-${destinationView}"]`),
);
}
async deleteView({ title }: { title: string }) {
await this.get().locator(`[pw-data="view-sidebar-view-${title}"]`).hover();
await this.get()
.locator(`[pw-data="view-sidebar-view-actions-${title}"]`)
.locator('.nc-view-delete-icon')
.click();
await this.rootPage.locator('.nc-modal-view-delete').locator('button:has-text("Submit")').click();
await this.rootPage.locator('.nc-modal-view-delete').locator('button:has-text("Submit")').waitFor({ state: 'detached' });
await this.toastWait({ message: 'View deleted successfully'});
}
}

7
scripts/playwright/pages/Dashboard/index.ts

@ -5,6 +5,7 @@ import { GridPage } from "./Grid";
import { ExpandedFormPage } from "./ExpandedForm";
import { TreeViewPage } from "./TreeView";
import { SettingsPage } from "./Settings";
import { ViewSidebarPage } from "./ViewSideBar";
export class DashboardPage extends BasePage {
readonly project: any;
@ -14,9 +15,10 @@ export class DashboardPage extends BasePage {
readonly grid: GridPage;
readonly expandedForm: ExpandedFormPage;
readonly settings: SettingsPage;
readonly viewSidebar: ViewSidebarPage;
constructor(rootPage: Page, project: any) {
super(rootPage);
super(rootPage);
this.project = project;
this.tablesSideBar = rootPage.locator(".nc-treeview-container");
this.tabBar = rootPage.locator(".nc-tab-bar");
@ -24,6 +26,7 @@ export class DashboardPage extends BasePage {
this.grid = new GridPage(this);
this.expandedForm = new ExpandedFormPage(this);
this.settings = new SettingsPage(this);
this.viewSidebar = new ViewSidebarPage(this);
}
get() {
@ -41,7 +44,7 @@ export class DashboardPage extends BasePage {
.click();
}
async verifyTableIsInTabBar({ title }: { title: string }) {
async verifyInTabBar({ title }: { title: string }) {
await this.tabBar
.textContent()
.then((text) => expect(text).toContain(title));

35
scripts/playwright/tests/views.spec.ts

@ -1,20 +1,45 @@
import { test } from '@playwright/test';
import { DashboardPage } from '../pages/Dashboard';
import { SettingsPage } from '../pages/Dashboard/Settings';
import setup from '../setup';
test.describe.skip('Views', () => {
let dashboard: DashboardPage, settings: SettingsPage;
test.describe('Views', () => {
let dashboard: DashboardPage;
let context: any;
test.beforeEach(async ({page}) => {
context = await setup({ page });
dashboard = new DashboardPage(page, context.project);
settings = new SettingsPage(page);
})
test('Create, and delete table, verify in audit tab, rename City table and reorder tables', async () => {
test('Create views, reorder and delete', async () => {
await dashboard.treeView.openTable({title: "City"});
await dashboard.viewSidebar.createGridView({title: "CityGrid"});
await dashboard.viewSidebar.verifyView({title: "CityGrid", index: 1});
await dashboard.viewSidebar.createFormView({title: "CityForm"});
await dashboard.viewSidebar.verifyView({title: "CityForm", index: 2});
await dashboard.viewSidebar.createGalleryView({title: "CityGallery"});
await dashboard.viewSidebar.verifyView({title: "CityGallery", index: 3});
await dashboard.viewSidebar.reorderViews({
sourceView: "CityGrid",
destinationView: "CityForm"
});
await dashboard.viewSidebar.verifyView({title: "CityGrid", index: 2});
await dashboard.viewSidebar.verifyView({title: "CityForm", index: 1});
await dashboard.viewSidebar.deleteView({title: "CityForm"});
await dashboard.viewSidebar.verifyViewNotPresent({title: "CityForm", index: 1});
// todo: Delete form view is deleting grid view. Probably a bug.
// await dashboard.viewSidebar.deleteView({title: "CityGrid"});
// await dashboard.viewSidebar.verifyViewNotPresent({title: "CityGrid", index: 1});
await dashboard.viewSidebar.deleteView({title: "CityGallery"});
await dashboard.viewSidebar.verifyViewNotPresent({title: "CityGallery", index: 1});
});
});

Loading…
Cancel
Save