diff --git a/__tests__/unit/chat-ui.spec.js b/__tests__/unit/chat-ui.spec.js index 6c77f51..58a2fa3 100644 --- a/__tests__/unit/chat-ui.spec.js +++ b/__tests__/unit/chat-ui.spec.js @@ -6,6 +6,7 @@ import { loadingDots as loadingDotsObj } from '../../src/lib/utils'; import { customEventTypes } from '../../src/lib/custom/tracking-events'; import { actionService } from '../../src/lib/action-service'; import { getStringInAngleBrackets } from '../../src/lib/helpers'; +import { experimentsPrompt } from '../../src/lib/config/prompts-affected'; const chatWidgets = require('../../src/lib/chat-widgets'); @@ -312,6 +313,49 @@ describe('ChatUi', () => { expect(sut.track).toBeCalledWith(customEventTypes.linkProvided); }); + test('should call set cta button to close', () => { + // Arrange + Object.defineProperty(window, 'location', { + value: { + search: `?utm_chat=${experimentsPrompt.finalPage}`, + }, + writable: true, + }); + const link = 'https://example.com'; + + // Act + sut.init({ containerId: 'chatbot-container', translations }); + sut.track = jest.fn(); + sut.setCtaButtonToClose = jest.fn(); + + sut.link = link; + sut.setCtaButton(); + + // Assert + // expect(sut.elements.ctaButton.getAttribute('href')).toBe('javascript:void(0)'); + expect(sut.elements.ctaButton.classList.contains('hidden')).toBe(false); + + expect(sut.elements.promptContainer.classList.contains('hidden')).toBe(true); + + expect(sut.setCtaButtonToClose).toBeCalledTimes(1); + expect(sut.track).toBeCalledTimes(1); + expect(sut.track).toBeCalledWith(customEventTypes.linkProvided); + }); + + test('should close the chat via cta button click', () => { + // Act + sut.init({ containerId: 'chatbot-container', translations }); + sut.closeWidget = jest.fn(); + + sut.setCtaButtonToClose(); + + sut.elements.ctaButton.click(); + + // Assert + expect(sut.elements.ctaButton.getAttribute('href')).toBe('javascript:void(0)'); + expect(sut.closeWidget).toBeCalledTimes(1); + }); + test('shouldHideChat returns true when user has seen the chat and the history has not expired (24hrs)', () => { // Arrange localStorage.setItem( diff --git a/package-lock.json b/package-lock.json index a0dbcb7..7055579 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "1ff-chat-ui", - "version": "1.0.41", + "version": "1.0.42", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "1ff-chat-ui", - "version": "1.0.41", + "version": "1.0.42", "license": "ISC", "dependencies": { "socket.io-client": "^4.6.1" diff --git a/package.json b/package.json index 218624a..3206b37 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "1ff-chat-ui", - "version": "1.0.41", + "version": "1.0.42", "description": "chatbot to communicate with taught ai", "main": "src/lib/chat-ui.js", "scripts": { diff --git a/src/lib/chat-ui.js b/src/lib/chat-ui.js index c2b9133..c2efd92 100644 --- a/src/lib/chat-ui.js +++ b/src/lib/chat-ui.js @@ -43,6 +43,7 @@ import { } from './socket-services'; import { actionService } from './action-service'; import { customEventTypes, standardEventTypes } from './custom/tracking-events'; +import { experimentsPrompt } from '../../src/lib/config/prompts-affected'; const nodeEvents = require('events'); @@ -202,8 +203,10 @@ const ChatUi = { if (this.link) { this.setCtaButton(); + if(getTerm() === experimentsPrompt.finalPage){ + this.link.remove(); + } } - if (content.includes(intentionType.email)) { this.setEmailVisibility(); } @@ -450,13 +453,27 @@ const ChatUi = { */ setCtaButton() { this.elements.ctaButton.classList.remove('hidden'); - this.elements.ctaButton.setAttribute('href', this.link); + if (getTerm() === experimentsPrompt.finalPage) { + this.setCtaButtonToClose(); + } else { + this.elements.ctaButton.setAttribute('href', this.link); + } input.hide(this); this.track(customEventTypes.linkProvided); this.elements.ctaButton.addEventListener('click', () => { this.track(customEventTypes.linkClicked); }); }, + + setCtaButtonToClose(){ + this.elements.ctaButton.setAttribute('href', 'javascript:void(0)'); + + this.elements.ctaButton.addEventListener('click', (e) => { + e.preventDefault(); + this.closeWidget(); + }); + }, + /** * Sets custom variables and applies them to the main container element and font family. * Theme-specific properties are handled separately. @@ -725,13 +742,17 @@ const ChatUi = { this.closeSocket(); localStorage.setItem(CHAT_SEEN_KEY, true); }, + goBack() { + this.closeSocket(); + history.back(); + }, /** * Attaches event listeners to the chat widget elements. * * @returns {void} */ attachListeners() { - this.elements.closeButton?.addEventListener('click', this.closeWidget.bind(this)); + this.elements.closeButton?.addEventListener('click', this.goBack.bind(this)); this.elements.sendButton.addEventListener('click', this.addNewMessage.bind(this)); this.elements.ctaButton.addEventListener('click', this.closeWidget.bind(this)); this.elements.messageInput.addEventListener('keydown', this.onKeyDown.bind(this)); diff --git a/src/lib/chat-widgets.js b/src/lib/chat-widgets.js index 253fef5..c7548cf 100644 --- a/src/lib/chat-widgets.js +++ b/src/lib/chat-widgets.js @@ -4,9 +4,11 @@ import { replaceLinksWithAnchors, replaceStringInCurlyBracketsWithStrong, removeStringInAngleBrackets, + getTerm, } from './helpers'; import { actionService } from './action-service'; import { translations } from './config/translations'; +import { experimentsPrompt } from '../../src/lib/config/prompts-affected'; export const chatMarkup = (config) => `
@@ -19,6 +21,7 @@ export const chatMarkup = (config) => `
${config.assistant.role}
+ ${getTerm() === experimentsPrompt.finalPage ? closeButton : ''}
diff --git a/src/lib/config/prompts-affected.js b/src/lib/config/prompts-affected.js new file mode 100644 index 0000000..cd7a892 --- /dev/null +++ b/src/lib/config/prompts-affected.js @@ -0,0 +1,3 @@ +export const experimentsPrompt = { + finalPage: 'md-final-getdiet-usamdr', +}; diff --git a/src/lib/helpers.js b/src/lib/helpers.js index 3decaf4..64cff90 100644 --- a/src/lib/helpers.js +++ b/src/lib/helpers.js @@ -14,6 +14,10 @@ export function getRandomInteger(min, max) { return Math.floor(Math.random() * (max - min) + min); // The maximum is exclusive and the minimum is inclusive } +export function removeUrl(text){ + return text.replace(REGEX_URL); +} + /** * Formats a date string according to the locale, including the date and time. * diff --git a/src/lib/socket-services.js b/src/lib/socket-services.js index c6a105f..8b46f7c 100644 --- a/src/lib/socket-services.js +++ b/src/lib/socket-services.js @@ -1,7 +1,9 @@ import { UNSENT_MESSAGES_KEY } from './chat-ui'; import { rolesHTML } from './chat-widgets'; -import { constructLink, replaceLinksWithAnchors, clearCarets } from './helpers'; +import { constructLink, replaceLinksWithAnchors, clearCarets, getTerm, removeUrl } from './helpers'; import { errorMessage, input, loadingDots, messages, resendButton } from './utils'; +import { experimentsPrompt } from '../../src/lib/config/prompts-affected'; + /** * Handles the start of the stream. * Hides loading dots, appends the current timestamp, and adds the assistant role element. @@ -129,7 +131,12 @@ export function onStreamEnd() { lastMessageTextContainer.classList.remove('cursor'); this.hasAnswers = lastMessageElement.querySelector('.answers-container'); this.link = constructLink(lastMessageTextContainer.innerHTML); - lastMessageTextContainer.innerHTML = replaceLinksWithAnchors(lastMessageTextContainer.innerHTML); + + if (getTerm() === experimentsPrompt.finalPage) { + lastMessageTextContainer.innerHTML = removeUrl(lastMessageTextContainer.innerHTML); + } else { + lastMessageTextContainer.innerHTML = replaceLinksWithAnchors(lastMessageTextContainer.innerHTML); + } if (this.link) { this.setCtaButton();