|
|
|
import { test, expect } 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 { GridPage } from "../pages/Dashboard/Grid";
|
|
|
|
import { SettingsErdPage } from "../pages/Dashboard/Settings/Erd";
|
|
|
|
|
|
|
|
test.describe("Erd", () => {
|
|
|
|
let dashboard: DashboardPage;
|
|
|
|
let context: any;
|
|
|
|
let project: any;
|
|
|
|
let sakilaTables, sakilaSqlViews;
|
|
|
|
|
|
|
|
// todo: Break the test into smaller tests
|
|
|
|
test.setTimeout(150000);
|
|
|
|
|
|
|
|
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}`);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// todo: Hack, edges are not getting rendered properly
|
|
|
|
const openSettingsErdWithEdgesRendered = async () => {
|
|
|
|
await dashboard.gotoSettings();
|
|
|
|
await dashboard.settings.selectTab({tab: SettingTab.ProjectMetadata, subTab: SettingsSubTab.Miscellaneous});
|
|
|
|
await dashboard.settings.miscellaneous.clickShowM2MTables();
|
|
|
|
|
|
|
|
await dashboard.settings.selectSubTab({subTab: SettingsSubTab.ERD});
|
|
|
|
// Todo: Otherwise edges wont be rendered
|
|
|
|
await dashboard.rootPage.waitForTimeout(800);
|
|
|
|
await dashboard.settings.selectSubTab({subTab: SettingsSubTab.Miscellaneous});
|
|
|
|
await dashboard.rootPage.waitForTimeout(800);
|
|
|
|
await dashboard.settings.selectSubTab({subTab: SettingsSubTab.ERD});
|
|
|
|
|
|
|
|
// Todo: Otherwise edges wont be rendered
|
|
|
|
await dashboard.rootPage.waitForTimeout(200);
|
|
|
|
}
|
|
|
|
|
|
|
|
// todo: remove this. Need for edges to be rendered
|
|
|
|
const openErdOfATableWithEdgesRendered = async (tableName: string) => {
|
|
|
|
await dashboard.treeView.openTable({title: tableName});
|
|
|
|
await dashboard.grid.toolbar.clickActions();
|
|
|
|
await dashboard.rootPage.waitForTimeout(1000);
|
|
|
|
await dashboard.grid.toolbar.actions.click("ERD View");
|
|
|
|
await dashboard.grid.toolbar.actions.erd.close();
|
|
|
|
|
|
|
|
await dashboard.treeView.openTable({title: 'Actor'});
|
|
|
|
await dashboard.grid.toolbar.clickActions();
|
|
|
|
await dashboard.rootPage.waitForTimeout(1000);
|
|
|
|
await dashboard.grid.toolbar.actions.click("ERD View");
|
|
|
|
await dashboard.grid.toolbar.actions.erd.close();
|
|
|
|
|
|
|
|
await dashboard.treeView.openTable({title: tableName});
|
|
|
|
await dashboard.grid.toolbar.clickActions();
|
|
|
|
await dashboard.rootPage.waitForTimeout(1000);
|
|
|
|
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 openSettingsErdWithEdgesRendered();
|
|
|
|
|
|
|
|
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 openErdOfATableWithEdgesRendered("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 openSettingsErdWithEdgesRendered();
|
|
|
|
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.rootPage.waitForTimeout(1000);
|
|
|
|
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 openSettingsErdWithEdgesRendered();
|
|
|
|
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.rootPage.waitForTimeout(1000);
|
|
|
|
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 openSettingsErdWithEdgesRendered();
|
|
|
|
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 openSettingsErdWithEdgesRendered();
|
|
|
|
await dashboard.settings.close()
|
|
|
|
|
|
|
|
await dashboard.treeView.openTable({title: "Country"});
|
|
|
|
await dashboard.grid.toolbar.clickActions();
|
|
|
|
await dashboard.rootPage.waitForTimeout(1000);
|
|
|
|
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 openSettingsErdWithEdgesRendered();
|
|
|
|
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 openSettingsErdWithEdgesRendered();
|
|
|
|
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.erd.dbClickShowColumnNames();
|
|
|
|
await dashboard.settings.erd.verifyEasterEggNotShown();
|
|
|
|
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'
|
|
|
|
];
|