Browse Source

test: webhook v2

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>
pull/5349/head
Raju Udava 2 years ago
parent
commit
755307faf2
  1. 142
      tests/playwright/tests/01-webhook.spec.ts
  2. 21
      tests/playwright/tests/utils/general.ts

142
tests/playwright/tests/01-webhook.spec.ts

@ -3,6 +3,7 @@ import { DashboardPage } from '../pages/Dashboard';
import setup from '../setup';
import makeServer from '../setup/server';
import { WebhookFormPage } from '../pages/Dashboard/WebhookForm';
import { isSubset } from '../utils';
const hookPath = 'http://localhost:9090/hook';
@ -16,9 +17,11 @@ async function clearServerData({ request }) {
await expect(await response.json()).toBe(0);
}
async function verifyHookTrigger(count: number, value: string, request) {
async function verifyHookTrigger(count: number, value: string, request, expectedData?: any) {
// Retry since there can be lag between the time the hook is triggered and the time the server receives the request
let response;
// retry since there can be lag between the time the hook is triggered and the time the server receives the request
for (let i = 0; i < 20; i++) {
response = await request.get(hookPath + '/count');
if ((await response.json()) === count) {
@ -30,17 +33,43 @@ async function verifyHookTrigger(count: number, value: string, request) {
if (count) {
let response;
// retry since there can be lag between the time the hook is triggered and the time the server receives the request
for (let i = 0; i < 20; i++) {
response = await request.get(hookPath + '/last');
if ((await response.json()).Title === value) {
const rspJson = await response.json();
if (rspJson.data.rows[0].Title === value) {
break;
}
await new Promise(resolve => setTimeout(resolve, 150));
}
await expect((await response.json()).Title).toBe(value);
const rspJson = await response.json();
await expect(rspJson?.data?.rows[0]?.Title).toBe(value);
if (expectedData) {
await expect(isSubset(rspJson, expectedData)).toBe(true);
}
}
}
async function buildExpectedResponseData(type, value) {
const expectedData = {
type: 'records.after.insert',
data: {
table_name: 'Test',
view_name: 'Test',
rows: [
{
Title: 'Poole',
},
],
},
};
expectedData.type = type;
expectedData.data.rows[0].Title = value;
return expectedData;
}
test.describe.serial('Webhook', () => {
// start a server locally for webhook tests
@ -58,7 +87,7 @@ test.describe.serial('Webhook', () => {
});
test('CRUD', async ({ request, page }) => {
// todo: Waiting for the server to start
// Waiting for the server to start
await page.waitForTimeout(1000);
// close 'Team & Auth' tab
@ -66,6 +95,12 @@ test.describe.serial('Webhook', () => {
await dashboard.closeTab({ title: 'Team & Auth' });
await dashboard.treeView.createTable({ title: 'Test' });
// hook order
// hook-1: after insert
// - verify trigger after insert
// - verify no trigger after edit
// - verify no trigger after delete
// after insert hook
await webhook.create({
title: 'hook-1',
@ -77,12 +112,24 @@ test.describe.serial('Webhook', () => {
columnHeader: 'Title',
value: 'Poole',
});
await verifyHookTrigger(1, 'Poole', request);
await verifyHookTrigger(1, 'Poole', request, buildExpectedResponseData('records.after.insert', 'Poole'));
// trigger edit row & delete row
// verify that the hook is not triggered (count doesn't change in this case)
await dashboard.grid.editRow({ index: 0, value: 'Delaware' });
await verifyHookTrigger(1, 'Poole', request);
await dashboard.grid.deleteRow(0);
await verifyHookTrigger(1, 'Poole', request);
///////////////////////////////////////////////////////////////////////////
// hook order
// hook-1: after insert
// hook-2: after update
// - verify trigger after insert
// - verify trigger after edit
// - verify no trigger after delete
// after update hook
await webhook.create({
title: 'hook-2',
@ -95,12 +142,22 @@ test.describe.serial('Webhook', () => {
columnHeader: 'Title',
value: 'Poole',
});
await verifyHookTrigger(1, 'Poole', request);
await verifyHookTrigger(1, 'Poole', request, buildExpectedResponseData('records.after.insert', 'Poole'));
await dashboard.grid.editRow({ index: 0, value: 'Delaware' });
await verifyHookTrigger(2, 'Delaware', request);
await verifyHookTrigger(2, 'Delaware', request, buildExpectedResponseData('records.after.update', 'Delaware'));
await dashboard.grid.deleteRow(0);
await verifyHookTrigger(2, 'Delaware', request);
///////////////////////////////////////////////////////////////////////////
// hook order
// hook-1: after insert
// hook-2: after update
// hook-3: after delete
// - verify trigger after insert
// - verify trigger after edit
// - verify trigger after delete
// after delete hook
await webhook.create({
title: 'hook-3',
@ -112,13 +169,24 @@ test.describe.serial('Webhook', () => {
columnHeader: 'Title',
value: 'Poole',
});
await verifyHookTrigger(1, 'Poole', request);
await verifyHookTrigger(1, 'Poole', request, buildExpectedResponseData('records.after.insert', 'Poole'));
await dashboard.grid.editRow({ index: 0, value: 'Delaware' });
await verifyHookTrigger(2, 'Delaware', request);
await verifyHookTrigger(2, 'Delaware', request, buildExpectedResponseData('records.after.update', 'Delaware'));
await dashboard.grid.deleteRow(0);
await verifyHookTrigger(3, 'Delaware', request);
await verifyHookTrigger(3, 'Delaware', request, buildExpectedResponseData('records.after.delete', 'Delaware'));
///////////////////////////////////////////////////////////////////////////
// modify webhook
// hook order
// hook-1: after delete
// hook-2: after delete
// hook-3: after delete
// - verify no trigger after insert
// - verify no trigger after edit
// - verify trigger after delete
await webhook.open({ index: 0 });
await webhook.configureWebhook({
title: 'hook-1-modified',
@ -140,13 +208,28 @@ test.describe.serial('Webhook', () => {
columnHeader: 'Title',
value: 'Poole',
});
// for insert & edit, the hook should not be triggered (count doesn't change in this case)
await verifyHookTrigger(0, 'Poole', request);
await dashboard.grid.editRow({ index: 0, value: 'Delaware' });
await verifyHookTrigger(0, 'Delaware', request);
await dashboard.grid.deleteRow(0);
await verifyHookTrigger(3, 'Delaware', request);
// for delete, the hook should be triggered (thrice in this case)
await verifyHookTrigger(3, 'Delaware', request, buildExpectedResponseData('records.after.delete', 'Delaware'));
///////////////////////////////////////////////////////////////////////////
// delete webhook
// hook order
// hook-1: -
// hook-2: -
// hook-3: -
// - verify no trigger after insert
// - verify no trigger after edit
// - verify no trigger after delete
await webhook.delete({ index: 0 });
await webhook.delete({ index: 0 });
await webhook.delete({ index: 0 });
@ -212,7 +295,18 @@ test.describe.serial('Webhook', () => {
save: true,
});
// verify
///////////////////////////////////////////////////////////////////////////
// webhook with condition
// hook order
// hook-1: after insert where Title is like 'Poole'
// hook-2: after update where Title is like 'Poole'
// hook-3: after delete where Title is like 'Poole'
// - verify trigger after insert gets triggered only when Title is like 'Poole'
// - verify trigger after edit gets triggered only when Title is like 'Poole'
// - verify trigger after delete gets triggered only when Title is like 'Poole'
await clearServerData({ request });
await dashboard.grid.addNewRow({
index: 0,
@ -224,15 +318,25 @@ test.describe.serial('Webhook', () => {
columnHeader: 'Title',
value: 'Delaware',
});
await verifyHookTrigger(1, 'Poole', request);
await verifyHookTrigger(1, 'Poole', request, buildExpectedResponseData('records.after.insert', 'Poole'));
await dashboard.grid.editRow({ index: 0, value: 'Delaware' });
await dashboard.grid.editRow({ index: 1, value: 'Poole' });
await verifyHookTrigger(2, 'Poole', request);
await verifyHookTrigger(2, 'Poole', request, buildExpectedResponseData('records.after.update', 'Poole'));
await dashboard.grid.deleteRow(1);
await dashboard.grid.deleteRow(0);
await verifyHookTrigger(3, 'Poole', request);
await verifyHookTrigger(3, 'Poole', request, buildExpectedResponseData('records.after.delete', 'Poole'));
///////////////////////////////////////////////////////////////////////////
// Delete condition
// webhook after conditions are removed
// hook order
// hook-1: after insert
// hook-2: after update
// hook-3: after delete
// - verify trigger after insert gets triggered when Title is like 'Poole' or not
// - verify trigger after edit gets triggered when Title is like 'Poole' or not
// - verify trigger after delete gets triggered when Title is like 'Poole' or not
await webhook.open({ index: 2 });
await webhook.deleteCondition({ save: true });
await webhook.open({ index: 1 });
@ -251,12 +355,12 @@ test.describe.serial('Webhook', () => {
columnHeader: 'Title',
value: 'Delaware',
});
await verifyHookTrigger(2, 'Delaware', request);
await verifyHookTrigger(2, 'Delaware', request, buildExpectedResponseData('records.after.insert', 'Delaware'));
await dashboard.grid.editRow({ index: 0, value: 'Delaware' });
await dashboard.grid.editRow({ index: 1, value: 'Poole' });
await verifyHookTrigger(4, 'Poole', request);
await verifyHookTrigger(4, 'Poole', request, buildExpectedResponseData('records.after.update', 'Poole'));
await dashboard.grid.deleteRow(1);
await dashboard.grid.deleteRow(0);
await verifyHookTrigger(6, 'Delaware', request);
await verifyHookTrigger(6, 'Delaware', request, buildExpectedResponseData('records.after.delete', 'Delaware'));
});
});

21
tests/playwright/tests/utils/general.ts

@ -19,4 +19,23 @@ async function getTextExcludeIconText(selector) {
return text.trim();
}
export { getTextExcludeIconText };
function isSubset(obj, potentialSubset) {
for (const prop in potentialSubset) {
// eslint-disable-next-line no-prototype-builtins
if (potentialSubset.hasOwnProperty(prop)) {
const potentialValue = potentialSubset[prop];
const objValue = obj[prop];
if (typeof potentialValue === 'object' && typeof objValue === 'object') {
if (!isSubset(objValue, potentialValue)) {
return false;
}
// eslint-disable-next-line no-prototype-builtins
} else if (!obj.hasOwnProperty(prop) || objValue !== potentialValue) {
return false;
}
}
}
return true;
}
export { getTextExcludeIconText, isSubset };

Loading…
Cancel
Save