From 160fa61b22993d5cd271d43903fe5072e2f3778c Mon Sep 17 00:00:00 2001 From: Raju Udava <86527202+dstala@users.noreply.github.com> Date: Sat, 6 May 2023 12:18:57 +0530 Subject: [PATCH] test: extDB corrections Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com> --- tests/playwright/pages/Dashboard/TreeView.ts | 5 +- tests/playwright/tests/db/timezone.spec.ts | 233 +++++-------------- tests/playwright/tests/utils/config.ts | 48 ++++ 3 files changed, 115 insertions(+), 171 deletions(-) create mode 100644 tests/playwright/tests/utils/config.ts diff --git a/tests/playwright/pages/Dashboard/TreeView.ts b/tests/playwright/pages/Dashboard/TreeView.ts index 169918f93d..f294ec8f7b 100644 --- a/tests/playwright/pages/Dashboard/TreeView.ts +++ b/tests/playwright/pages/Dashboard/TreeView.ts @@ -57,12 +57,13 @@ export class TreeViewPage extends BasePage { // check if nodeTitle contains title if (nodeTitle.includes(title)) { // click on node + await node.waitFor({ state: 'visible' }); await node.click(); break; } } - await this.rootPage.waitForTimeout(1000); + await this.rootPage.waitForTimeout(5000); } // assumption: first view rendered is always GRID @@ -89,6 +90,8 @@ export class TreeViewPage extends BasePage { } } + await this.get().locator(`.nc-project-tree-tbl-${title}`).waitFor({ state: 'visible' }); + if (networkResponse === true) { await this.waitForResponse({ uiAction: () => this.get().locator(`.nc-project-tree-tbl-${title}`).click(), diff --git a/tests/playwright/tests/db/timezone.spec.ts b/tests/playwright/tests/db/timezone.spec.ts index 86b05c53b4..d58c3a2434 100644 --- a/tests/playwright/tests/db/timezone.spec.ts +++ b/tests/playwright/tests/db/timezone.spec.ts @@ -5,6 +5,7 @@ import { knex } from 'knex'; import { Api, UITypes } from 'nocodb-sdk'; import { ProjectsPage } from '../../pages/ProjectsPage'; import { isMysql, isPg, isSqlite } from '../../setup/db'; +import { getKnexConfig } from '../utils/config'; let api: Api, records: any[]; const columns = [ @@ -343,27 +344,9 @@ test.describe('Timezone', () => { async function createTableWithDateTimeColumn(database: string) { if (database === 'pg') { - const config = { - client: 'pg', - connection: { - host: 'localhost', - port: 5432, - user: 'postgres', - password: 'password', - database: 'postgres', - multipleStatements: true, - }, - searchPath: ['public', 'information_schema'], - pool: { min: 0, max: 5 }, - }; - - const config2 = { - ...config, - connection: { - ...config.connection, - database: 'datetimetable', - }, - }; + const config = getKnexConfig({ dbName: 'postgres', dbType: 'pg' }); + const config2 = getKnexConfig({ dbName: 'datetimetable', dbType: 'pg' }); + const pgknex = knex(config); await pgknex.raw(`DROP DATABASE IF EXISTS datetimetable`); await pgknex.raw(`CREATE DATABASE datetimetable`); @@ -376,35 +359,17 @@ async function createTableWithDateTimeColumn(database: string) { datetime_without_tz TIMESTAMP WITHOUT TIME ZONE, datetime_with_tz TIMESTAMP WITH TIME ZONE ); - SET timezone = 'Asia/Hong_Kong'; - SELECT pg_sleep(1); + -- SET timezone = 'Asia/Hong_Kong'; + -- SELECT pg_sleep(1); INSERT INTO my_table (datetime_without_tz, datetime_with_tz) VALUES - ('2023-04-27 10:00:00', '2023-04-27 12:30:00'), + ('2023-04-27 10:00:00', '2023-04-27 10:00:00'), ('2023-04-27 10:00:00+05:30', '2023-04-27 10:00:00+05:30'); `); await pgknex2.destroy(); } else if (database === 'mysql') { - const config = { - client: 'mysql2', - connection: { - host: 'localhost', - port: 3306, - user: 'root', - password: 'password', - database: 'sakila', - multipleStatements: true, - }, - pool: { min: 0, max: 5 }, - }; - - const config2 = { - ...config, - connection: { - ...config.connection, - database: 'datetimetable', - }, - }; + const config = getKnexConfig({ dbName: 'sakila', dbType: 'mysql' }); + const config2 = getKnexConfig({ dbName: 'datetimetable', dbType: 'mysql' }); const mysqlknex = knex(config); await mysqlknex.raw(`DROP DATABASE IF EXISTS datetimetable`); @@ -419,22 +384,15 @@ async function createTableWithDateTimeColumn(database: string) { datetime_without_tz DATETIME, datetime_with_tz TIMESTAMP ); - SET time_zone = '+08:00'; + -- SET time_zone = '+08:00'; INSERT INTO my_table (datetime_without_tz, datetime_with_tz) VALUES - ('2023-04-27 10:00:00', '2023-04-27 12:30:00'), + ('2023-04-27 10:00:00', '2023-04-27 10:00:00'), ('2023-04-27 10:00:00+05:30', '2023-04-27 10:00:00+05:30'); `); await mysqlknex2.destroy(); } else if (database === 'sqlite') { - const config = { - client: 'sqlite3', - connection: { - filename: './mydb.sqlite3', - }, - useNullAsDefault: true, - pool: { min: 0, max: 5 }, - }; + const config = getKnexConfig({ dbName: 'mydb', dbType: 'sqlite' }); // SQLite supports just one type of datetime // Timezone information, if specified is stored as is in the database @@ -461,32 +419,32 @@ async function createTableWithDateTimeColumn(database: string) { } } -test.describe.skip('External DB - DateTime column', async () => { +test.describe('External DB - DateTime column', async () => { let dashboard: DashboardPage; let context: any; const expectedDisplayValues = { pg: { DatetimeWithoutTz: ['2023-04-27 10:00', '2023-04-27 10:00'], - DatetimeWithTz: ['2023-04-27 12:30', '2023-04-27 12:30'], + DatetimeWithTz: ['2023-04-27 10:00', '2023-04-27 10:00'], }, sqlite: { // without +HH:MM information, display value is same as inserted value // with +HH:MM information, display value is converted to browser timezone // SQLite doesn't have with & without timezone fields; both are same in this case - DatetimeWithoutTz: ['2023-04-27 10:00', '2023-04-27 12:30'], - DatetimeWithTz: ['2023-04-27 10:00', '2023-04-27 12:30'], + DatetimeWithoutTz: ['2023-04-27 10:00', '2023-04-27 10:00'], + DatetimeWithTz: ['2023-04-27 10:00', '2023-04-27 10:00'], }, mysql: { - DatetimeWithoutTz: ['2023-04-27 10:00', '2023-04-27 12:30'], - DatetimeWithTz: ['2023-04-27 04:30', '2023-04-27 04:30'], + DatetimeWithoutTz: ['2023-04-27 10:00', '2023-04-27 04:30'], + DatetimeWithTz: ['2023-04-27 10:00', '2023-04-27 04:30'], }, }; - test.use({ - locale: 'zh-HK', - timezoneId: 'Asia/Hong_Kong', - }); + // test.use({ + // locale: 'zh-HK', + // timezoneId: 'Asia/Hong_Kong', + // }); test.beforeEach(async ({ page }) => { context = await setup({ page, isEmptyProject: true }); @@ -505,17 +463,7 @@ test.describe.skip('External DB - DateTime column', async () => { await api.base.create(context.project.id, { alias: 'datetimetable', type: 'pg', - config: { - client: 'pg', - connection: { - host: 'localhost', - port: '5432', - user: 'postgres', - password: 'password', - database: 'datetimetable', - }, - searchPath: ['public'], - }, + config: getKnexConfig({ dbName: 'datetimetable', dbType: 'pg' }), inflection_column: 'camelize', inflection_table: 'camelize', }); @@ -523,16 +471,7 @@ test.describe.skip('External DB - DateTime column', async () => { await api.base.create(context.project.id, { alias: 'datetimetable', type: 'mysql2', - config: { - client: 'mysql2', - connection: { - host: 'localhost', - port: '3306', - user: 'root', - password: 'password', - database: 'datetimetable', - }, - }, + config: getKnexConfig({ dbName: 'datetimetable', dbType: 'mysql' }), inflection_column: 'camelize', inflection_table: 'camelize', }); @@ -557,9 +496,15 @@ test.describe.skip('External DB - DateTime column', async () => { } await dashboard.rootPage.reload(); + // wait for 5 seconds for the base to be created + // hack for CI + await dashboard.rootPage.waitForTimeout(5000); }); test('Verify display value, UI insert, API response', async () => { + // get timezone offset + const timezoneOffset = new Date().getTimezoneOffset(); + await dashboard.treeView.openBase({ title: 'datetimetable' }); await dashboard.treeView.openTable({ title: 'MyTable' }); @@ -596,7 +541,7 @@ test.describe.skip('External DB - DateTime column', async () => { await dashboard.grid.cell.dateTime.setDateTime({ index: 2, columnHeader: 'DatetimeWithTz', - dateTime: '2023-04-27 12:30:00', + dateTime: '2023-04-27 10:00:00', }); // reload page & verify if inserted values are shown correctly @@ -609,7 +554,7 @@ test.describe.skip('External DB - DateTime column', async () => { await dashboard.grid.cell.verifyDateCell({ index: 2, columnHeader: 'DatetimeWithTz', - value: '2023-04-27 12:30', + value: '2023-04-27 10:00', }); // verify API response @@ -621,92 +566,40 @@ test.describe.skip('External DB - DateTime column', async () => { let dateTimeWithoutTz = records.list.map(record => record.DatetimeWithoutTz); let dateTimeWithTz = records.list.map(record => record.DatetimeWithTz); - if (isPg(context)) { - const expectedDateTimeWithoutTz = [ - 'Thu, 27 Apr 2023 04:30:00 GMT', - 'Thu, 27 Apr 2023 04:30:00 GMT', - 'Thu, 27 Apr 2023 02:00:00 GMT', - ]; - const expectedDateTimeWithTz = [ - 'Thu, 27 Apr 2023 04:30:00 GMT', - 'Thu, 27 Apr 2023 04:30:00 GMT', - 'Thu, 27 Apr 2023 04:30:00 GMT', - ]; - - // convert to ISO string, skip seconds part or reset seconds to 00 - dateTimeWithoutTz = dateTimeWithoutTz.map(dateTimeStr => { - const dateObj = new Date(dateTimeStr); - dateObj.setSeconds(0); - return dateObj.toUTCString(); - }); - dateTimeWithTz = dateTimeWithTz.map(dateTimeStr => { - const dateObj = new Date(dateTimeStr); - dateObj.setSeconds(0); - return dateObj.toUTCString(); - }); - - console.log(dateTimeWithoutTz); - console.log(dateTimeWithTz); - expect(dateTimeWithoutTz).toEqual(expectedDateTimeWithoutTz); - expect(dateTimeWithTz).toEqual(expectedDateTimeWithTz); - } else if (isMysql(context)) { - const expectedDateTimeWithoutTz = [ - 'Thu, 27 Apr 2023 04:30:00 GMT', - 'Thu, 27 Apr 2023 07:00:00 GMT', - 'Thu, 27 Apr 2023 02:00:00 GMT', - ]; - const expectedDateTimeWithTz = [ - 'Wed, 26 Apr 2023 23:00:00 GMT', - 'Wed, 26 Apr 2023 23:00:00 GMT', - 'Thu, 27 Apr 2023 04:30:00 GMT', - ]; - - // convert to ISO string, skip seconds part or reset seconds to 00 - dateTimeWithoutTz = dateTimeWithoutTz.map(dateTimeStr => { - const dateObj = new Date(dateTimeStr); - dateObj.setSeconds(0); - return dateObj.toUTCString(); - }); - dateTimeWithTz = dateTimeWithTz.map(dateTimeStr => { - const dateObj = new Date(dateTimeStr); - dateObj.setSeconds(0); - return dateObj.toUTCString(); - }); + const expectedDateTimeWithoutTz = [ + 'Thu, 27 Apr 2023 10:00:00 GMT', + 'Thu, 27 Apr 2023 10:00:00 GMT', + 'Thu, 27 Apr 2023 10:00:00 GMT', + ]; + const expectedDateTimeWithTz = [ + 'Thu, 27 Apr 2023 10:00:00 GMT', + 'Thu, 27 Apr 2023 10:00:00 GMT', + 'Thu, 27 Apr 2023 10:00:00 GMT', + ]; - console.log(dateTimeWithoutTz); - console.log(dateTimeWithTz); + if (isMysql(context)) { + expectedDateTimeWithoutTz[1] = 'Thu, 27 Apr 2023 04:30:00 GMT'; + expectedDateTimeWithTz[1] = 'Thu, 27 Apr 2023 04:30:00 GMT'; + } - expect(dateTimeWithoutTz).toEqual(expectedDateTimeWithoutTz); - expect(dateTimeWithTz).toEqual(expectedDateTimeWithTz); - } else if (isSqlite(context)) { - const expectedDateTimeWithoutTz = [ - 'Thu, 27 Apr 2023 04:30:00 GMT', - 'Thu, 27 Apr 2023 04:30:00 GMT', - 'Thu, 27 Apr 2023 02:00:00 GMT', - ]; - const expectedDateTimeWithTz = [ - 'Thu, 27 Apr 2023 04:30:00 GMT', - 'Thu, 27 Apr 2023 04:30:00 GMT', - 'Thu, 27 Apr 2023 04:30:00 GMT', - ]; - - // convert to ISO string, skip seconds part or reset seconds to 00 - dateTimeWithoutTz = dateTimeWithoutTz.map(dateTimeStr => { - const dateObj = new Date(dateTimeStr); - dateObj.setSeconds(0); - return dateObj.toUTCString(); - }); - dateTimeWithTz = dateTimeWithTz.map(dateTimeStr => { - const dateObj = new Date(dateTimeStr); - dateObj.setSeconds(0); - return dateObj.toUTCString(); - }); + // convert to ISO string, skip seconds part or reset seconds to 00 + dateTimeWithoutTz = dateTimeWithoutTz.map(dateTimeStr => { + const dateObj = new Date(dateTimeStr); + dateObj.setSeconds(0); + dateObj.setMinutes(dateObj.getMinutes() - timezoneOffset); + return dateObj.toUTCString(); + }); + dateTimeWithTz = dateTimeWithTz.map(dateTimeStr => { + const dateObj = new Date(dateTimeStr); + dateObj.setSeconds(0); + dateObj.setMinutes(dateObj.getMinutes() - timezoneOffset); + return dateObj.toUTCString(); + }); - console.log(dateTimeWithoutTz); - console.log(dateTimeWithTz); + // console.log(dateTimeWithoutTz); + // console.log(dateTimeWithTz); - expect(dateTimeWithoutTz).toEqual(expectedDateTimeWithoutTz); - expect(dateTimeWithTz).toEqual(expectedDateTimeWithTz); - } + expect(dateTimeWithoutTz).toEqual(expectedDateTimeWithoutTz); + expect(dateTimeWithTz).toEqual(expectedDateTimeWithTz); }); }); diff --git a/tests/playwright/tests/utils/config.ts b/tests/playwright/tests/utils/config.ts new file mode 100644 index 0000000000..f587574c0c --- /dev/null +++ b/tests/playwright/tests/utils/config.ts @@ -0,0 +1,48 @@ +const knexConfig = { + pg: { + client: 'pg', + connection: { + host: 'localhost', + port: 5432, + user: 'postgres', + password: 'password', + database: 'postgres', + multipleStatements: true, + }, + searchPath: ['public', 'information_schema'], + pool: { min: 0, max: 5 }, + }, + mysql: { + client: 'mysql2', + connection: { + host: 'localhost', + port: 3306, + user: 'root', + password: 'password', + database: 'sakila', + multipleStatements: true, + }, + pool: { min: 0, max: 5 }, + }, + sqlite: { + client: 'sqlite3', + connection: { + filename: './mydb.sqlite3', + }, + useNullAsDefault: true, + pool: { min: 0, max: 5 }, + }, +}; + +function getKnexConfig({ dbName, dbType }: { dbName: string; dbType: string }) { + const config = knexConfig[dbType]; + + if (dbType === 'sqlite') { + config.connection.filename = `./${dbName}.sqlite3`; + return config; + } + config.connection.database = dbName; + return config; +} + +export { getKnexConfig };