✅ (webhook) Improve bot test
This commit is contained in:
@ -31,31 +31,7 @@ test.describe('Webhook block', () => {
|
||||
`"Group #1": "answer value", "Group #2": "20", "Group #2 (1)": "Yes"`
|
||||
)
|
||||
})
|
||||
test('Generated body should work', async ({ page }) => {
|
||||
const typebotId = cuid()
|
||||
await importTypebotInDatabase(
|
||||
path.join(__dirname, '../../fixtures/typebots/integrations/webhook.json'),
|
||||
{
|
||||
id: typebotId,
|
||||
}
|
||||
)
|
||||
await createWebhook(typebotId)
|
||||
|
||||
await page.goto(`/typebots/${typebotId}/edit`)
|
||||
await page.click('text=Configure...')
|
||||
await page.fill(
|
||||
'input[placeholder="Paste webhook URL..."]',
|
||||
`${process.env.PLAYWRIGHT_BUILDER_TEST_BASE_URL}/api/mock/webhook-easy-config`
|
||||
)
|
||||
await page.click('text=Advanced configuration')
|
||||
await page.click('text=GET')
|
||||
await page.click('text=POST')
|
||||
|
||||
await page.click('text=Test the request')
|
||||
await expect(page.locator('div[role="textbox"] >> nth=-1')).toContainText(
|
||||
'"message": "This is a sample result, it has been generated ⬇️"'
|
||||
)
|
||||
})
|
||||
test('its configuration should work', async ({ page }) => {
|
||||
const typebotId = cuid()
|
||||
await importTypebotInDatabase(
|
||||
|
@ -1,72 +1,193 @@
|
||||
{
|
||||
"id": "cl26li8fl0407iez0w2tlw8fn",
|
||||
"createdAt": "2022-04-19T20:25:30.417Z",
|
||||
"updatedAt": "2022-04-19T20:40:48.366Z",
|
||||
"id": "cl9ip9u0l00001ad79a2lzm55",
|
||||
"createdAt": "2022-10-21T16:22:07.414Z",
|
||||
"updatedAt": "2022-10-21T16:30:57.642Z",
|
||||
"icon": null,
|
||||
"name": "My typebot",
|
||||
"publishedTypebotId": null,
|
||||
"folderId": null,
|
||||
"groups": [
|
||||
{
|
||||
"id": "cl26li8fj0000iez05x7razkg",
|
||||
"id": "cl9ip9u0j0000d71a5d98gwni",
|
||||
"title": "Start",
|
||||
"blocks": [
|
||||
{
|
||||
"id": "cl26li8fj0001iez0bqfraw9h",
|
||||
"id": "cl9ip9u0j0001d71a44dsd2p1",
|
||||
"type": "start",
|
||||
"label": "Start",
|
||||
"groupId": "cl26li8fj0000iez05x7razkg",
|
||||
"outgoingEdgeId": "cl26liqj6000g2e6ed2cwkvse"
|
||||
"groupId": "cl9ip9u0j0000d71a5d98gwni",
|
||||
"outgoingEdgeId": "cl9ipkkb2001b3b6oh3vptq9k"
|
||||
}
|
||||
],
|
||||
"title": "Start",
|
||||
"graphCoordinates": { "x": 0, "y": 0 }
|
||||
},
|
||||
{
|
||||
"id": "cl26lidjz000a2e6etf4v03hv",
|
||||
"id": "cl9ipa38j00083b6o69e90m4t",
|
||||
"graphCoordinates": { "x": 340, "y": 341 },
|
||||
"title": "Group #1",
|
||||
"blocks": [
|
||||
{
|
||||
"id": "cl26lidk4000b2e6es2fos0nl",
|
||||
"id": "cl9ipaaut000a3b6ovrqlec3x",
|
||||
"groupId": "cl9ipa38j00083b6o69e90m4t",
|
||||
"type": "text input",
|
||||
"options": {
|
||||
"isLong": false,
|
||||
"labels": { "button": "Send", "placeholder": "Type a name..." },
|
||||
"variableId": "vcl9ipajth000c3b6okl97r81j"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "cl9ipan8f000d3b6oo2ovi3ac",
|
||||
"groupId": "cl9ipa38j00083b6o69e90m4t",
|
||||
"type": "number input",
|
||||
"options": {
|
||||
"labels": { "button": "Send", "placeholder": "Type an age..." },
|
||||
"variableId": "vcl9ipaszl000e3b6ousjxuw7b"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "cl9ipb08n000f3b6ok3mi2p48",
|
||||
"groupId": "cl9ipa38j00083b6o69e90m4t",
|
||||
"type": "choice input",
|
||||
"options": {
|
||||
"buttonLabel": "Send",
|
||||
"isMultipleChoice": false,
|
||||
"variableId": "vcl9ipg4tb00103b6oue08w3nm"
|
||||
},
|
||||
"items": [
|
||||
{
|
||||
"id": "cl26lidk5000c2e6e39wyc7wq",
|
||||
"id": "cl9ipb08n000g3b6okr691uad",
|
||||
"blockId": "cl9ipb08n000f3b6ok3mi2p48",
|
||||
"type": 0,
|
||||
"blockId": "cl26lidk4000b2e6es2fos0nl",
|
||||
"content": "Send success webhook"
|
||||
"content": "Male"
|
||||
},
|
||||
{
|
||||
"blockId": "cl9ipb08n000f3b6ok3mi2p48",
|
||||
"type": 0,
|
||||
"id": "cl9ipb2kk000h3b6oadwtonnz",
|
||||
"content": "Female"
|
||||
}
|
||||
],
|
||||
"groupId": "cl26lidjz000a2e6etf4v03hv",
|
||||
"options": { "buttonLabel": "Send", "isMultipleChoice": false }
|
||||
},
|
||||
{
|
||||
"id": "cl26lip76000e2e6ebmph843a",
|
||||
"type": "Webhook",
|
||||
"groupId": "cl26lidjz000a2e6etf4v03hv",
|
||||
"options": {
|
||||
"isCustomBody": false,
|
||||
"isAdvancedConfig": false,
|
||||
"variablesForTest": [],
|
||||
"responseVariableMapping": []
|
||||
},
|
||||
"webhookId": "success-webhook"
|
||||
},
|
||||
{
|
||||
"id": "cl26m0pdz00042e6ebjdoclaa",
|
||||
"groupId": "cl26lidjz000a2e6etf4v03hv",
|
||||
"type": "choice input",
|
||||
"options": { "buttonLabel": "Send", "isMultipleChoice": false },
|
||||
"items": [
|
||||
{
|
||||
"id": "cl26m0pdz00052e6ecmxwfz44",
|
||||
"blockId": "cl26m0pdz00042e6ebjdoclaa",
|
||||
"type": 0,
|
||||
"content": "Send failed webhook"
|
||||
"outgoingEdgeId": "cl9ipcp83000o3b6odsn0a9a1"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "cl26m0w9b00072e6eld1ei291",
|
||||
"groupId": "cl26lidjz000a2e6etf4v03hv",
|
||||
"id": "cl9ipbcjy000j3b6oqngo7luv",
|
||||
"graphCoordinates": { "x": 781, "y": 91 },
|
||||
"title": "Group #2",
|
||||
"blocks": [
|
||||
{
|
||||
"id": "cl9ipbl6l000m3b6o3evn41kv",
|
||||
"groupId": "cl9ipbcjy000j3b6oqngo7luv",
|
||||
"type": "Set variable",
|
||||
"options": {
|
||||
"variableId": "vcl9ipbokm000n3b6o06hvarrf",
|
||||
"expressionToEvaluate": "{\n \"name\": \"John\",\n \"age\": 25,\n \"gender\": \"male\"\n}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "cl9ipbcjy000k3b6oe8lta5c1",
|
||||
"groupId": "cl9ipbcjy000j3b6oqngo7luv",
|
||||
"type": "Webhook",
|
||||
"options": {
|
||||
"responseVariableMapping": [
|
||||
{
|
||||
"id": "cl9ipdspg000p3b6ognbfvmdx",
|
||||
"variableId": "vcl9ipdxnj000q3b6oy55th4xb",
|
||||
"bodyPath": "data"
|
||||
}
|
||||
],
|
||||
"variablesForTest": [],
|
||||
"isAdvancedConfig": true,
|
||||
"isCustomBody": true
|
||||
},
|
||||
"webhookId": "full-body-webhook"
|
||||
},
|
||||
{
|
||||
"id": "cl9ipe5t8000s3b6ocswre500",
|
||||
"groupId": "cl9ipbcjy000j3b6oqngo7luv",
|
||||
"type": "text",
|
||||
"content": {
|
||||
"html": "<div>Data of first request:</div><div></div><div>{{Data}}</div>",
|
||||
"richText": [
|
||||
{
|
||||
"type": "p",
|
||||
"children": [{ "text": "Data of first request:" }]
|
||||
},
|
||||
{ "type": "p", "children": [{ "text": "" }] },
|
||||
{ "type": "p", "children": [{ "text": "{{Data}}" }] }
|
||||
],
|
||||
"plainText": "Data of first request:{{Data}}"
|
||||
},
|
||||
"outgoingEdgeId": "cl9ipet83000z3b6of6zfqota"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "cl9ipej6b000u3b6oeaz305l6",
|
||||
"graphCoordinates": { "x": 1138, "y": 85 },
|
||||
"title": "Group #2 copy",
|
||||
"blocks": [
|
||||
{
|
||||
"id": "cl9ipej6c000w3b6otzk247vl",
|
||||
"groupId": "cl9ipej6b000u3b6oeaz305l6",
|
||||
"type": "Webhook",
|
||||
"options": {
|
||||
"responseVariableMapping": [
|
||||
{
|
||||
"id": "cl9ipdspg000p3b6ognbfvmdx",
|
||||
"variableId": "vcl9ipdxnj000q3b6oy55th4xb",
|
||||
"bodyPath": "data"
|
||||
}
|
||||
],
|
||||
"variablesForTest": [],
|
||||
"isAdvancedConfig": true,
|
||||
"isCustomBody": true
|
||||
},
|
||||
"webhookId": "partial-body-webhook"
|
||||
},
|
||||
{
|
||||
"id": "cl9ipej6c000y3b6oegzkgloq",
|
||||
"groupId": "cl9ipej6b000u3b6oeaz305l6",
|
||||
"type": "text",
|
||||
"content": {
|
||||
"html": "<div>Data of second request:</div><div></div><div>{{Data}}</div>",
|
||||
"richText": [
|
||||
{
|
||||
"type": "p",
|
||||
"children": [{ "text": "Data of second request:" }]
|
||||
},
|
||||
{ "type": "p", "children": [{ "text": "" }] },
|
||||
{ "type": "p", "children": [{ "text": "{{Data}}" }] }
|
||||
],
|
||||
"plainText": "Data of second request:{{Data}}"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "cl9ipkaer00153b6ov230yuv2",
|
||||
"graphCoordinates": { "x": 333, "y": 26 },
|
||||
"title": "Group #4",
|
||||
"blocks": [
|
||||
{
|
||||
"id": "cl9ipkaer00163b6o0ohmmscn",
|
||||
"groupId": "cl9ipkaer00153b6ov230yuv2",
|
||||
"type": "choice input",
|
||||
"options": { "buttonLabel": "Send", "isMultipleChoice": false },
|
||||
"items": [
|
||||
{
|
||||
"id": "cl9ipkaer00173b6oxof4zrqn",
|
||||
"blockId": "cl9ipkaer00163b6o0ohmmscn",
|
||||
"type": 0,
|
||||
"content": "Send failing webhook"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "cl9ipki9u00193b6okmhudo0f",
|
||||
"groupId": "cl9ipkaer00153b6ov230yuv2",
|
||||
"type": "Webhook",
|
||||
"options": {
|
||||
"responseVariableMapping": [],
|
||||
@ -74,26 +195,51 @@
|
||||
"isAdvancedConfig": false,
|
||||
"isCustomBody": false
|
||||
},
|
||||
"webhookId": "failed-webhook"
|
||||
"webhookId": "failing-webhook",
|
||||
"outgoingEdgeId": "cl9ipklm0001c3b6oy0a5nbhr"
|
||||
}
|
||||
],
|
||||
"title": "Group #1",
|
||||
"graphCoordinates": { "x": 386, "y": 117 }
|
||||
]
|
||||
}
|
||||
],
|
||||
"variables": [
|
||||
{ "id": "vcl26lzmg100012e6e9rn57c3o", "name": "var1" },
|
||||
{ "id": "vcl26lzo7q00022e6edw3pe7lf", "name": "var2" },
|
||||
{ "id": "vcl26lzq6s00032e6ecuhh80qz", "name": "var3" }
|
||||
{ "id": "vcl9ipajth000c3b6okl97r81j", "name": "Name" },
|
||||
{ "id": "vcl9ipaszl000e3b6ousjxuw7b", "name": "Age" },
|
||||
{ "id": "vcl9ipbokm000n3b6o06hvarrf", "name": "Full body" },
|
||||
{ "id": "vcl9ipdxnj000q3b6oy55th4xb", "name": "Data" },
|
||||
{ "id": "vcl9ipg4tb00103b6oue08w3nm", "name": "Gender" }
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"id": "cl26liqj6000g2e6ed2cwkvse",
|
||||
"to": { "groupId": "cl26lidjz000a2e6etf4v03hv" },
|
||||
"from": {
|
||||
"blockId": "cl26li8fj0001iez0bqfraw9h",
|
||||
"groupId": "cl26li8fj0000iez05x7razkg"
|
||||
}
|
||||
"groupId": "cl9ipa38j00083b6o69e90m4t",
|
||||
"blockId": "cl9ipb08n000f3b6ok3mi2p48"
|
||||
},
|
||||
"to": { "groupId": "cl9ipbcjy000j3b6oqngo7luv" },
|
||||
"id": "cl9ipcp83000o3b6odsn0a9a1"
|
||||
},
|
||||
{
|
||||
"from": {
|
||||
"groupId": "cl9ipbcjy000j3b6oqngo7luv",
|
||||
"blockId": "cl9ipe5t8000s3b6ocswre500"
|
||||
},
|
||||
"to": { "groupId": "cl9ipej6b000u3b6oeaz305l6" },
|
||||
"id": "cl9ipet83000z3b6of6zfqota"
|
||||
},
|
||||
{
|
||||
"from": {
|
||||
"groupId": "cl9ip9u0j0000d71a5d98gwni",
|
||||
"blockId": "cl9ip9u0j0001d71a44dsd2p1"
|
||||
},
|
||||
"to": { "groupId": "cl9ipkaer00153b6ov230yuv2" },
|
||||
"id": "cl9ipkkb2001b3b6oh3vptq9k"
|
||||
},
|
||||
{
|
||||
"from": {
|
||||
"groupId": "cl9ipkaer00153b6ov230yuv2",
|
||||
"blockId": "cl9ipki9u00193b6okmhudo0f"
|
||||
},
|
||||
"to": { "groupId": "cl9ipa38j00083b6o69e90m4t" },
|
||||
"id": "cl9ipklm0001c3b6oy0a5nbhr"
|
||||
}
|
||||
],
|
||||
"theme": {
|
||||
@ -115,8 +261,9 @@
|
||||
},
|
||||
"settings": {
|
||||
"general": {
|
||||
"isBrandingEnabled": true,
|
||||
"isBrandingEnabled": false,
|
||||
"isInputPrefillEnabled": true,
|
||||
"isHideQueryParamsEnabled": true,
|
||||
"isNewResultOnRefreshEnabled": false
|
||||
},
|
||||
"metadata": {
|
||||
@ -125,5 +272,8 @@
|
||||
"typingEmulation": { "speed": 300, "enabled": true, "maxDelay": 1.5 }
|
||||
},
|
||||
"publicId": null,
|
||||
"customDomain": null
|
||||
"customDomain": null,
|
||||
"workspaceId": "proWorkspace",
|
||||
"isArchived": false,
|
||||
"isClosed": false
|
||||
}
|
||||
|
@ -14,40 +14,50 @@ test('should execute webhooks properly', async ({ page }) => {
|
||||
path.join(__dirname, '../fixtures/typebots/webhook.json'),
|
||||
{ id: typebotId, publicId: `${typebotId}-public` }
|
||||
)
|
||||
|
||||
await createWebhook(typebotId, {
|
||||
id: 'success-webhook',
|
||||
url: 'http://localhost:3001/api/mock/success',
|
||||
method: HttpMethod.POST,
|
||||
})
|
||||
await createWebhook(typebotId, {
|
||||
id: 'failed-webhook',
|
||||
id: 'failing-webhook',
|
||||
url: 'http://localhost:3001/api/mock/fail',
|
||||
method: HttpMethod.POST,
|
||||
})
|
||||
|
||||
await createWebhook(typebotId, {
|
||||
id: 'partial-body-webhook',
|
||||
url: 'http://localhost:3000/api/mock/webhook-easy-config',
|
||||
method: HttpMethod.POST,
|
||||
body: `{
|
||||
"name": "{{Name}}",
|
||||
"age": {{Age}},
|
||||
"gender": "{{Gender}}"
|
||||
}`,
|
||||
})
|
||||
|
||||
await createWebhook(typebotId, {
|
||||
id: 'full-body-webhook',
|
||||
url: 'http://localhost:3000/api/mock/webhook-easy-config',
|
||||
method: HttpMethod.POST,
|
||||
body: `{{Full body}}`,
|
||||
})
|
||||
|
||||
await page.goto(`/${typebotId}-public`)
|
||||
await Promise.all([
|
||||
page.waitForResponse(
|
||||
async (resp) =>
|
||||
resp.request().url().includes(`/api/typebots/${typebotId}/blocks`) &&
|
||||
resp.status() === 200 &&
|
||||
(await resp.json()).statusCode === 200
|
||||
),
|
||||
typebotViewer(page).locator('text=Send success webhook').click(),
|
||||
])
|
||||
await Promise.all([
|
||||
page.waitForResponse(
|
||||
async (resp) =>
|
||||
resp.request().url().includes(`/api/typebots/${typebotId}/blocks`) &&
|
||||
resp.status() === 200 &&
|
||||
(await resp.json()).statusCode === 500
|
||||
),
|
||||
typebotViewer(page).locator('text=Send failed webhook').click(),
|
||||
])
|
||||
await typebotViewer(page).locator('text=Send failing webhook').click()
|
||||
await typebotViewer(page)
|
||||
.locator('[placeholder="Type a name..."]')
|
||||
.fill('John')
|
||||
await typebotViewer(page).locator('text="Send"').click()
|
||||
await typebotViewer(page).locator('[placeholder="Type an age..."]').fill('30')
|
||||
await typebotViewer(page).locator('text="Send"').click()
|
||||
await typebotViewer(page).locator('text="Male"').click()
|
||||
await expect(
|
||||
typebotViewer(page).getByText('{"name":"John","age":25,"gender":"male"}')
|
||||
).toBeVisible()
|
||||
await expect(
|
||||
typebotViewer(page).getByText('{"name":"John","age":30,"gender":"Male"}')
|
||||
).toBeVisible()
|
||||
await page.goto(`http://localhost:3000/typebots/${typebotId}/results`)
|
||||
await page.click('text="See logs"')
|
||||
await expect(
|
||||
page.locator('text="Webhook successfuly executed."')
|
||||
page.locator('text="Webhook successfuly executed." >> nth=1')
|
||||
).toBeVisible()
|
||||
await expect(page.locator('text="Webhook returned an error"')).toBeVisible()
|
||||
})
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Variable } from 'models'
|
||||
import { Variable, VariableWithValue } from 'models'
|
||||
import { isDefined, isNotDefined } from 'utils'
|
||||
|
||||
export const stringContainsVariable = (str: string): boolean =>
|
||||
@ -18,11 +18,10 @@ export const parseVariables =
|
||||
const matchedVarName = fullVariableString.replace(/{{|}}/g, '')
|
||||
const variable = variables.find((v) => {
|
||||
return matchedVarName === v.name && isDefined(v.value)
|
||||
})
|
||||
}) as VariableWithValue | undefined
|
||||
if (!variable) return ''
|
||||
if (options.fieldToParse === 'id') return variable.id
|
||||
const { value } = variable
|
||||
if (isNotDefined(value)) return ''
|
||||
if (options.escapeForJson) return jsonParse(value)
|
||||
const parsedValue = safeStringify(value)
|
||||
if (!parsedValue) return ''
|
||||
|
Reference in New Issue
Block a user