Skip to content

Commit

Permalink
separate out formula tests which are not supported in sqlite
Browse files Browse the repository at this point in the history
formula tests to run based on supported db type

pw formula tests, check formula not supported error

pw formula tests for mysql regex

remove sqlite exclusion for LOG test

reverted suite 3 and kept only 2

reverted suite 3 and kept only 2

remove alternate buggy paths which was added to pass the test
  • Loading branch information
starbirdtech383 committed Dec 21, 2023
1 parent 785ad49 commit d0992e8
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 25 deletions.
12 changes: 10 additions & 2 deletions tests/playwright/pages/Base.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Locator, Page } from '@playwright/test';
import { expect, Locator, Page } from '@playwright/test';
import { readFileSync } from 'fs';

type ResponseSelector = (json: any) => boolean;
Expand All @@ -16,6 +16,12 @@ export default abstract class BasePage {
await this.rootPage.locator('.ant-message .ant-message-notice-content', { hasText: message }).last().isVisible();
}

async verifyLastToast({ message }: { message: string }) {
await expect(
this.rootPage.locator('.ant-message .ant-message-notice-content', { hasText: message }).last()
).toHaveText(message);
}

async waitForResponse({
// Playwright action that triggers the request i.e locatorSomething.click()
uiAction,
Expand All @@ -24,18 +30,20 @@ export default abstract class BasePage {
// A function that takes the response body and returns true if the response is the one we are looking for
responseJsonMatcher,
timeout,
responseStatusCodeToMatch = 200,
}: {
uiAction: () => Promise<any>;
requestUrlPathToMatch: string;
httpMethodsToMatch?: string[];
responseJsonMatcher?: ResponseSelector;
timeout?: number;
responseStatusCodeToMatch?: number;
}) {
const [res] = await Promise.all([
this.rootPage.waitForResponse(
res =>
res.url().includes(requestUrlPathToMatch) &&
res.status() === 200 &&
res.status() === responseStatusCodeToMatch &&
httpMethodsToMatch.includes(res.request().method()),
timeout ? { timeout } : undefined
),
Expand Down
14 changes: 14 additions & 0 deletions tests/playwright/pages/Dashboard/Grid/Column/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,20 @@ export class ColumnPageObject extends BasePage {
await this.rootPage.waitForTimeout(200);
}

async saveFail({ errorMessage }: { errorMessage?: string } = {}) {
await this.waitForResponse({
uiAction: async () => await this.get().locator('button:has-text("Save")').click(),
requestUrlPathToMatch: 'api/v1/db/meta',
httpMethodsToMatch: ['GET', 'PATCH'],
responseStatusCodeToMatch: 400,
});
await this.verifyLastToast({
message: errorMessage,
});
await this.get().waitFor({ state: 'visible' });
await this.rootPage.waitForTimeout(200);
}

async verify({ title, isVisible = true }: { title: string; isVisible?: boolean }) {
if (!isVisible) {
return await expect(this.getColumnHeader(title)).not.toBeVisible();
Expand Down
68 changes: 45 additions & 23 deletions tests/playwright/tests/db/columns/columnFormula.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { test } from '@playwright/test';
import { DashboardPage } from '../../../pages/Dashboard';
import setup, { NcContext, unsetup } from '../../../setup';
import { enableQuickRun, isPg, isSqlite } from '../../../setup/db';
import { enableQuickRun, isMysql, isPg, isSqlite } from '../../../setup/db';

// Add formula to be verified here & store expected results for 5 rows
// Column data from City table (Sakila DB)
Expand All @@ -19,6 +19,7 @@ const formulaDataByDbType = (context: NcContext, index: number) => {
{
formula: '1 + 1',
result: ['2', '2', '2', '2', '2'],
unSupDbType: [],
},
{
formula: 'ADD({CityId}, {CountryId}) + AVG({CityId}, {CountryId}) + LEN({City})',
Expand Down Expand Up @@ -92,6 +93,7 @@ const formulaDataByDbType = (context: NcContext, index: number) => {
{
formula: 'VALUE("12ab-c345")',
result: ['-12345', '-12345', '-12345', '-12345', '-12345'],
unSupDbType: ['sqlite3'],
},
{
formula: 'TRUE()',
Expand All @@ -101,19 +103,6 @@ const formulaDataByDbType = (context: NcContext, index: number) => {
formula: 'FALSE()',
result: ['0', '0', '0', '0', '0'],
},
{
formula: 'REGEX_MATCH({City}, "a[a-z]a")',
result: ['0', '0', '0', '0', '1'],
},
{
formula: 'REGEX_EXTRACT({City}, "a[a-z]a")',
result: ['', '', '', '', 'ana'],
},
{
formula: 'REGEX_REPLACE({City}, "a[a-z]a","...")',
result: ['A Corua (La Corua)', 'Abha', 'Abu Dhabi', 'Acua', 'Ad...'],
},

{
formula: '"City Name: " & {City}',
result: [
Expand All @@ -137,12 +126,35 @@ const formulaDataByDbType = (context: NcContext, index: number) => {
formula: 'RECORD_ID()',
result: ['1', '2', '3', '4', '5'],
},
{
formula: 'REGEX_MATCH({City}, "a[a-z]a")',
result: ['0', '0', '0', '0', '1'],
unSupDbType: ['sqlite3'],
},
{
// TODO: this is bug in mysql, its being case in-sensitive.
formula: 'REGEX_EXTRACT({City}, "a[a-z]a")',
result: ['', '', '', '', 'ana'],
unSupDbType: ['sqlite3'],
},
{
// TODO: this is bug in mysql, its being case in-sensitive.
formula: 'REGEX_REPLACE({City}, "a[a-z]a","...")',
result: ['A Corua (La Corua)', 'Abha', 'Abu Dhabi', 'Acua', 'Ad...'],
unSupDbType: ['sqlite3'],
},
{
//TODO: this test fails in mysql due to not considering rouding factor
formula: 'ROUNDUP({CityId} + 2.49, 1)',
result: ['4', '5', '6', '7', '8'],
},
];
else
return [
{
formula: `DATETIME_DIFF("2023/10/14", "2023/01/12", "y")`,
result: ['0', '0', '0', '0', '0'],
unSupDbType: [],
},
{
formula: `DATETIME_DIFF("2023-01-12", "2021-08-29", "y")`,
Expand Down Expand Up @@ -180,9 +192,16 @@ const formulaDataByDbType = (context: NcContext, index: number) => {
},
{
formula: `LOG({CityId}) + EXP({CityId}) + POWER({CityId}, 3) + SQRT({CountryId})`,
result: isPg(context)
? ['13.04566088154786', '24.74547123273205', '57.61253379902822', '126.94617671688704', '283.9609869087087']
: ['13.04566088154786', '25.137588417628013', '58.23402483297667', '127.73041108667896', '284.8714548168068'],
result:
isPg(context) || isSqlite(context)
? ['13.04566088154786', '24.74547123273205', '57.61253379902822', '126.94617671688704', '283.9609869087087']
: [
'13.04566088154786',
'25.137588417628013',
'58.23402483297667',
'127.73041108667896',
'284.8714548168068',
],
},
{
formula: `NOW()`,
Expand Down Expand Up @@ -245,26 +264,29 @@ test.describe('Virtual Columns', () => {
async function formulaTestSpec(index: number) {
// close 'Team & Auth' tab
const formulaData = formulaDataByDbType(context, index);
const dbType = context.base.sources[0].type;
await dashboard.closeTab({ title: 'Team & Auth' });

await dashboard.treeView.openTable({ title: 'City' });
// Create formula column
// Create dummy formula column which will then be updated for every testcase
await dashboard.grid.column.create({
title: 'NC_MATH_0',
type: 'Formula',
formula: formulaData[1].formula,
formula: '1 + 1',
});

// verify different formula's
for (let i = 1; i < formulaData.length; i++) {
// Sqlite does not support log function
if (isSqlite(context) && formulaData[i].formula.includes('LOG(')) continue;

for (let i = 0; i < formulaData.length; i++) {
await dashboard.grid.column.openEdit({
title: 'NC_MATH_0',
type: 'Formula',
formula: formulaData[i].formula,
});
if (formulaData[i].unSupDbType?.includes(dbType)) {
// assert for message not supported or greyed out save button.
await dashboard.grid.column.saveFail({ errorMessage: 'Invalid Formula' });
continue;
}
await dashboard.grid.column.save({ isUpdated: true });
if (formulaData[i].formula !== `NOW()`) {
await formulaResultVerify({
Expand Down

0 comments on commit d0992e8

Please sign in to comment.