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' ];