From fd3bf599d7519ad19515b1b4a27beef99ef09f52 Mon Sep 17 00:00:00 2001 From: Joseph Kempster Date: Mon, 11 Oct 2021 16:13:54 +0100 Subject: [PATCH] Focus on the Zendesk widget when it loads Currently, when the widget loads, the focus is still in the footer, so the user has to tab all the way through it until focus gets trapped in the widget. Add another looped timer to wait until the widget is loaded so that we focus there instead. --- .../controllers/talk-to-us_controller.js | 19 +++++++++++--- .../controllers/talk-to-us_controller_spec.js | 25 +++++++++++++------ 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/app/webpacker/controllers/talk-to-us_controller.js b/app/webpacker/controllers/talk-to-us_controller.js index c1df7b3869..fc0c5e69f2 100644 --- a/app/webpacker/controllers/talk-to-us_controller.js +++ b/app/webpacker/controllers/talk-to-us_controller.js @@ -50,10 +50,12 @@ export default class extends Controller { this.appendZendeskScript(); this.waitForZendesk(() => { window.$zopim.livechat.window.show(); - - setTimeout(() => { - this.buttonTarget.querySelector('span').innerHTML = originalText; - }, 500); // Small delay to account for the chat box animating in. + this.waitForWidget(() => { + setTimeout(() => { + document.getElementById('webWidget').focus(); + this.buttonTarget.querySelector('span').innerHTML = originalText; + }, 500); // Small delay to account for the chat box animating in. + }); }); } @@ -79,6 +81,15 @@ export default class extends Controller { document.body.appendChild(script); } + waitForWidget(callback) { + const interval = setInterval(() => { + if (document.getElementById('webWidget')) { + clearInterval(interval); + callback(); + } + }, 100); + } + waitForZendesk(callback) { const interval = setInterval(() => { if (window.$zopim && window.$zopim.livechat) { diff --git a/spec/javascript/controllers/talk-to-us_controller_spec.js b/spec/javascript/controllers/talk-to-us_controller_spec.js index f982911cf0..5b535d5e4a 100644 --- a/spec/javascript/controllers/talk-to-us_controller_spec.js +++ b/spec/javascript/controllers/talk-to-us_controller_spec.js @@ -8,14 +8,19 @@ describe('TalkToUsController', () => { const setBody = (zendeskEnabled, offlineText = null) => { document.body.innerHTML = ` - - Chat Online - ${offlineText ? `

${offlineText}

` : ''} -
+
+ + Chat Online + ${offlineText ? `

${offlineText}

` : ''} +
+
// Represents the Zendesk modal + +
+
`; } @@ -68,13 +73,16 @@ describe('TalkToUsController', () => { it('appends the Zendesk snippet, opens the chat window and shows a loading message when clicking the button', () => { const button = document.querySelector('a'); + expect(document.activeElement.id).not.toEqual("webWidget"); button.click(); expect(document.querySelector('#ze-snippet')).not.toBeNull(); expect(getButtonText()).toEqual("Starting chat..."); jest.runOnlyPendingTimers(); // Timer for script loading, + jest.runOnlyPendingTimers(); // Timer to wait for the widget to load. jest.runOnlyPendingTimers(); // Timer to wait for chat window to open. expect(chatShowSpy).toHaveBeenCalled(); expect(getButtonText()).toEqual("Chat Online"); + expect(document.activeElement.id).toEqual("webWidget"); }); describe('when clicking the chat button twice', () => { @@ -83,6 +91,7 @@ describe('TalkToUsController', () => { button.click(); expect(button.textContent).toEqual("Starting chat..."); jest.runOnlyPendingTimers(); // Timer for script loading, + jest.runOnlyPendingTimers(); // Timer to wait for the widget to load. jest.runOnlyPendingTimers(); // Timer to wait for chat window to open. expect(chatShowSpy).toHaveBeenCalled(); expect(button.textContent).toEqual("Chat Online");