diff --git a/CHANGELOG.md b/CHANGELOG.md index fe6e929f59..dd69393c5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,11 +22,17 @@ Legends: ### Added - Added `styleOptions.richCardTitleOmitHeadingRole` (default `false`) to opt out of `style: 'heading'` on rich card titles, in PR [#5839](https://github.com/microsoft/BotFramework-WebChat/pull/5839), by [@cjennison](https://github.com/cjennison) -- Added support of Adaptive Cards `Action.Submit` action with `msteams/signin` sub-action to open sign-in link in a popup window, in PR [#5860](https://github.com/microsoft/BotFramework-WebChat/pull/5860), by [@compulim](https://github.com/compulim) - - Added `styleOptions.adaptiveCardSignInActionPopupWindowHeight/Width` for sizing the sign-in popup window - - Link to [Adaptive Cards spec](https://adaptivecards.microsoft.com/?topic=SigninSubmitActionData) - - Refer to [this test](./__tests__/html2/adaptiveCard/signInAction.html) for the reference payload - - Note: this implementation is based on observation of how Microsoft Teams behave and could deviate from their official implementation +- ~~Added support of Adaptive Cards `Action.Submit` action with `msteams/signin` sub-action to open sign-in link in a popup window, in PR [#5860](https://github.com/microsoft/BotFramework-WebChat/pull/5860), by [@compulim](https://github.com/compulim)~~ + - ~~Added `styleOptions.adaptiveCardSignInActionPopupWindowHeight/Width` for sizing the sign-in popup window~~ + - ~~Link to [Adaptive Cards spec](https://adaptivecards.microsoft.com/?topic=SigninSubmitActionData)~~ + - ~~Refer to [this test](./__tests__/html2/adaptiveCard/signInAction.html) for the reference payload~~ + - ~~Note: this implementation is based on observation of how Microsoft Teams behave and could deviate from their official implementation~~ + - Obsoleted in favor of PR [#5862](https://github.com/microsoft/BotFramework-WebChat/pull/5862) +- Added card action `webchat:callURL` and [Adaptive Card action `Action.OpenUrlDialog`](https://adaptivecards.microsoft.com/?topic=Action.OpenUrlDialog), in PR [#5862](https://github.com/microsoft/BotFramework-WebChat/pull/5862), by [@compulim](https://github.com/compulim) + - Added `styleOptions.callURLActionPopupWindowHeight/Width` for sizing the popup window + - Reference payload for Direct Line `webchat:callURL` card action can be found in [this test](./__tests__/html2/adaptiveCard/openUrlDialog/heroCard.html) + - Reference payload for Adaptive Card `Action.OpenUrlDialog` can be found in [this test](./__tests__/html2/adaptiveCard/openUrlDialog/simple.html) + - Note: the Adaptive Card implementation is based on observation of how other apps behave and could deviate from their official implementation ### Fixed diff --git a/__tests__/html2/adaptiveCard/msteams/signInSubAction.html.snap-1.png b/__tests__/html2/adaptiveCard/msteams/signInSubAction.html.snap-1.png deleted file mode 100644 index 7862e7e63a..0000000000 Binary files a/__tests__/html2/adaptiveCard/msteams/signInSubAction.html.snap-1.png and /dev/null differ diff --git a/__tests__/html2/adaptiveCard/msteams/signInSubAction.skip.html b/__tests__/html2/adaptiveCard/openUrlDialog/dialog.skip.html similarity index 100% rename from __tests__/html2/adaptiveCard/msteams/signInSubAction.skip.html rename to __tests__/html2/adaptiveCard/openUrlDialog/dialog.skip.html diff --git a/__tests__/html2/adaptiveCard/msteams/signInSubAction.disallowedScheme.html b/__tests__/html2/adaptiveCard/openUrlDialog/disallowedScheme.html similarity index 85% rename from __tests__/html2/adaptiveCard/msteams/signInSubAction.disallowedScheme.html rename to __tests__/html2/adaptiveCard/openUrlDialog/disallowedScheme.html index f685f79214..c159e60278 100644 --- a/__tests__/html2/adaptiveCard/msteams/signInSubAction.disallowedScheme.html +++ b/__tests__/html2/adaptiveCard/openUrlDialog/disallowedScheme.html @@ -52,15 +52,16 @@ { actions: [ { - title: 'Sign in', - type: 'Action.Submit', - data: { - msteams: { - type: 'signin', - value: 'mailto:johndoe@microsoft.com' - } + title: 'Sign in (Action.OpenUrlDialog)', + type: 'Action.OpenUrlDialog', + url: 'mailto:johndoe@microsoft.com', + + fallback: { + title: 'Sign in (Action.OpenUrl)', + type: 'Action.OpenUrl', + url: 'mailto:johndoe@microsoft.com' } - } + }, ], type: 'ActionSet' } @@ -101,14 +102,15 @@ }; // WHEN: The "Sign in" button is clicked. - await host.click(document.querySelector('[aria-label="Sign in"]')); + await host.click(document.querySelector('[aria-label="Sign in (Action.OpenUrlDialog)"]')); // THEN: Should not call `window.open`. expect(windowOpenCalled).toBe(false); // THEN: Should warn. expect(consoleWarnArgs).toEqual([ - 'botframework-webchat: "Action.Submit/msteams" sub-action validation error.', + 'botframework-webchat: Cannot call invalid URL.', + 'mailto:johndoe@microsoft.com', '"value" must have protocol of either "http:" or "https:"' ]); }); diff --git a/__tests__/html2/adaptiveCard/openUrlDialog/heroCard.html b/__tests__/html2/adaptiveCard/openUrlDialog/heroCard.html new file mode 100644 index 0000000000..7534010167 --- /dev/null +++ b/__tests__/html2/adaptiveCard/openUrlDialog/heroCard.html @@ -0,0 +1,110 @@ + + +
+ + + + + + + + diff --git a/__tests__/html2/adaptiveCard/msteams/signInSubAction.relativeURL.html b/__tests__/html2/adaptiveCard/openUrlDialog/relativeURL.html similarity index 87% rename from __tests__/html2/adaptiveCard/msteams/signInSubAction.relativeURL.html rename to __tests__/html2/adaptiveCard/openUrlDialog/relativeURL.html index 3884b40105..c90d8e07e2 100644 --- a/__tests__/html2/adaptiveCard/msteams/signInSubAction.relativeURL.html +++ b/__tests__/html2/adaptiveCard/openUrlDialog/relativeURL.html @@ -52,13 +52,14 @@ { actions: [ { - title: 'Sign in', - type: 'Action.Submit', - data: { - msteams: { - type: 'signin', - value: '/index.html' - } + title: 'Sign in (Action.OpenUrlDialog)', + type: 'Action.OpenUrlDialog', + url: '/index.html', + + fallback: { + title: 'Sign in (Action.OpenUrl)', + type: 'Action.OpenUrl', + url: '/index.html' } } ], @@ -101,14 +102,15 @@ }; // WHEN: The "Sign in" button is clicked. - await host.click(document.querySelector('[aria-label="Sign in"]')); + await host.click(document.querySelector('[aria-label="Sign in (Action.OpenUrlDialog)"]')); // THEN: Should not call `window.open`. expect(windowOpenCalled).toBe(false); // THEN: Should warn. expect(consoleWarnArgs).toEqual([ - 'botframework-webchat: "Action.Submit/msteams" sub-action validation error.', + 'botframework-webchat: Cannot call invalid URL.', + '/index.html', '"value" must be an absolute URL', '"value" must have protocol of either "http:" or "https:"' ]); diff --git a/__tests__/html2/adaptiveCard/msteams/signInSubAction.html b/__tests__/html2/adaptiveCard/openUrlDialog/simple.html similarity index 85% rename from __tests__/html2/adaptiveCard/msteams/signInSubAction.html rename to __tests__/html2/adaptiveCard/openUrlDialog/simple.html index 2d64094d2a..82151781b8 100644 --- a/__tests__/html2/adaptiveCard/msteams/signInSubAction.html +++ b/__tests__/html2/adaptiveCard/openUrlDialog/simple.html @@ -52,15 +52,16 @@ { actions: [ { - title: 'Sign in', - type: 'Action.Submit', - data: { - msteams: { - type: 'signin', - value: new URL('signInSubAction.skip.html', location).toString() - } + title: 'Sign in (Action.OpenUrlDialog)', + type: 'Action.OpenUrlDialog', + url: new URL('dialog.skip.html', location).toString(), + + fallback: { + title: 'Sign in (Action.OpenUrl)', + type: 'Action.OpenUrl', + url: new URL('dialog.skip.html', location).toString() } - } + }, ], type: 'ActionSet' } @@ -93,7 +94,7 @@ // Note: popup.addEventListener('close') does not dispatch. const interval = setInterval(() => { - if (popup.closed) { + if (popup?.closed) { clearInterval(interval); popupClosedDeferred.resolve(); @@ -104,7 +105,7 @@ }; // WHEN: The "Sign in" button is clicked. - await host.click(document.querySelector('[aria-label="Sign in"]')); + await host.click(document.querySelector('[aria-label="Sign in (Action.OpenUrlDialog)"]')); // THEN: Popup window should close itself. await Promise.race([ @@ -116,7 +117,7 @@ ]); expect(windowOpenArgs).toEqual([ - expect.stringContaining('signInSubAction.skip.html'), + expect.stringContaining('dialog.skip.html'), '_blank', 'height=640,popup,width=480' ]); diff --git a/__tests__/html2/adaptiveCard/openUrlDialog/simple.html.snap-1.png b/__tests__/html2/adaptiveCard/openUrlDialog/simple.html.snap-1.png new file mode 100644 index 0000000000..c3f8d61b47 Binary files /dev/null and b/__tests__/html2/adaptiveCard/openUrlDialog/simple.html.snap-1.png differ diff --git a/__tests__/html2/adaptiveCard/msteams/signInSubAction.size.html b/__tests__/html2/adaptiveCard/openUrlDialog/size.html similarity index 84% rename from __tests__/html2/adaptiveCard/msteams/signInSubAction.size.html rename to __tests__/html2/adaptiveCard/openUrlDialog/size.html index 6941a90178..ace527e222 100644 --- a/__tests__/html2/adaptiveCard/msteams/signInSubAction.size.html +++ b/__tests__/html2/adaptiveCard/openUrlDialog/size.html @@ -32,8 +32,8 @@ const { directLine, store } = createDirectLineEmulator(); const styleOptions = { - adaptiveCardSignInActionPopupWindowHeight: 480, - adaptiveCardSignInActionPopupWindowWidth: 360 + callURLActionPopupWindowHeight: 480, + callURLActionPopupWindowWidth: 360 }; renderWebChat({ directLine, store, styleOptions }, document.getElementById('webchat')); @@ -56,13 +56,14 @@ { actions: [ { - title: 'Sign in', - type: 'Action.Submit', - data: { - msteams: { - type: 'signin', - value: new URL('signInSubAction.skip.html', location) - } + title: 'Sign in (Action.OpenUrlDialog)', + type: 'Action.OpenUrlDialog', + url: new URL('dialog.skip.html', location).toString(), + + fallback: { + title: 'Sign in (Action.OpenUrl)', + type: 'Action.OpenUrl', + url: new URL('dialog.skip.html', location).toString() } } ], @@ -96,7 +97,7 @@ // Note: popup.addEventListener('close') does not dispatch. const interval = setInterval(() => { - if (popup.closed) { + if (popup?.closed) { clearInterval(interval); popupClosedDeferred.resolve(); @@ -107,7 +108,7 @@ }; // WHEN: The "Sign in" button is clicked. - await host.click(document.querySelector('[aria-label="Sign in"]')); + await host.click(document.querySelector('[aria-label="Sign in (Action.OpenUrlDialog)"]')); // THEN: Popup window should close itself. await Promise.race([ @@ -119,7 +120,7 @@ ]); expect(windowOpenArgs).toEqual([ - expect.stringContaining('signInSubAction.skip.html'), + expect.stringContaining('dialog.skip.html'), '_blank', 'height=480,popup,width=360' ]); diff --git a/__tests__/html2/adaptiveCard/openUrlDialog/suggestedActions.html b/__tests__/html2/adaptiveCard/openUrlDialog/suggestedActions.html new file mode 100644 index 0000000000..892b5cd01e --- /dev/null +++ b/__tests__/html2/adaptiveCard/openUrlDialog/suggestedActions.html @@ -0,0 +1,111 @@ + + + + + + + + + + + diff --git a/__tests__/html2/adaptiveCard/msteams/unknownSubAction.html b/__tests__/html2/cardAction/heroCard.webchatCallURL.html similarity index 51% rename from __tests__/html2/adaptiveCard/msteams/unknownSubAction.html rename to __tests__/html2/cardAction/heroCard.webchatCallURL.html index 1ab4e2dcce..af67ea79ca 100644 --- a/__tests__/html2/adaptiveCard/msteams/unknownSubAction.html +++ b/__tests__/html2/cardAction/heroCard.webchatCallURL.html @@ -36,35 +36,20 @@ await pageConditions.uiConnected(); + // GIVEN: A Hero card with a "webchat:callURL" button rendered as a direct card-action payload. await directLine.emulateIncomingActivity({ attachments: [ { - contentType: 'application/vnd.microsoft.card.adaptive', + contentType: 'application/vnd.microsoft.card.hero', content: { - $schema: 'http://adaptivecards.io/schemas/adaptive-card.json', - type: 'AdaptiveCard', - version: '1.2', - body: [ + buttons: [ { - text: 'Hello, World!', - type: 'TextBlock' - }, - { - actions: [ - { - title: 'Sign in', - type: 'Action.Submit', - data: { - msteams: { - type: 'imBack', - value: 'Hello, World!' - } - } - } - ], - type: 'ActionSet' + title: 'Call URL', + type: 'webchat:callURL', + value: 'https://bing.com/' } - ] + ], + title: 'Hero card' } } ], @@ -77,29 +62,23 @@ type: 'message' }); - // THEN: Should render the Adaptive Card with a "Sign in" button. await pageConditions.numActivitiesShown(1); - // GIVEN: Intercept `console.warn`. - const originalConsoleWarn = console.warn.bind(console); - let consoleWarnArgs; + // GIVEN: Intercept `window.open`. + const originalOpen = window.open.bind(window); + let windowOpenArgs; - console.warn = (...args) => { - consoleWarnArgs = args; + window.open = (...args) => { + windowOpenArgs = args; - return originalConsoleWarn(...args); + return originalOpen(...args); }; - // WHEN: The "Sign in" button is clicked. - await host.click(document.querySelector('[aria-label="Sign in"]')); + // WHEN: The "Call URL" button is clicked. + await host.click(document.querySelector('[aria-label="Call URL"]')); - // THEN: Should warn. - expect(consoleWarnArgs).toEqual([ - 'botframework-webchat: "Action.Submit/msteams" sub-action validation error.', - "Sub-action type must be \"signin\"", - '"value" must be an absolute URL', - '"value" must have protocol of either "http:" or "https:"' - ]); + // THEN: Should call `window.open` using the popup window features, instead of a plain "openUrl" dispatch. + expect(windowOpenArgs).toEqual(['https://bing.com/', '_blank', 'height=640,popup,width=480']); }); + + + +diff --git a/__tests__/html2/cardAction/webchatCallURL.heroCard.button.html b/__tests__/html2/cardAction/webchatCallURL.heroCard.button.html new file mode 100644 index 0000000000..71332fbfdd --- /dev/null +++ b/__tests__/html2/cardAction/webchatCallURL.heroCard.button.html @@ -0,0 +1,88 @@ + + +
+ + +
+