Browse Source

tests: playwright

pull/8708/head
Pranav C 2 weeks ago
parent
commit
d62f2cccfc
  1. 8
      packages/nc-gui/components/dashboard/settings/DataSources.vue
  2. 4
      packages/nc-gui/components/dashboard/settings/data-sources/CreateBase.vue
  3. 4
      packages/nc-gui/components/dashboard/settings/data-sources/EditBase.vue
  4. 44
      tests/playwright/pages/Dashboard/Settings/Source.ts
  5. 3
      tests/playwright/pages/Dashboard/Settings/index.ts
  6. 8
      tests/playwright/pages/Dashboard/TreeView.ts
  7. 83
      tests/playwright/tests/db/general/sourceRestrictions.spec.ts

8
packages/nc-gui/components/dashboard/settings/DataSources.vue

@ -260,7 +260,7 @@ const openedTab = ref('erd')
</script>
<template>
<div class="flex flex-col h-full">
<div class="flex flex-col h-full" data-testid="nc-settings-datasources-tab">
<div class="px-4 py-2 flex justify-between">
<a-breadcrumb separator=">" class="w-full cursor-pointer font-weight-bold">
<a-breadcrumb-item @click="activeSource = null">
@ -307,7 +307,7 @@ const openedTab = ref('erd')
<LazyDashboardSettingsBaseAudit :source-id="activeSource.id" />
</div>
</a-tab-pane>
<a-tab-pane v-if="!activeSource.is_meta && !activeSource.is_local" key="audit">
<a-tab-pane v-if="!activeSource.is_meta && !activeSource.is_local" key="edit">
<template #tab>
<div class="tab" data-testid="nc-connection-tab">
<div>{{ $t('labels.connectionDetails') }}</div>
@ -397,7 +397,7 @@ const openedTab = ref('erd')
<NcButton
v-if="!sources[0].is_meta && !sources[0].is_local"
size="small"
class="nc-action-btn cursor-pointer outline-0 !w-8 !px-1 !rounded-lg"
class="nc-action-btn nc-edit-base cursor-pointer outline-0 !w-8 !px-1 !rounded-lg"
type="text"
@click.stop="baseAction(sources[0].id, DataSourcesSubTab.Edit)"
>
@ -446,7 +446,7 @@ const openedTab = ref('erd')
<NcButton
v-if="!source.is_meta && !source.is_local"
size="small"
class="nc-action-btn cursor-pointer outline-0 !w-8 !px-1 !rounded-lg"
class="nc-action-btn nc-delete-base cursor-pointer outline-0 !w-8 !px-1 !rounded-lg"
type="text"
@click.stop="openDeleteBase(source)"
>

4
packages/nc-gui/components/dashboard/settings/data-sources/CreateBase.vue

@ -545,7 +545,7 @@ const allowDataWrite = computed({
</NcTooltip>
</div>
</template>
<a-switch v-model:checked="allowMetaWrite" size="small"></a-switch>
<a-switch v-model:checked="allowMetaWrite" data-testid="nc-allow-meta-write" size="small"></a-switch>
</a-form-item>
<a-form-item>
<template #label>
@ -561,7 +561,7 @@ const allowDataWrite = computed({
</NcTooltip>
</div>
</template>
<a-switch v-model:checked="allowDataWrite" size="small"></a-switch>
<a-switch v-model:checked="allowDataWrite" data-testid="nc-allow-data-write" size="small"></a-switch>
</a-form-item>
<div class="flex items-right justify-end gap-2">

4
packages/nc-gui/components/dashboard/settings/data-sources/EditBase.vue

@ -563,7 +563,7 @@ const allowDataWrite = computed({
</NcTooltip>
</div>
</template>
<a-switch v-model:checked="allowMetaWrite" size="small"></a-switch>
<a-switch v-model:checked="allowMetaWrite" data-testid="nc-allow-meta-write" size="small"></a-switch>
</a-form-item>
<a-form-item>
<template #label>
@ -579,7 +579,7 @@ const allowDataWrite = computed({
</NcTooltip>
</div>
</template>
<a-switch v-model:checked="allowDataWrite" size="small"></a-switch>
<a-switch v-model:checked="allowDataWrite" data-testid="nc-allow-data-write" size="small"></a-switch>
</a-form-item>
<!-- Use Connection URL -->
<div class="flex justify-end gap-2">

44
tests/playwright/pages/Dashboard/Settings/Source.ts

@ -0,0 +1,44 @@
import { expect } from '@playwright/test';
import { SettingsPage } from '.';
import BasePage from '../../Base';
export class SourcePage extends BasePage {
private readonly settings: SettingsPage;
constructor(settings: SettingsPage) {
super(settings.rootPage);
this.settings = settings;
}
get() {
return this.rootPage.getByTestId('nc-settings-datasources');
}
async openEditWindow({ sourceName }: { sourceName: string }) {
await this.get().locator('.ds-table-row', { hasText: sourceName }).click();
await this.get().getByTestId('nc-connection-tab').click();
}
async updateSchemaReadOnly({ sourceName, readOnly }: { sourceName: string; readOnly: boolean }) {
await this.openEditWindow({ sourceName });
const switchBtn = this.get().getByTestId('nc-allow-meta-write');
if (switchBtn.getAttribute('checked') !== readOnly.toString()) {
await switchBtn.click();
}
await this.saveConnection();
}
async updateDataReadOnly({ sourceName, readOnly = true }: { sourceName: string; readOnly?: boolean }) {
await this.openEditWindow({ sourceName });
const switchBtn = this.get().getByTestId('nc-allow-data-write');
if (switchBtn.getAttribute('checked') !== readOnly.toString()) {
await switchBtn.click();
}
await this.saveConnection();
}
async saveConnection() {
await this.get().locator('.nc-extdb-btn-test-connection').click();
await this.get().locator('.nc-extdb-btn-submit:enabled').click();
}
}

3
tests/playwright/pages/Dashboard/Settings/index.ts

@ -4,6 +4,7 @@ import { AuditSettingsPage } from './Audit';
import { MiscSettingsPage } from './Miscellaneous';
import { TeamsPage } from './Teams';
import { DataSourcesPage } from './DataSources';
import { SourcePage } from './Source';
export enum SettingTab {
TeamAuth = 'teamAndAuth',
@ -20,6 +21,7 @@ export enum SettingsSubTab {
export class SettingsPage extends BasePage {
readonly audit: AuditSettingsPage;
readonly source: SourcePage;
readonly miscellaneous: MiscSettingsPage;
readonly dataSources: DataSourcesPage;
readonly teams: TeamsPage;
@ -30,6 +32,7 @@ export class SettingsPage extends BasePage {
this.miscellaneous = new MiscSettingsPage(this);
this.dataSources = new DataSourcesPage(this);
this.teams = new TeamsPage(this);
this.source = new SourcePage(this);
}
get() {

8
tests/playwright/pages/Dashboard/TreeView.ts

@ -366,16 +366,12 @@ export class TreeViewPage extends BasePage {
await this.rootPage.locator('div.ant-modal-content').locator(`button.ant-btn:has-text("Delete")`).click();
}
async duplicateProject(param: { title: string; context: NcContext }) {
async openProjectSourceSettings(param: { title: string; context: NcContext }) {
param.title = this.scopedProjectTitle({ title: param.title, context: param.context });
await this.openProjectContextMenu({ baseTitle: param.title });
const contextMenu = this.dashboard.get().locator('.ant-dropdown-menu.nc-scrollbar-md:visible');
await contextMenu.waitFor();
await contextMenu.locator(`.ant-dropdown-menu-item:has-text("Duplicate")`).click();
await this.rootPage.locator('div.ant-modal-content').locator(`button.ant-btn:has-text("Confirm")`).click();
await this.rootPage.waitForTimeout(10000);
await contextMenu.locator(`.ant-dropdown-menu-item:has-text("Settings")`).click();
}
}

83
tests/playwright/tests/db/general/sourceRestrictions.spec.ts

@ -0,0 +1,83 @@
import { expect, test } from '@playwright/test';
import { DashboardPage } from '../../../pages/Dashboard';
import setup, { NcContext, unsetup } from '../../../setup';
import { Api } from 'nocodb-sdk';
import { SettingsPage } from '../../../pages/Dashboard/Settings';
test.describe('Source Restrictions', () => {
let dashboard: DashboardPage;
let settingsPage: SettingsPage;
let context: NcContext;
let api: Api<any>;
test.setTimeout(150000);
test.beforeEach(async ({ page }) => {
page.setDefaultTimeout(70000);
context = await setup({ page });
dashboard = new DashboardPage(page, context.base);
settingsPage = new SettingsPage(dashboard);
api = new Api({
baseURL: `http://localhost:8080/`,
headers: {
'xc-auth': context.token,
},
});
});
test.afterEach(async () => {
await unsetup(context);
});
test('Readonly data source', async () => {
await dashboard.treeView.openProjectSourceSettings({ title: context.defaultProjectTitle, context });
await settingsPage.selectTab({ tab: 'dataSources' });
await dashboard.rootPage.waitForTimeout(300);
await settingsPage.source.updateDataReadOnly({ sourceName: 'Default', readOnly: true });
await settingsPage.close();
// reload page to reflect source changes
await dashboard.rootPage.reload();
await dashboard.treeView.verifyTable({ title: 'Actor' });
// open table and verify that it is readonly
await dashboard.treeView.openTable({ title: 'Actor' });
await expect(dashboard.grid.get().locator('.nc-grid-add-new-cell')).toHaveCount(0);
await dashboard.grid.get().getByTestId(`cell-FirstName-0`).click({
button: 'right',
});
await expect(dashboard.rootPage.locator('.ant-dropdown-menu-item:has-text("Copy")')).toHaveCount(1);
await expect(dashboard.rootPage.locator('.ant-dropdown-menu-item:has-text("Delete record")')).toHaveCount(0);
});
test('Readonly schema source', async () => {
await dashboard.treeView.openProjectSourceSettings({ title: context.defaultProjectTitle, context });
await settingsPage.selectTab({ tab: 'dataSources' });
await dashboard.rootPage.waitForTimeout(300);
await settingsPage.source.updateSchemaReadOnly({ sourceName: 'Default', readOnly: true });
await settingsPage.close();
// reload page to reflect source changes
await dashboard.rootPage.reload();
await dashboard.treeView.verifyTable({ title: 'Actor' });
// open table and verify that it is readonly
await dashboard.treeView.openTable({ title: 'Actor' });
await dashboard.grid
.get()
.locator(`th[data-title="LastName"]`)
.first()
.locator('.nc-ui-dt-dropdown')
.scrollIntoViewIfNeeded();
await dashboard.grid.get().locator(`th[data-title="LastName"]`).first().locator('.nc-ui-dt-dropdown').click();
await expect(await dashboard.rootPage.locator('li[role="menuitem"]:has-text("Edit"):visible').last()).toBeVisible();
});
});
Loading…
Cancel
Save