diff --git a/CHANGELOG.md b/CHANGELOG.md index b836f46116..b406bbc022 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] ### Changed + - `*`: Bumps all dev dependencies to latest version, by [@compulim](https://github.com/compulim), in PR [#2182](https://github.com/microsoft/BotFramework-WebChat/pull/2182), notably - [`@babel/*@7.5.4`](https://www.npmjs.com/package/@babel/core) - [`jest@24.8.0`](https://www.npmjs.com/package/jest) @@ -47,6 +48,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Fix [#2160](https://github.com/microsoft/BotFramework-WebChat/issues/2160). Clear suggested actions after clicking on a suggested actions of type `openUrl`, by [@tdurnford](https://github.com/tdurnford) in PR [#2190](https://github.com/microsoft/BotFramework-WebChat/pull/2190) - Fix [#2187](https://github.com/microsoft/BotFramework-WebChat/issues/2187). Bump core-js and update core-js modules on index-es5.js, by [@corinagum](https://github.com/corinagum) in PR [#2195](https://github.com/microsoft/BotFramework-WebChat/pull/2195) +### Added + +- Added bubble nub and style options, by [@compulim](https://github.com/compulim), in PR [#2137](https://github.com/Microsoft/BotFramework-WebChat/pull/2137) ## [4.5.0] - 2019-07-10 diff --git a/__tests__/__image_snapshots__/chrome-docker/bubble-border-js-bubble-border-with-color-radius-style-and-width-set-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/bubble-border-js-bubble-border-with-color-radius-style-and-width-set-1-snap.png new file mode 100644 index 0000000000..3819f04fad Binary files /dev/null and b/__tests__/__image_snapshots__/chrome-docker/bubble-border-js-bubble-border-with-color-radius-style-and-width-set-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/bubble-border-js-bubble-border-with-deprecated-border-style-of-2-px-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/bubble-border-js-bubble-border-with-deprecated-border-style-of-2-px-1-snap.png new file mode 100644 index 0000000000..15bfb5237e Binary files /dev/null and b/__tests__/__image_snapshots__/chrome-docker/bubble-border-js-bubble-border-with-deprecated-border-style-of-2-px-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/bubble-border-js-bubble-border-with-deprecated-border-style-of-dashed-2-px-red-and-dotted-2-px-green-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/bubble-border-js-bubble-border-with-deprecated-border-style-of-dashed-2-px-red-and-dotted-2-px-green-1-snap.png new file mode 100644 index 0000000000..01cd11022c Binary files /dev/null and b/__tests__/__image_snapshots__/chrome-docker/bubble-border-js-bubble-border-with-deprecated-border-style-of-dashed-2-px-red-and-dotted-2-px-green-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/bubble-border-js-bubble-border-with-deprecated-border-style-of-dashed-and-dotted-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/bubble-border-js-bubble-border-with-deprecated-border-style-of-dashed-and-dotted-1-snap.png new file mode 100644 index 0000000000..be5bd5dcbb Binary files /dev/null and b/__tests__/__image_snapshots__/chrome-docker/bubble-border-js-bubble-border-with-deprecated-border-style-of-dashed-and-dotted-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/bubble-border-js-bubble-border-with-deprecated-border-style-of-red-and-green-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/bubble-border-js-bubble-border-with-deprecated-border-style-of-red-and-green-1-snap.png new file mode 100644 index 0000000000..2504d6a350 Binary files /dev/null and b/__tests__/__image_snapshots__/chrome-docker/bubble-border-js-bubble-border-with-deprecated-border-style-of-red-and-green-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/bubble-border-js-bubble-border-with-deprecated-border-style-with-color-radius-style-and-width-set-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/bubble-border-js-bubble-border-with-deprecated-border-style-with-color-radius-style-and-width-set-1-snap.png new file mode 100644 index 0000000000..3819f04fad Binary files /dev/null and b/__tests__/__image_snapshots__/chrome-docker/bubble-border-js-bubble-border-with-deprecated-border-style-with-color-radius-style-and-width-set-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-at-corner-with-offset-at-bottom-should-have-flipped-nub-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-at-corner-with-offset-at-bottom-should-have-flipped-nub-1-snap.png new file mode 100644 index 0000000000..db4ecd6cda Binary files /dev/null and b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-at-corner-with-offset-at-bottom-should-have-flipped-nub-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-at-corner-with-offset-of-10-px-should-have-corner-radius-of-10-px-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-at-corner-with-offset-of-10-px-should-have-corner-radius-of-10-px-1-snap.png new file mode 100644 index 0000000000..489d04017f Binary files /dev/null and b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-at-corner-with-offset-of-10-px-should-have-corner-radius-of-10-px-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-at-corner-with-offset-of-5-px-should-have-corner-radius-of-5-px-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-at-corner-with-offset-of-5-px-should-have-corner-radius-of-5-px-1-snap.png new file mode 100644 index 0000000000..88270e767f Binary files /dev/null and b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-at-corner-with-offset-of-5-px-should-have-corner-radius-of-5-px-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-at-corner-with-offset-of-minus-10-px-should-have-corner-radius-of-10-px-and-flipped-nub-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-at-corner-with-offset-of-minus-10-px-should-have-corner-radius-of-10-px-and-flipped-nub-1-snap.png new file mode 100644 index 0000000000..70de4ed8a5 Binary files /dev/null and b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-at-corner-with-offset-of-minus-10-px-should-have-corner-radius-of-10-px-and-flipped-nub-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-at-corner-with-offset-of-minus-5-px-should-have-corner-radius-of-5-px-and-flipped-nub-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-at-corner-with-offset-of-minus-5-px-should-have-corner-radius-of-5-px-and-flipped-nub-1-snap.png new file mode 100644 index 0000000000..6d20c10a78 Binary files /dev/null and b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-at-corner-with-offset-of-minus-5-px-should-have-corner-radius-of-5-px-and-flipped-nub-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-with-avatar-initials-and-a-single-message-should-have-nub-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-with-avatar-initials-and-a-single-message-should-have-nub-1-snap.png new file mode 100644 index 0000000000..f08df118c8 Binary files /dev/null and b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-with-avatar-initials-and-a-single-message-should-have-nub-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-with-avatar-initials-and-carousel-with-a-message-should-have-nub-on-message-only-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-with-avatar-initials-and-carousel-with-a-message-should-have-nub-on-message-only-1-snap.png new file mode 100644 index 0000000000..56793ac816 Binary files /dev/null and b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-with-avatar-initials-and-carousel-with-a-message-should-have-nub-on-message-only-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-with-avatar-initials-and-carousel-with-a-single-attachment-should-have-nub-on-message-only-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-with-avatar-initials-and-carousel-with-a-single-attachment-should-have-nub-on-message-only-1-snap.png new file mode 100644 index 0000000000..0d841276ed Binary files /dev/null and b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-with-avatar-initials-and-carousel-with-a-single-attachment-should-have-nub-on-message-only-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-with-avatar-initials-and-carousel-without-a-message-should-not-have-nubs-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-with-avatar-initials-and-carousel-without-a-message-should-not-have-nubs-1-snap.png new file mode 100644 index 0000000000..1a3eb9a654 Binary files /dev/null and b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-with-avatar-initials-and-carousel-without-a-message-should-not-have-nubs-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-with-avatar-initials-and-stacked-without-a-message-should-not-have-nubs-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-with-avatar-initials-and-stacked-without-a-message-should-not-have-nubs-1-snap.png new file mode 100644 index 0000000000..313a1ac590 Binary files /dev/null and b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-with-avatar-initials-and-stacked-without-a-message-should-not-have-nubs-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-with-standard-setup-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-with-standard-setup-1-snap.png new file mode 100644 index 0000000000..6f27b03f39 Binary files /dev/null and b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-with-standard-setup-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-without-avatar-initials-and-a-single-message-should-have-nub-and-indented-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-without-avatar-initials-and-a-single-message-should-have-nub-and-indented-1-snap.png new file mode 100644 index 0000000000..cf03c59caf Binary files /dev/null and b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-without-avatar-initials-and-a-single-message-should-have-nub-and-indented-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-without-avatar-initials-and-carousel-with-a-message-should-have-nub-on-message-only-and-indented-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-without-avatar-initials-and-carousel-with-a-message-should-have-nub-on-message-only-and-indented-1-snap.png new file mode 100644 index 0000000000..e9570d3659 Binary files /dev/null and b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-without-avatar-initials-and-carousel-with-a-message-should-have-nub-on-message-only-and-indented-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-without-avatar-initials-and-carousel-with-a-single-attachment-should-have-nub-on-message-only-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-without-avatar-initials-and-carousel-with-a-single-attachment-should-have-nub-on-message-only-1-snap.png new file mode 100644 index 0000000000..089110a2b3 Binary files /dev/null and b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-without-avatar-initials-and-carousel-with-a-single-attachment-should-have-nub-on-message-only-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-without-avatar-initials-and-carousel-without-a-message-should-not-have-nubs-and-indented-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-without-avatar-initials-and-carousel-without-a-message-should-not-have-nubs-and-indented-1-snap.png new file mode 100644 index 0000000000..a8bc89351c Binary files /dev/null and b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-without-avatar-initials-and-carousel-without-a-message-should-not-have-nubs-and-indented-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-without-avatar-initials-and-stacked-without-a-message-should-not-have-nubs-and-indented-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-without-avatar-initials-and-stacked-without-a-message-should-not-have-nubs-and-indented-1-snap.png new file mode 100644 index 0000000000..6c8e0c5d05 Binary files /dev/null and b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-without-avatar-initials-and-stacked-without-a-message-should-not-have-nubs-and-indented-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/carousel-js-carousel-with-avatar-initials-1-attachment-with-wide-screen-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/carousel-js-carousel-with-avatar-initials-1-attachment-with-wide-screen-1-snap.png index 04bf6e349d..beda61d5f7 100644 Binary files a/__tests__/__image_snapshots__/chrome-docker/carousel-js-carousel-with-avatar-initials-1-attachment-with-wide-screen-1-snap.png and b/__tests__/__image_snapshots__/chrome-docker/carousel-js-carousel-with-avatar-initials-1-attachment-with-wide-screen-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/carousel-js-carousel-without-avatar-initials-1-attachment-with-wide-screen-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/carousel-js-carousel-without-avatar-initials-1-attachment-with-wide-screen-1-snap.png index e01c1d02ff..fbe4aae65f 100644 Binary files a/__tests__/__image_snapshots__/chrome-docker/carousel-js-carousel-without-avatar-initials-1-attachment-with-wide-screen-1-snap.png and b/__tests__/__image_snapshots__/chrome-docker/carousel-js-carousel-without-avatar-initials-1-attachment-with-wide-screen-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/stacked-js-stacked-with-avatar-initials-1-attachment-with-wide-screen-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/stacked-js-stacked-with-avatar-initials-1-attachment-with-wide-screen-1-snap.png index 5675f11f22..084d4ea8b1 100644 Binary files a/__tests__/__image_snapshots__/chrome-docker/stacked-js-stacked-with-avatar-initials-1-attachment-with-wide-screen-1-snap.png and b/__tests__/__image_snapshots__/chrome-docker/stacked-js-stacked-with-avatar-initials-1-attachment-with-wide-screen-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/stacked-js-stacked-without-avatar-initials-1-attachment-with-wide-screen-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/stacked-js-stacked-without-avatar-initials-1-attachment-with-wide-screen-1-snap.png index ce8875b5e8..80f527a1cc 100644 Binary files a/__tests__/__image_snapshots__/chrome-docker/stacked-js-stacked-without-avatar-initials-1-attachment-with-wide-screen-1-snap.png and b/__tests__/__image_snapshots__/chrome-docker/stacked-js-stacked-without-avatar-initials-1-attachment-with-wide-screen-1-snap.png differ diff --git a/__tests__/bubbleBorder.js b/__tests__/bubbleBorder.js new file mode 100644 index 0000000000..39bbb64ef6 --- /dev/null +++ b/__tests__/bubbleBorder.js @@ -0,0 +1,131 @@ +import { imageSnapshotOptions, timeouts } from './constants.json'; + +import allImagesLoaded from './setup/conditions/allImagesLoaded'; +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); + +async function sendMessageAndMatchSnapshot(driver, pageObjects, message) { + await driver.wait(uiConnected(), timeouts.directLine); + await pageObjects.sendMessageViaSendBox(message); + + await driver.wait(minNumActivitiesShown(3), timeouts.directLine); + + const base64PNG = await driver.takeScreenshot(); + + expect(base64PNG).toMatchImageSnapshot(imageSnapshotOptions); +} + +describe('bubble border', () => { + test('with color, radius, style, and width set', async () => { + const { driver, pageObjects } = await setupWebDriver({ + props: { + styleOptions: { + bubbleBorderColor: 'Red', + bubbleBorderRadius: 10, + bubbleBorderStyle: 'dashed', + bubbleBorderWidth: 2, + + bubbleFromUserBorderColor: 'Green', + bubbleFromUserBorderRadius: 20, + bubbleFromUserBorderStyle: 'dotted', + bubbleFromUserBorderWidth: 3 + } + }, + zoom: 3 + }); + + await sendMessageAndMatchSnapshot(driver, pageObjects, 'echo Hello, World!'); + }); + + describe('with deprecated border style', () => { + test('with color, radius, style, and width set', async () => { + const { driver, pageObjects } = await setupWebDriver({ + props: { + styleOptions: { + bubbleBorder: 'dashed 2px Red', + bubbleBorderRadius: 10, + + bubbleFromUserBorder: 'dotted 3px Green', + bubbleFromUserBorderRadius: 20 + } + }, + zoom: 3 + }); + + await sendMessageAndMatchSnapshot(driver, pageObjects, 'echo Hello, World!'); + }); + + test('of "dashed 2px Red" and "dotted 2px Green"', async () => { + const { driver, pageObjects } = await setupWebDriver({ + props: { + styleOptions: { + bubbleBorder: 'dashed 2px Red', + bubbleFromUserBorder: 'dotted 2px Green' + } + } + }); + + await driver.wait(uiConnected(), timeouts.directLine); + await pageObjects.sendMessageViaSendBox('Hello, World!'); + await driver.wait(minNumActivitiesShown(2), timeouts.directLine); + + expect(await driver.takeScreenshot()).toMatchImageSnapshot(imageSnapshotOptions); + }); + + test('of "dashed" and "dotted"', async () => { + const { driver, pageObjects } = await setupWebDriver({ + props: { + styleOptions: { + bubbleBorder: 'dashed', + bubbleFromUserBorder: 'dotted' + } + } + }); + + await driver.wait(uiConnected(), timeouts.directLine); + await pageObjects.sendMessageViaSendBox('Hello, World!'); + await driver.wait(minNumActivitiesShown(2), timeouts.directLine); + + expect(await driver.takeScreenshot()).toMatchImageSnapshot(imageSnapshotOptions); + }); + + test('of "2px"', async () => { + const { driver, pageObjects } = await setupWebDriver({ + props: { + styleOptions: { + bubbleBorder: '2px', + bubbleFromUserBorder: '2px' + } + } + }); + + await driver.wait(uiConnected(), timeouts.directLine); + await pageObjects.sendMessageViaSendBox('Hello, World!'); + await driver.wait(minNumActivitiesShown(2), timeouts.directLine); + + expect(await driver.takeScreenshot()).toMatchImageSnapshot(imageSnapshotOptions); + }); + + test('of "Red" and "Green"', async () => { + const { driver, pageObjects } = await setupWebDriver({ + props: { + styleOptions: { + bubbleBorder: 'Red', + bubbleFromUserBorder: 'Green' + } + } + }); + + await driver.wait(uiConnected(), timeouts.directLine); + await pageObjects.sendMessageViaSendBox('Hello, World!'); + await driver.wait(minNumActivitiesShown(2), timeouts.directLine); + + expect(await driver.takeScreenshot()).toMatchImageSnapshot(imageSnapshotOptions); + }); + }); +}); diff --git a/__tests__/bubbleNub.js b/__tests__/bubbleNub.js new file mode 100644 index 0000000000..806c8e0c8f --- /dev/null +++ b/__tests__/bubbleNub.js @@ -0,0 +1,216 @@ +import { imageSnapshotOptions, timeouts } from './constants.json'; + +import allImagesLoaded from './setup/conditions/allImagesLoaded'; +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); + +async function sendMessageAndMatchSnapshot(driver, pageObjects, message) { + await driver.wait(uiConnected(), timeouts.directLine); + await pageObjects.sendMessageViaSendBox(message); + + await driver.wait(minNumActivitiesShown(2), timeouts.directLine); + await driver.wait(allImagesLoaded(), timeouts.fetch); + + const base64PNG = await driver.takeScreenshot(); + + expect(base64PNG).toMatchImageSnapshot(imageSnapshotOptions); +} + +describe('bubble nub', () => { + let props; + + test('with standard setup', async () => { + const { driver, pageObjects } = await setupWebDriver({ + props: { + styleOptions: { + bubbleNubOffset: 0, + bubbleNubSize: 10, + bubbleFromUserNubOffset: 0, + bubbleFromUserNubSize: 10 + } + }, + zoom: 3 + }); + + await sendMessageAndMatchSnapshot(driver, pageObjects, 'layout carousel'); + }); + + beforeEach(() => { + props = { + styleOptions: { + bubbleBorderColor: 'red', + bubbleBorderRadius: 10, + bubbleBorderWidth: 2, + bubbleFromUserBorderColor: 'green', + bubbleFromUserBorderRadius: 10, + bubbleFromUserNubOffset: 0, + bubbleFromUserNubSize: 10, + bubbleFromUserBorderWidth: 2, + bubbleNubOffset: 0, + bubbleNubSize: 10 + } + }; + }); + + describe('with avatar initials', () => { + beforeEach(() => { + props = { + ...props, + styleOptions: { + ...props.styleOptions, + botAvatarInitials: 'WC', + userAvatarInitials: 'WW' + } + }; + }); + + test('and carousel with a message should have nub on message only', async () => { + const { driver, pageObjects } = await setupWebDriver({ props, zoom: 3 }); + + await sendMessageAndMatchSnapshot(driver, pageObjects, 'layout carousel'); + }); + + test('and carousel without a message should not have nubs', async () => { + const { driver, pageObjects } = await setupWebDriver({ props, zoom: 3 }); + + await sendMessageAndMatchSnapshot(driver, pageObjects, 'carousel'); + }); + + test('and stacked without a message should not have nubs', async () => { + const { driver, pageObjects } = await setupWebDriver({ props, zoom: 3 }); + + await sendMessageAndMatchSnapshot(driver, pageObjects, 'layout single'); + }); + + test('and a single message should have nub', async () => { + const { driver, pageObjects } = await setupWebDriver({ props, zoom: 3 }); + + await sendMessageAndMatchSnapshot(driver, pageObjects, 'Hello, World!'); + }); + + test('and carousel with a single attachment should have nub on message only', async () => { + const { driver, pageObjects } = await setupWebDriver({ props, zoom: 3 }); + + await sendMessageAndMatchSnapshot(driver, pageObjects, 'layout single carousel'); + }); + }); + + describe('without avatar initials', () => { + test('and carousel with a message should have nub on message only and indented', async () => { + const { driver, pageObjects } = await setupWebDriver({ props, zoom: 3 }); + + await sendMessageAndMatchSnapshot(driver, pageObjects, 'layout carousel'); + }); + + test('and carousel without a message should not have nubs and indented', async () => { + const { driver, pageObjects } = await setupWebDriver({ props, zoom: 3 }); + + await sendMessageAndMatchSnapshot(driver, pageObjects, 'carousel'); + }); + + test('and stacked without a message should not have nubs and indented', async () => { + const { driver, pageObjects } = await setupWebDriver({ props, zoom: 3 }); + + await sendMessageAndMatchSnapshot(driver, pageObjects, 'layout single'); + }); + + test('and a single message should have nub and indented', async () => { + const { driver, pageObjects } = await setupWebDriver({ props, zoom: 3 }); + + await sendMessageAndMatchSnapshot(driver, pageObjects, 'Hello, World!'); + }); + + test('and carousel with a single attachment should have nub on message only', async () => { + const { driver, pageObjects } = await setupWebDriver({ props, zoom: 3 }); + + await sendMessageAndMatchSnapshot(driver, pageObjects, 'layout single carousel'); + }); + }); + + describe('at corner with offset', () => { + test('of 5px should have corner radius of 5px', async () => { + const { driver, pageObjects } = await setupWebDriver({ + props: { + ...props, + styleOptions: { + ...props.styleOptions, + bubbleFromUserNubOffset: 5, + bubbleNubOffset: 5 + } + }, + zoom: 3 + }); + + await sendMessageAndMatchSnapshot(driver, pageObjects, 'Hello, World!'); + }); + + test('of 10px should have corner radius of 10px', async () => { + const { driver, pageObjects } = await setupWebDriver({ + props: { + ...props, + styleOptions: { + ...props.styleOptions, + bubbleFromUserNubOffset: 10, + bubbleNubOffset: 10 + } + }, + zoom: 3 + }); + + await sendMessageAndMatchSnapshot(driver, pageObjects, 'Hello, World!'); + }); + + test('of minus 5px should have corner radius of 5px and flipped nub', async () => { + const { driver, pageObjects } = await setupWebDriver({ + props: { + ...props, + styleOptions: { + ...props.styleOptions, + bubbleFromUserNubOffset: -5, + bubbleNubOffset: -5 + } + }, + zoom: 3 + }); + + await sendMessageAndMatchSnapshot(driver, pageObjects, 'Hello, World!'); + }); + + test('of minus 10px should have corner radius of 10px and flipped nub', async () => { + const { driver, pageObjects } = await setupWebDriver({ + props: { + ...props, + styleOptions: { + ...props.styleOptions, + bubbleFromUserNubOffset: -10, + bubbleNubOffset: -10 + } + }, + zoom: 3 + }); + + await sendMessageAndMatchSnapshot(driver, pageObjects, 'Hello, World!'); + }); + + test('at bottom should have flipped nub', async () => { + const { driver, pageObjects } = await setupWebDriver({ + props: { + ...props, + styleOptions: { + ...props.styleOptions, + bubbleFromUserNubOffset: 'bottom', + bubbleNubOffset: 'bottom' + } + }, + zoom: 3 + }); + + await sendMessageAndMatchSnapshot(driver, pageObjects, 'Hello, World!'); + }); + }); +}); diff --git a/__tests__/setup/setupTestEnvironment.js b/__tests__/setup/setupTestEnvironment.js index eb13f97b51..ebfd1fa597 100644 --- a/__tests__/setup/setupTestEnvironment.js +++ b/__tests__/setup/setupTestEnvironment.js @@ -1,6 +1,6 @@ import { Options } from 'selenium-webdriver/chrome'; -export default function setupTestEnvironment(browserName, builder, { height, width } = {}) { +export default function setupTestEnvironment(browserName, builder, { height = 640, width = 360, zoom = 1 } = {}) { switch (browserName) { case 'chrome-local': return { @@ -8,7 +8,7 @@ export default function setupTestEnvironment(browserName, builder, { height, wid builder: builder .forBrowser('chrome') .setChromeOptions( - (builder.getChromeOptions() || new Options()).windowSize({ height: height || 640, width: width || 360 }) + (builder.getChromeOptions() || new Options()).windowSize({ height: height * zoom, width: width * zoom }) ) }; @@ -22,7 +22,7 @@ export default function setupTestEnvironment(browserName, builder, { height, wid .setChromeOptions( (builder.getChromeOptions() || new Options()) .headless() - .windowSize({ height: height || 640, width: width || 360 }) + .windowSize({ height: height * zoom, width: width * zoom }) ) }; } diff --git a/__tests__/setup/setupTestFramework.js b/__tests__/setup/setupTestFramework.js index 8f21bd6cf9..2c4d469df9 100644 --- a/__tests__/setup/setupTestFramework.js +++ b/__tests__/setup/setupTestFramework.js @@ -72,6 +72,10 @@ global.setupWebDriver = async options => { (coverage, options, callback) => { window.__coverage__ = coverage; + if (options.zoom) { + document.body.style.zoom = options.zoom; + } + main(options).then( () => callback(), err => { diff --git a/packages/component/package-lock.json b/packages/component/package-lock.json index 1e75b8f14e..16ba476906 100644 --- a/packages/component/package-lock.json +++ b/packages/component/package-lock.json @@ -1608,6 +1608,15 @@ "object-visit": "^1.0.0" } }, + "color": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.1.1.tgz", + "integrity": "sha512-PvUltIXRjehRKPSy89VnDWFKY58xyhTLyxIg21vwQBI6qLwZNPmC8k3C1uytIgFKEpOIzN4y32iPm8231zFHIg==", + "requires": { + "color-convert": "^1.9.1", + "color-string": "^1.5.2" + } + }, "color-convert": { "version": "1.9.2", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz", @@ -1621,6 +1630,15 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=" }, + "color-string": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", + "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, "commander": { "version": "2.20.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", @@ -4889,6 +4907,21 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "requires": { + "is-arrayish": "^0.3.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + } + } + }, "simple-update-in": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/simple-update-in/-/simple-update-in-1.3.0.tgz", diff --git a/packages/component/package.json b/packages/component/package.json index 6bfb6b8f9e..4c7581f99a 100644 --- a/packages/component/package.json +++ b/packages/component/package.json @@ -49,6 +49,7 @@ "botframework-webchat-core": "0.0.0-0", "bytes": "^3.0.0", "classnames": "^2.2.6", + "color": "^3.1.1", "eslint": "^5.16.0", "eslint-plugin-react": "^7.13.0", "glamor": "^2.20.40", diff --git a/packages/component/src/Activity/Bubble.js b/packages/component/src/Activity/Bubble.js index e4c1e2ad5b..c8763e39d1 100644 --- a/packages/component/src/Activity/Bubble.js +++ b/packages/component/src/Activity/Bubble.js @@ -1,12 +1,37 @@ +import { css } from 'glamor'; import classNames from 'classnames'; import PropTypes from 'prop-types'; import React from 'react'; import connectToWebChat from '../connectToWebChat'; -const Bubble = ({ 'aria-hidden': ariaHidden, children, className, fromUser, styleSet }) => ( -