|
|
|
import { test } from '@playwright/test';
|
|
|
|
import {
|
|
|
|
mysqlSakilaSqlViews,
|
|
|
|
mysqlSakilaTables,
|
|
|
|
pgSakilaSqlViews,
|
|
|
|
pgSakilaTables,
|
|
|
|
sqliteSakilaSqlViews,
|
|
|
|
} from './utils/sakila';
|
|
|
|
import { DashboardPage } from '../pages/Dashboard';
|
|
|
|
import { SettingsSubTab, SettingTab } from '../pages/Dashboard/Settings';
|
|
|
|
import setup from '../setup';
|
|
|
|
import { isMysql, isPg, isSqlite } from '../setup/db';
|
|
|
|
import { SettingsErdPage } from '../pages/Dashboard/Settings/Erd';
|
|
|
|
|
|
|
|
test.describe('Erd', () => {
|
|
|
|
let dashboard: DashboardPage;
|
|
|
|
let context: any;
|
|
|
|
let project: any;
|
|
|
|
let sakilaTables, sakilaSqlViews;
|
|
|
|
|
|
|
|
test.slow();
|
|
|
|
|
|
|
|
test.beforeEach(async ({ page }) => {
|
|
|
|
context = await setup({ page });
|
|
|
|
dashboard = new DashboardPage(page, context.project);
|
|
|
|
|
|
|
|
project = context.project;
|
|
|
|
if (isPg(context)) {
|
|
|
|
sakilaTables = pgSakilaTables;
|
|
|
|
sakilaSqlViews = pgSakilaSqlViews;
|
|
|
|
} else if (isMysql(context)) {
|
|
|
|
sakilaTables = mysqlSakilaTables;
|
|
|
|
sakilaSqlViews = mysqlSakilaSqlViews;
|
|
|
|
} else if (isSqlite(context)) {
|
|
|
|
sakilaTables = mysqlSakilaTables.map(tableName => `${project.prefix}${tableName}`);
|
|
|
|
sakilaSqlViews = sqliteSakilaSqlViews.map(viewName => `${project.prefix}${viewName}`);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
const enableMM = async () => {
|
|
|
|
await dashboard.settings.selectTab({ tab: SettingTab.ProjectMetadata, subTab: SettingsSubTab.Miscellaneous });
|
|
|
|
await dashboard.settings.miscellaneous.clickShowM2MTables();
|
|
|
|
await dashboard.settings.selectSubTab({ subTab: SettingsSubTab.ERD });
|
|
|
|
};
|
|
|
|
|
|
|
|
const openSettingsErd = async () => {
|
|
|
|
await dashboard.gotoSettings();
|
|
|
|
await dashboard.settings.selectTab({ tab: SettingTab.ProjectMetadata, subTab: SettingsSubTab.ERD });
|
|
|
|
};
|
|
|
|
|
|
|
|
const openErdOfATable = async (tableName: string) => {
|
|
|
|
await dashboard.treeView.openTable({ title: tableName });
|
|
|
|
await dashboard.grid.toolbar.clickActions();
|
|
|
|
await dashboard.grid.toolbar.actions.click('ERD View');
|
|
|
|
};
|
|
|
|
|
|
|
|
test('Verify default config, all columns disabled, only PK and FK disabled, Sql views and MM table option, junction table names', async () => {
|
|
|
|
await openSettingsErd();
|
|
|
|
await enableMM();
|
|
|
|
|
|
|
|
const erd: SettingsErdPage = dashboard.settings.erd;
|
|
|
|
|
|
|
|
await erd.dbClickShowColumnNames();
|
|
|
|
|
|
|
|
if (isPg(context)) {
|
|
|
|
await erd.verifyNodesCount(mysqlSakilaTables.length);
|
|
|
|
await erd.verifyEdgesCount({
|
|
|
|
count: 32,
|
|
|
|
circleCount: 29,
|
|
|
|
rectangleCount: 35,
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
await erd.verifyNodesCount(mysqlSakilaTables.length);
|
|
|
|
await erd.verifyEdgesCount({
|
|
|
|
count: 14,
|
|
|
|
circleCount: 11,
|
|
|
|
rectangleCount: 17,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
for (const tableName of sakilaTables) {
|
|
|
|
await erd.verifyNode({ tableName });
|
|
|
|
}
|
|
|
|
|
|
|
|
// Verify Actor table
|
|
|
|
await erd.verifyColumns({
|
|
|
|
tableName: `${isSqlite(context) ? project.prefix : ''}actor`,
|
|
|
|
columns: actorTableColumn,
|
|
|
|
});
|
|
|
|
|
|
|
|
// Verify Payment table
|
|
|
|
await erd.verifyColumns({
|
|
|
|
tableName: `${isSqlite(context) ? project.prefix : ''}payment`,
|
|
|
|
columns: isPg(context) ? pgPaymentTableColumns : mysqlPaymentTableColumns,
|
|
|
|
});
|
|
|
|
|
|
|
|
// Disable show column names and pk/fk
|
|
|
|
// todo: rerender edges, otherwise some edges wont be rendered
|
|
|
|
await erd.clickShowColumnNames();
|
|
|
|
await erd.clickShowJunctionTableNames();
|
|
|
|
await erd.clickShowJunctionTableNames();
|
|
|
|
|
|
|
|
await erd.verifyColumns({
|
|
|
|
tableName: `${isSqlite(context) ? project.prefix : ''}actor`,
|
|
|
|
columns: actorLTARColumns,
|
|
|
|
});
|
|
|
|
await erd.verifyColumns({
|
|
|
|
tableName: `${isSqlite(context) ? project.prefix : ''}payment`,
|
|
|
|
columns: paymentLTARColumns,
|
|
|
|
});
|
|
|
|
|
|
|
|
// Enable show column names and disable pk/fk
|
|
|
|
await erd.clickShowColumnNames();
|
|
|
|
await erd.clickShowPkAndFk();
|
|
|
|
|
|
|
|
await erd.verifyColumns({
|
|
|
|
tableName: `${isSqlite(context) ? project.prefix : ''}actor`,
|
|
|
|
columns: actorNonPkFkColumns,
|
|
|
|
});
|
|
|
|
await erd.verifyColumns({
|
|
|
|
tableName: `${isSqlite(context) ? project.prefix : ''}payment`,
|
|
|
|
columns: isPg(context) ? pgPaymentNonPkFkColumns : paymentNonPkFkColumns,
|
|
|
|
});
|
|
|
|
|
|
|
|
await erd.clickShowPkAndFk();
|
|
|
|
// Verify views
|
|
|
|
await erd.clickShowSqlViews();
|
|
|
|
if (isPg(context)) {
|
|
|
|
await erd.verifyNodesCount(sakilaTables.length + sakilaSqlViews.length);
|
|
|
|
await erd.verifyEdgesCount({
|
|
|
|
count: 32,
|
|
|
|
circleCount: 29,
|
|
|
|
rectangleCount: 35,
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
await erd.verifyNodesCount(sakilaTables.length + sakilaSqlViews.length);
|
|
|
|
await erd.verifyEdgesCount({
|
|
|
|
count: 14,
|
|
|
|
circleCount: 11,
|
|
|
|
rectangleCount: 17,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const tableName of [...sakilaTables, ...sakilaSqlViews]) {
|
|
|
|
await erd.verifyNode({ tableName });
|
|
|
|
}
|
|
|
|
|
|
|
|
// Verify ActorInfo SQL View
|
|
|
|
await erd.verifyColumns({
|
|
|
|
tableName: `${isSqlite(context) ? project.prefix : ''}sales_by_store`,
|
|
|
|
columns: salesByStoreColumns,
|
|
|
|
});
|
|
|
|
|
|
|
|
await erd.clickShowSqlViews(); // disable sql views
|
|
|
|
|
|
|
|
await erd.verifyNodeDoesNotExist({ tableName: `${isSqlite(context) ? project.prefix : ''}store` });
|
|
|
|
|
|
|
|
// // Verify MM tables
|
|
|
|
await erd.clickShowMMTables();
|
|
|
|
await erd.clickShowJunctionTableNames();
|
|
|
|
await erd.clickShowJunctionTableNames();
|
|
|
|
|
|
|
|
await erd.verifyNodesCount(isPg(context) ? 21 : 16);
|
|
|
|
await erd.verifyEdgesCount({
|
|
|
|
count: isPg(context) ? 44 : 26,
|
|
|
|
circleCount: isPg(context) ? 40 : 22,
|
|
|
|
rectangleCount: isPg(context) ? 48 : 30,
|
|
|
|
});
|
|
|
|
|
|
|
|
await erd.verifyNode({ tableName: `${isSqlite(context) ? project.prefix : ''}store` });
|
|
|
|
|
|
|
|
// Verify show junction table names
|
|
|
|
await erd.clickShowJunctionTableNames();
|
|
|
|
await erd.verifyJunctionTableLabel({
|
|
|
|
tableName: `${isSqlite(context) ? project.prefix : ''}film_actor`,
|
|
|
|
tableTitle: 'filmactor',
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
test('Verify ERD Table view, and verify column operations are reflected to the ERD view', async () => {
|
|
|
|
await openErdOfATable('Country');
|
|
|
|
const erd = dashboard.grid.toolbar.actions.erd;
|
|
|
|
|
|
|
|
// Verify tables with default config
|
|
|
|
await erd.verifyColumns({
|
|
|
|
tableName: `${isSqlite(context) ? project.prefix : ''}country`,
|
|
|
|
columns: ['country_id', 'country', 'last_update', 'city_list'],
|
|
|
|
});
|
|
|
|
|
|
|
|
await erd.verifyColumns({
|
|
|
|
tableName: `${isSqlite(context) ? project.prefix : ''}city`,
|
|
|
|
columns: ['city_id', 'city', 'country_id', 'last_update', 'country', 'address_list'],
|
|
|
|
});
|
|
|
|
|
|
|
|
// Verify with PK/FK disabled
|
|
|
|
await erd.clickShowPkAndFk();
|
|
|
|
await erd.verifyColumns({
|
|
|
|
tableName: `${isSqlite(context) ? project.prefix : ''}country`,
|
|
|
|
columns: ['country', 'last_update', 'city_list'],
|
|
|
|
});
|
|
|
|
|
|
|
|
await erd.verifyColumns({
|
|
|
|
tableName: `${isSqlite(context) ? project.prefix : ''}city`,
|
|
|
|
columns: ['city', 'last_update', 'country', 'address_list'],
|
|
|
|
});
|
|
|
|
|
|
|
|
// Verify with all columns disabled
|
|
|
|
await erd.clickShowColumnNames();
|
|
|
|
await erd.verifyColumns({ tableName: `${isSqlite(context) ? project.prefix : ''}country`, columns: ['city_list'] });
|
|
|
|
|
|
|
|
await erd.verifyColumns({
|
|
|
|
tableName: `${isSqlite(context) ? project.prefix : ''}city`,
|
|
|
|
columns: ['country', 'address_list'],
|
|
|
|
});
|
|
|
|
|
|
|
|
// Enable All columns
|
|
|
|
await erd.clickShowColumnNames();
|
|
|
|
|
|
|
|
await erd.close();
|
|
|
|
|
|
|
|
// Add column
|
|
|
|
await dashboard.grid.column.create({ title: 'test_column' });
|
|
|
|
// Verify in Settings ERD and table ERD
|
|
|
|
await openSettingsErd();
|
|
|
|
await dashboard.settings.erd.verifyNode({
|
|
|
|
tableName: `${isSqlite(context) ? project.prefix : ''}country`,
|
|
|
|
columnName: 'test_column',
|
|
|
|
});
|
|
|
|
await dashboard.settings.close();
|
|
|
|
|
|
|
|
await dashboard.treeView.openTable({ title: 'Country' });
|
|
|
|
await dashboard.grid.toolbar.clickActions();
|
|
|
|
await dashboard.grid.toolbar.actions.click('ERD View');
|
|
|
|
await dashboard.grid.toolbar.actions.erd.verifyNode({
|
|
|
|
tableName: `${isSqlite(context) ? project.prefix : ''}country`,
|
|
|
|
columnName: 'test_column',
|
|
|
|
});
|
|
|
|
await dashboard.grid.toolbar.actions.erd.close();
|
|
|
|
|
|
|
|
// Update column
|
|
|
|
await dashboard.grid.column.openEdit({ title: 'test_column' });
|
|
|
|
await dashboard.grid.column.fillTitle({ title: 'new_test_column' });
|
|
|
|
await dashboard.grid.column.save({
|
|
|
|
isUpdated: true,
|
|
|
|
});
|
|
|
|
// Verify in Settings ERD and table ERD
|
|
|
|
await openSettingsErd();
|
|
|
|
await dashboard.settings.erd.verifyNode({
|
|
|
|
tableName: `${isSqlite(context) ? project.prefix : ''}country`,
|
|
|
|
columnName: 'new_test_column',
|
|
|
|
});
|
|
|
|
await dashboard.settings.close();
|
|
|
|
|
|
|
|
await dashboard.treeView.openTable({ title: 'Country' });
|
|
|
|
await dashboard.grid.toolbar.clickActions();
|
|
|
|
await dashboard.grid.toolbar.actions.click('ERD View');
|
|
|
|
await dashboard.grid.toolbar.actions.erd.verifyNode({
|
|
|
|
tableName: `${isSqlite(context) ? project.prefix : ''}country`,
|
|
|
|
columnName: 'new_test_column',
|
|
|
|
});
|
|
|
|
await dashboard.grid.toolbar.actions.erd.close();
|
|
|
|
|
|
|
|
// Delete column
|
|
|
|
await dashboard.grid.column.delete({ title: 'new_test_column' });
|
|
|
|
// Verify in Settings ERD and table ERD
|
|
|
|
await openSettingsErd();
|
|
|
|
await dashboard.settings.erd.verifyNode({
|
|
|
|
tableName: `${isSqlite(context) ? project.prefix : ''}country`,
|
|
|
|
columnNameShouldNotExist: 'new_test_column',
|
|
|
|
});
|
|
|
|
await dashboard.settings.close();
|
|
|
|
});
|
|
|
|
|
|
|
|
test('Verify table operations sync with ERD', async () => {
|
|
|
|
await openSettingsErd();
|
|
|
|
await dashboard.settings.close();
|
|
|
|
|
|
|
|
await dashboard.treeView.openTable({ title: 'Country' });
|
|
|
|
await dashboard.grid.toolbar.clickActions();
|
|
|
|
await dashboard.grid.toolbar.actions.click('ERD View');
|
|
|
|
await dashboard.grid.toolbar.actions.erd.verifyNode({
|
|
|
|
tableName: `${isSqlite(context) ? project.prefix : ''}country`,
|
|
|
|
columnNameShouldNotExist: 'new_test_column',
|
|
|
|
});
|
|
|
|
await dashboard.grid.toolbar.actions.erd.close();
|
|
|
|
|
|
|
|
// Create table and verify ERD
|
|
|
|
await dashboard.treeView.createTable({ title: 'Test' });
|
|
|
|
// Verify in Settings ERD and table ERD
|
|
|
|
await openSettingsErd();
|
|
|
|
await dashboard.settings.erd.verifyNode({
|
|
|
|
tableName: `${isSqlite(context) ? project.prefix : ''}Test`,
|
|
|
|
});
|
|
|
|
await dashboard.settings.close();
|
|
|
|
|
|
|
|
// Delete table and verify ERD
|
|
|
|
await dashboard.treeView.deleteTable({ title: 'Test' });
|
|
|
|
await openSettingsErd();
|
|
|
|
await dashboard.settings.erd.verifyNodeDoesNotExist({
|
|
|
|
tableName: `${isSqlite(context) ? project.prefix : ''}Test`,
|
|
|
|
});
|
|
|
|
|
|
|
|
// Verify that `show mm table` option disabled will not trigger easter in ERD options
|
|
|
|
await dashboard.settings.selectSubTab({ subTab: SettingsSubTab.Miscellaneous });
|
|
|
|
await dashboard.settings.miscellaneous.clickShowM2MTables(); // disable
|
|
|
|
await dashboard.settings.selectSubTab({ subTab: SettingsSubTab.ERD });
|
|
|
|
await dashboard.settings.close();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
const actorTableColumn = ['actor_id', 'first_name', 'last_name', 'last_update', 'film_list'];
|
|
|
|
|
|
|
|
const mysqlPaymentTableColumns = [
|
|
|
|
'payment_id',
|
|
|
|
'customer_id',
|
|
|
|
'staff_id',
|
|
|
|
'rental_id',
|
|
|
|
'amount',
|
|
|
|
'payment_date',
|
|
|
|
'last_update',
|
|
|
|
'customer',
|
|
|
|
'rental',
|
|
|
|
'staff',
|
|
|
|
];
|
|
|
|
|
|
|
|
const pgPaymentTableColumns = [
|
|
|
|
'payment_id',
|
|
|
|
'customer_id',
|
|
|
|
'staff_id',
|
|
|
|
'rental_id',
|
|
|
|
'amount',
|
|
|
|
'payment_date',
|
|
|
|
'customer',
|
|
|
|
'rental',
|
|
|
|
'staff',
|
|
|
|
];
|
|
|
|
|
|
|
|
const actorLTARColumns = ['filmactor_list', 'film_list'];
|
|
|
|
|
|
|
|
const actorNonPkFkColumns = ['first_name', 'last_name', 'last_update', 'film_list', 'filmactor_list'];
|
|
|
|
|
|
|
|
const paymentLTARColumns = ['customer', 'rental', 'staff'];
|
|
|
|
|
|
|
|
const pgPaymentNonPkFkColumns = ['amount', 'payment_date', 'customer', 'rental', 'staff'];
|
|
|
|
const paymentNonPkFkColumns = [...pgPaymentNonPkFkColumns, 'last_update'];
|
|
|
|
|
|
|
|
const salesByStoreColumns = ['store', 'manager', 'total_sales'];
|