Browse Source

test: extDB corrections

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>
pull/5602/head
Raju Udava 2 years ago
parent
commit
160fa61b22
  1. 5
      tests/playwright/pages/Dashboard/TreeView.ts
  2. 197
      tests/playwright/tests/db/timezone.spec.ts
  3. 48
      tests/playwright/tests/utils/config.ts

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

@ -57,12 +57,13 @@ export class TreeViewPage extends BasePage {
// check if nodeTitle contains title // check if nodeTitle contains title
if (nodeTitle.includes(title)) { if (nodeTitle.includes(title)) {
// click on node // click on node
await node.waitFor({ state: 'visible' });
await node.click(); await node.click();
break; break;
} }
} }
await this.rootPage.waitForTimeout(1000); await this.rootPage.waitForTimeout(5000);
} }
// assumption: first view rendered is always GRID // 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) { if (networkResponse === true) {
await this.waitForResponse({ await this.waitForResponse({
uiAction: () => this.get().locator(`.nc-project-tree-tbl-${title}`).click(), uiAction: () => this.get().locator(`.nc-project-tree-tbl-${title}`).click(),

197
tests/playwright/tests/db/timezone.spec.ts

@ -5,6 +5,7 @@ import { knex } from 'knex';
import { Api, UITypes } from 'nocodb-sdk'; import { Api, UITypes } from 'nocodb-sdk';
import { ProjectsPage } from '../../pages/ProjectsPage'; import { ProjectsPage } from '../../pages/ProjectsPage';
import { isMysql, isPg, isSqlite } from '../../setup/db'; import { isMysql, isPg, isSqlite } from '../../setup/db';
import { getKnexConfig } from '../utils/config';
let api: Api<any>, records: any[]; let api: Api<any>, records: any[];
const columns = [ const columns = [
@ -343,27 +344,9 @@ test.describe('Timezone', () => {
async function createTableWithDateTimeColumn(database: string) { async function createTableWithDateTimeColumn(database: string) {
if (database === 'pg') { if (database === 'pg') {
const config = { const config = getKnexConfig({ dbName: 'postgres', dbType: 'pg' });
client: 'pg', const config2 = getKnexConfig({ dbName: 'datetimetable', dbType: '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 pgknex = knex(config); const pgknex = knex(config);
await pgknex.raw(`DROP DATABASE IF EXISTS datetimetable`); await pgknex.raw(`DROP DATABASE IF EXISTS datetimetable`);
await pgknex.raw(`CREATE DATABASE datetimetable`); await pgknex.raw(`CREATE DATABASE datetimetable`);
@ -376,35 +359,17 @@ async function createTableWithDateTimeColumn(database: string) {
datetime_without_tz TIMESTAMP WITHOUT TIME ZONE, datetime_without_tz TIMESTAMP WITHOUT TIME ZONE,
datetime_with_tz TIMESTAMP WITH TIME ZONE datetime_with_tz TIMESTAMP WITH TIME ZONE
); );
SET timezone = 'Asia/Hong_Kong'; -- SET timezone = 'Asia/Hong_Kong';
SELECT pg_sleep(1); -- SELECT pg_sleep(1);
INSERT INTO my_table (datetime_without_tz, datetime_with_tz) INSERT INTO my_table (datetime_without_tz, datetime_with_tz)
VALUES 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'); ('2023-04-27 10:00:00+05:30', '2023-04-27 10:00:00+05:30');
`); `);
await pgknex2.destroy(); await pgknex2.destroy();
} else if (database === 'mysql') { } else if (database === 'mysql') {
const config = { const config = getKnexConfig({ dbName: 'sakila', dbType: 'mysql' });
client: 'mysql2', const config2 = getKnexConfig({ dbName: 'datetimetable', dbType: 'mysql' });
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 mysqlknex = knex(config); const mysqlknex = knex(config);
await mysqlknex.raw(`DROP DATABASE IF EXISTS datetimetable`); await mysqlknex.raw(`DROP DATABASE IF EXISTS datetimetable`);
@ -419,22 +384,15 @@ async function createTableWithDateTimeColumn(database: string) {
datetime_without_tz DATETIME, datetime_without_tz DATETIME,
datetime_with_tz TIMESTAMP datetime_with_tz TIMESTAMP
); );
SET time_zone = '+08:00'; -- SET time_zone = '+08:00';
INSERT INTO my_table (datetime_without_tz, datetime_with_tz) INSERT INTO my_table (datetime_without_tz, datetime_with_tz)
VALUES 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'); ('2023-04-27 10:00:00+05:30', '2023-04-27 10:00:00+05:30');
`); `);
await mysqlknex2.destroy(); await mysqlknex2.destroy();
} else if (database === 'sqlite') { } else if (database === 'sqlite') {
const config = { const config = getKnexConfig({ dbName: 'mydb', dbType: 'sqlite' });
client: 'sqlite3',
connection: {
filename: './mydb.sqlite3',
},
useNullAsDefault: true,
pool: { min: 0, max: 5 },
};
// SQLite supports just one type of datetime // SQLite supports just one type of datetime
// Timezone information, if specified is stored as is in the database // 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 dashboard: DashboardPage;
let context: any; let context: any;
const expectedDisplayValues = { const expectedDisplayValues = {
pg: { pg: {
DatetimeWithoutTz: ['2023-04-27 10:00', '2023-04-27 10:00'], 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: { sqlite: {
// without +HH:MM information, display value is same as inserted value // without +HH:MM information, display value is same as inserted value
// with +HH:MM information, display value is converted to browser timezone // 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 // 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'], DatetimeWithoutTz: ['2023-04-27 10:00', '2023-04-27 10:00'],
DatetimeWithTz: ['2023-04-27 10:00', '2023-04-27 12:30'], DatetimeWithTz: ['2023-04-27 10:00', '2023-04-27 10:00'],
}, },
mysql: { mysql: {
DatetimeWithoutTz: ['2023-04-27 10:00', '2023-04-27 12:30'], DatetimeWithoutTz: ['2023-04-27 10:00', '2023-04-27 04:30'],
DatetimeWithTz: ['2023-04-27 04:30', '2023-04-27 04:30'], DatetimeWithTz: ['2023-04-27 10:00', '2023-04-27 04:30'],
}, },
}; };
test.use({ // test.use({
locale: 'zh-HK', // locale: 'zh-HK',
timezoneId: 'Asia/Hong_Kong', // timezoneId: 'Asia/Hong_Kong',
}); // });
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
context = await setup({ page, isEmptyProject: true }); 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, { await api.base.create(context.project.id, {
alias: 'datetimetable', alias: 'datetimetable',
type: 'pg', type: 'pg',
config: { config: getKnexConfig({ dbName: 'datetimetable', dbType: 'pg' }),
client: 'pg',
connection: {
host: 'localhost',
port: '5432',
user: 'postgres',
password: 'password',
database: 'datetimetable',
},
searchPath: ['public'],
},
inflection_column: 'camelize', inflection_column: 'camelize',
inflection_table: 'camelize', inflection_table: 'camelize',
}); });
@ -523,16 +471,7 @@ test.describe.skip('External DB - DateTime column', async () => {
await api.base.create(context.project.id, { await api.base.create(context.project.id, {
alias: 'datetimetable', alias: 'datetimetable',
type: 'mysql2', type: 'mysql2',
config: { config: getKnexConfig({ dbName: 'datetimetable', dbType: 'mysql' }),
client: 'mysql2',
connection: {
host: 'localhost',
port: '3306',
user: 'root',
password: 'password',
database: 'datetimetable',
},
},
inflection_column: 'camelize', inflection_column: 'camelize',
inflection_table: 'camelize', inflection_table: 'camelize',
}); });
@ -557,9 +496,15 @@ test.describe.skip('External DB - DateTime column', async () => {
} }
await dashboard.rootPage.reload(); 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 () => { 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.openBase({ title: 'datetimetable' });
await dashboard.treeView.openTable({ title: 'MyTable' }); await dashboard.treeView.openTable({ title: 'MyTable' });
@ -596,7 +541,7 @@ test.describe.skip('External DB - DateTime column', async () => {
await dashboard.grid.cell.dateTime.setDateTime({ await dashboard.grid.cell.dateTime.setDateTime({
index: 2, index: 2,
columnHeader: 'DatetimeWithTz', 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 // 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({ await dashboard.grid.cell.verifyDateCell({
index: 2, index: 2,
columnHeader: 'DatetimeWithTz', columnHeader: 'DatetimeWithTz',
value: '2023-04-27 12:30', value: '2023-04-27 10:00',
}); });
// verify API response // verify API response
@ -621,92 +566,40 @@ test.describe.skip('External DB - DateTime column', async () => {
let dateTimeWithoutTz = records.list.map(record => record.DatetimeWithoutTz); let dateTimeWithoutTz = records.list.map(record => record.DatetimeWithoutTz);
let dateTimeWithTz = records.list.map(record => record.DatetimeWithTz); let dateTimeWithTz = records.list.map(record => record.DatetimeWithTz);
if (isPg(context)) {
const expectedDateTimeWithoutTz = [ const expectedDateTimeWithoutTz = [
'Thu, 27 Apr 2023 04:30:00 GMT', 'Thu, 27 Apr 2023 10:00:00 GMT',
'Thu, 27 Apr 2023 04:30:00 GMT', 'Thu, 27 Apr 2023 10:00:00 GMT',
'Thu, 27 Apr 2023 02:00:00 GMT', 'Thu, 27 Apr 2023 10:00:00 GMT',
]; ];
const expectedDateTimeWithTz = [ const expectedDateTimeWithTz = [
'Thu, 27 Apr 2023 04:30:00 GMT', 'Thu, 27 Apr 2023 10:00:00 GMT',
'Thu, 27 Apr 2023 04:30:00 GMT', 'Thu, 27 Apr 2023 10:00:00 GMT',
'Thu, 27 Apr 2023 04:30:00 GMT', 'Thu, 27 Apr 2023 10:00:00 GMT',
]; ];
// convert to ISO string, skip seconds part or reset seconds to 00 if (isMysql(context)) {
dateTimeWithoutTz = dateTimeWithoutTz.map(dateTimeStr => { expectedDateTimeWithoutTz[1] = 'Thu, 27 Apr 2023 04:30:00 GMT';
const dateObj = new Date(dateTimeStr); expectedDateTimeWithTz[1] = 'Thu, 27 Apr 2023 04:30:00 GMT';
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();
});
console.log(dateTimeWithoutTz);
console.log(dateTimeWithTz);
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 // convert to ISO string, skip seconds part or reset seconds to 00
dateTimeWithoutTz = dateTimeWithoutTz.map(dateTimeStr => { dateTimeWithoutTz = dateTimeWithoutTz.map(dateTimeStr => {
const dateObj = new Date(dateTimeStr); const dateObj = new Date(dateTimeStr);
dateObj.setSeconds(0); dateObj.setSeconds(0);
dateObj.setMinutes(dateObj.getMinutes() - timezoneOffset);
return dateObj.toUTCString(); return dateObj.toUTCString();
}); });
dateTimeWithTz = dateTimeWithTz.map(dateTimeStr => { dateTimeWithTz = dateTimeWithTz.map(dateTimeStr => {
const dateObj = new Date(dateTimeStr); const dateObj = new Date(dateTimeStr);
dateObj.setSeconds(0); dateObj.setSeconds(0);
dateObj.setMinutes(dateObj.getMinutes() - timezoneOffset);
return dateObj.toUTCString(); return dateObj.toUTCString();
}); });
console.log(dateTimeWithoutTz); // console.log(dateTimeWithoutTz);
console.log(dateTimeWithTz); // console.log(dateTimeWithTz);
expect(dateTimeWithoutTz).toEqual(expectedDateTimeWithoutTz); expect(dateTimeWithoutTz).toEqual(expectedDateTimeWithoutTz);
expect(dateTimeWithTz).toEqual(expectedDateTimeWithTz); expect(dateTimeWithTz).toEqual(expectedDateTimeWithTz);
}
}); });
}); });

48
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 };
Loading…
Cancel
Save