-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Customizing typing indicator (#2912)
* Add activeTyping * Fix send typing momentarily not showing after post * Add sample * Doc * Fix build break * Doc * Format * Add entry * Add GitHub CDN * Fix tests * Add tests and doc * Add tests * Remove dead code * Use useLocalizer * Format * Apply suggestions from code review Co-Authored-By: TJ Durnford <[email protected]> * Remove deprecated code Co-authored-by: TJ Durnford <[email protected]>
- Loading branch information
Showing
31 changed files
with
730 additions
and
65 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file added
BIN
+16.5 KB
...nd-typing-indicator-js-changing-typing-indicator-duration-on-the-fly-1-snap.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+15 KB
...nd-typing-indicator-js-changing-typing-indicator-duration-on-the-fly-2-snap.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+16.5 KB
...nd-typing-indicator-js-changing-typing-indicator-duration-on-the-fly-3-snap.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
import { Key } from 'selenium-webdriver'; | ||
|
||
import { timeouts } from '../constants.json'; | ||
|
||
import minNumActivitiesShown from '../setup/conditions/minNumActivitiesShown'; | ||
import uiConnected from '../setup/conditions/uiConnected'; | ||
|
||
// selenium-webdriver API doc: | ||
// https://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebDriver.html | ||
|
||
jest.setTimeout(timeouts.test); | ||
|
||
test('getter should represent bot and user typing respectively', async () => { | ||
const { driver, pageObjects } = await setupWebDriver({ | ||
props: { sendTypingIndicator: true }, | ||
setup: () => | ||
Promise.all([ | ||
window.WebChatTest.loadScript('https://unpkg.com/[email protected]/client/core.min.js'), | ||
window.WebChatTest.loadScript('https://unpkg.com/[email protected]/lolex.js') | ||
]).then(() => { | ||
window.WebChatTest.clock = lolex.install(); | ||
}) | ||
}); | ||
|
||
await driver.wait(uiConnected(), timeouts.directLine); | ||
|
||
let activeTyping; | ||
|
||
await expect(pageObjects.runHook('useActiveTyping')).resolves.toEqual([{}]); | ||
|
||
await pageObjects.typeOnSendBox('typing 1'); | ||
|
||
activeTyping = await pageObjects.runHook('useActiveTyping'); | ||
|
||
expect(Object.values(activeTyping[0])).toEqual([ | ||
{ | ||
at: 0, | ||
expireAt: 5000, | ||
name: 'Happy Web Chat user', | ||
role: 'user' | ||
} | ||
]); | ||
|
||
await pageObjects.typeOnSendBox(Key.ENTER); | ||
await driver.wait(minNumActivitiesShown(2), timeouts.directLine); | ||
|
||
activeTyping = await pageObjects.runHook('useActiveTyping'); | ||
|
||
expect(Object.values(activeTyping[0])).toEqual([ | ||
{ | ||
at: 0, | ||
expireAt: 5000, | ||
name: 'bot', | ||
role: 'bot' | ||
} | ||
]); | ||
|
||
await pageObjects.typeOnSendBox('.'); | ||
|
||
activeTyping = await pageObjects.runHook('useActiveTyping'); | ||
|
||
expect(Object.values(activeTyping[0]).sort(({ role: x }, { role: y }) => x - y)).toEqual([ | ||
{ | ||
at: 0, | ||
expireAt: 5000, | ||
name: 'bot', | ||
role: 'bot' | ||
}, | ||
{ | ||
at: 0, | ||
expireAt: 5000, | ||
name: 'Happy Web Chat user', | ||
role: 'user' | ||
} | ||
]); | ||
}); | ||
|
||
test('getter should filter out inactive typing', async () => { | ||
const { driver, pageObjects } = await setupWebDriver({ | ||
props: { sendTypingIndicator: true }, | ||
setup: () => | ||
Promise.all([ | ||
window.WebChatTest.loadScript('https://unpkg.com/[email protected]/client/core.min.js'), | ||
window.WebChatTest.loadScript('https://unpkg.com/[email protected]/lolex.js') | ||
]).then(() => { | ||
window.WebChatTest.clock = lolex.install(); | ||
}) | ||
}); | ||
|
||
await driver.wait(uiConnected(), timeouts.directLine); | ||
|
||
let activeTyping; | ||
|
||
await expect(pageObjects.runHook('useActiveTyping')).resolves.toEqual([{}]); | ||
|
||
await pageObjects.typeOnSendBox('Hello, World!'); | ||
|
||
activeTyping = await pageObjects.runHook('useActiveTyping'); | ||
|
||
expect(Object.values(activeTyping[0])).toEqual([ | ||
{ | ||
at: 0, | ||
expireAt: 5000, | ||
name: 'Happy Web Chat user', | ||
role: 'user' | ||
} | ||
]); | ||
|
||
// We need to wait for 6000 ms because: | ||
// 1. t=0: Typed letter "H" | ||
// 2. t=0: Send typing activity | ||
// 3. t=10: Typed letter "a" | ||
// 4. t=10: Scheduled another typing indicator at t=3000 | ||
// 5. t=3000: Send typing activity | ||
await driver.executeScript(() => window.WebChatTest.clock.tick(3000)); | ||
|
||
activeTyping = await pageObjects.runHook('useActiveTyping'); | ||
|
||
expect(Object.values(activeTyping[0])).toEqual([ | ||
{ | ||
at: 3000, | ||
expireAt: 8000, | ||
name: 'Happy Web Chat user', | ||
role: 'user' | ||
} | ||
]); | ||
|
||
await driver.executeScript(() => window.WebChatTest.clock.tick(8000)); | ||
|
||
await expect(pageObjects.runHook('useActiveTyping')).resolves.toEqual([{}]); | ||
|
||
// Even it is filtered out, when setting a longer expiration, it should come back. | ||
activeTyping = await pageObjects.runHook('useActiveTyping', [10000]); | ||
|
||
expect(Object.values(activeTyping[0])).toEqual([ | ||
{ | ||
at: 3000, | ||
expireAt: 13000, | ||
name: 'Happy Web Chat user', | ||
role: 'user' | ||
} | ||
]); | ||
}); | ||
|
||
test('setter should be falsy', async () => { | ||
const { pageObjects } = await setupWebDriver(); | ||
const [_, setActiveTyping] = await pageObjects.runHook('useActiveTyping'); | ||
|
||
expect(setActiveTyping).toBeFalsy(); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { By, until } from 'selenium-webdriver'; | ||
|
||
export default function typingIndicatorShown() { | ||
return until.elementLocated(By.css('.webchat__typingIndicator')); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.