diff --git a/apps/builder/src/features/blocks/bubbles/image/image.spec.ts b/apps/builder/src/features/blocks/bubbles/image/image.spec.ts index 9d1cc531f..dcf6042a3 100644 --- a/apps/builder/src/features/blocks/bubbles/image/image.spec.ts +++ b/apps/builder/src/features/blocks/bubbles/image/image.spec.ts @@ -25,6 +25,7 @@ test.describe.parallel('Image bubble block', () => { await page.goto(`/typebots/${typebotId}/edit`) await page.click('text=Click to edit...') + await page.getByRole('button', { name: 'Upload' }).click() await page.setInputFiles('input[type="file"]', getTestAsset('avatar.jpg')) await expect(page.locator('img')).toHaveAttribute( 'src', diff --git a/apps/builder/src/features/blocks/bubbles/textBubble/textBubble.spec.ts b/apps/builder/src/features/blocks/bubbles/textBubble/textBubble.spec.ts index 7d2b238e5..12e58d3a3 100644 --- a/apps/builder/src/features/blocks/bubbles/textBubble/textBubble.spec.ts +++ b/apps/builder/src/features/blocks/bubbles/textBubble/textBubble.spec.ts @@ -44,6 +44,7 @@ test.describe('Text bubble block', () => { await page.click('[data-testid="link-button"]') await page.fill('input[placeholder="Paste link"]', 'https://github.com') await page.press('input[placeholder="Paste link"]', 'Enter') + await page.press('div[role="textbox"]', 'ArrowRight') await page.press('div[role="textbox"]', 'Shift+Enter') await page.click('button[aria-label="Insert variable"]') await page.fill('[data-testid="variables-input"]', 'test') diff --git a/apps/viewer/src/features/variables/parseVariables.ts b/apps/viewer/src/features/variables/parseVariables.ts index 3fb7cc01b..650fca4fe 100644 --- a/apps/viewer/src/features/variables/parseVariables.ts +++ b/apps/viewer/src/features/variables/parseVariables.ts @@ -21,29 +21,34 @@ export const parseVariables = ) => (text: string | undefined): string => { if (!text || text === '') return '' - return text.replace(/\{\{(.*?)\}\}/g, (_, fullVariableString) => { - const matchedVarName = fullVariableString.replace(/{{|}}/g, '') - const variable = variables.find((variable) => { - return ( - matchedVarName === variable.name && - (options.fieldToParse === 'id' || isDefined(variable.value)) + // Capture {{variable}} and ${{{variable}}} (variables in template litterals) + const pattern = /\{\{([^{}]+)\}\}|\$\{\{([^{}]+)\}\}/g + return text.replace( + pattern, + (_, nameInCurlyBraces, nameInTemplateLitteral) => { + const matchedVarName = nameInCurlyBraces ?? nameInTemplateLitteral + const variable = variables.find((variable) => { + return ( + matchedVarName === variable.name && + (options.fieldToParse === 'id' || isDefined(variable.value)) + ) + }) as VariableWithValue | undefined + if (!variable) return '' + if (options.fieldToParse === 'id') return variable.id + const { value } = variable + if (options.escapeForJson) + return jsonParse( + typeof value !== 'string' ? JSON.stringify(value) : value + ) + const parsedValue = safeStringify( + options.takeLatestIfList && Array.isArray(value) + ? value[value.length - 1] + : value ) - }) as VariableWithValue | undefined - if (!variable) return '' - if (options.fieldToParse === 'id') return variable.id - const { value } = variable - if (options.escapeForJson) - return jsonParse( - typeof value !== 'string' ? JSON.stringify(value) : value - ) - const parsedValue = safeStringify( - options.takeLatestIfList && Array.isArray(value) - ? value[value.length - 1] - : value - ) - if (!parsedValue) return '' - return parsedValue - }) + if (!parsedValue) return '' + return parsedValue + } + ) } const jsonParse = (str: string) =>