diff --git a/.eslintrc.react.yml b/.eslintrc.react.yml index 7c0a66f1d1..0a281a14aa 100644 --- a/.eslintrc.react.yml +++ b/.eslintrc.react.yml @@ -41,9 +41,6 @@ rules: - error - multiline-multiprop react/jsx-handler-names: error - react/jsx-indent: - - error - - 2 react/jsx-indent-props: - error - 2 diff --git a/__tests__/__image_snapshots__/html/activity-add-decorate-js-activity-middleware-adds-a-custom-activity-with-decoration-1-snap.png b/__tests__/__image_snapshots__/html/activity-add-decorate-js-activity-middleware-adds-a-custom-activity-with-decoration-1-snap.png new file mode 100644 index 0000000000..accf8cd06c Binary files /dev/null and b/__tests__/__image_snapshots__/html/activity-add-decorate-js-activity-middleware-adds-a-custom-activity-with-decoration-1-snap.png differ diff --git a/__tests__/__image_snapshots__/html/activity-add-js-activity-middleware-adds-a-custom-activity-1-snap.png b/__tests__/__image_snapshots__/html/activity-add-js-activity-middleware-adds-a-custom-activity-1-snap.png new file mode 100644 index 0000000000..54d9d25097 Binary files /dev/null and b/__tests__/__image_snapshots__/html/activity-add-js-activity-middleware-adds-a-custom-activity-1-snap.png differ diff --git a/__tests__/__image_snapshots__/html/activity-decorate-js-activity-middleware-decorates-an-activity-by-text-1-snap.png b/__tests__/__image_snapshots__/html/activity-decorate-js-activity-middleware-decorates-an-activity-by-text-1-snap.png new file mode 100644 index 0000000000..8985b97f78 Binary files /dev/null and b/__tests__/__image_snapshots__/html/activity-decorate-js-activity-middleware-decorates-an-activity-by-text-1-snap.png differ diff --git a/__tests__/__image_snapshots__/html/activity-remove-js-activity-middleware-removes-an-activity-by-text-1-snap.png b/__tests__/__image_snapshots__/html/activity-remove-js-activity-middleware-removes-an-activity-by-text-1-snap.png new file mode 100644 index 0000000000..db94053003 Binary files /dev/null and b/__tests__/__image_snapshots__/html/activity-remove-js-activity-middleware-removes-an-activity-by-text-1-snap.png differ diff --git a/__tests__/__image_snapshots__/html/activity-remove-replace-js-activity-middleware-removes-activity-and-replaces-activity-1-snap.png b/__tests__/__image_snapshots__/html/activity-remove-replace-js-activity-middleware-removes-activity-and-replaces-activity-1-snap.png new file mode 100644 index 0000000000..3056863b8a Binary files /dev/null and b/__tests__/__image_snapshots__/html/activity-remove-replace-js-activity-middleware-removes-activity-and-replaces-activity-1-snap.png differ diff --git a/__tests__/__image_snapshots__/html/activity-replace-js-activity-middleware-replaces-an-activity-by-text-1-snap.png b/__tests__/__image_snapshots__/html/activity-replace-js-activity-middleware-replaces-an-activity-by-text-1-snap.png new file mode 100644 index 0000000000..df2489d748 Binary files /dev/null and b/__tests__/__image_snapshots__/html/activity-replace-js-activity-middleware-replaces-an-activity-by-text-1-snap.png differ diff --git a/__tests__/__image_snapshots__/html/activity-replace-remove-js-activity-middleware-replaces-activity-and-removes-activity-1-snap.png b/__tests__/__image_snapshots__/html/activity-replace-remove-js-activity-middleware-replaces-activity-and-removes-activity-1-snap.png new file mode 100644 index 0000000000..d774db9e6b Binary files /dev/null and b/__tests__/__image_snapshots__/html/activity-replace-remove-js-activity-middleware-replaces-activity-and-removes-activity-1-snap.png differ diff --git a/__tests__/__image_snapshots__/html/use-create-activity-renderer-decorate-js-activity-middleware-hooks-decorates-an-activity-when-used-with-use-create-activity-renderer-1-snap.png b/__tests__/__image_snapshots__/html/use-create-activity-renderer-decorate-js-activity-middleware-hooks-decorates-an-activity-when-used-with-use-create-activity-renderer-1-snap.png new file mode 100644 index 0000000000..9997253cf4 Binary files /dev/null and b/__tests__/__image_snapshots__/html/use-create-activity-renderer-decorate-js-activity-middleware-hooks-decorates-an-activity-when-used-with-use-create-activity-renderer-1-snap.png differ diff --git a/__tests__/__image_snapshots__/html/use-render-attachment-decorate-js-activity-middleware-hooks-decorates-an-activity-when-used-with-use-render-attachment-1-snap.png b/__tests__/__image_snapshots__/html/use-render-attachment-decorate-js-activity-middleware-hooks-decorates-an-activity-when-used-with-use-render-attachment-1-snap.png new file mode 100644 index 0000000000..ae91db40d7 Binary files /dev/null and b/__tests__/__image_snapshots__/html/use-render-attachment-decorate-js-activity-middleware-hooks-decorates-an-activity-when-used-with-use-render-attachment-1-snap.png differ diff --git a/__tests__/html/middleware/shim-v1-v2/activity.add.decorate.html b/__tests__/html/middleware/shim-v1-v2/activity.add.decorate.html new file mode 100644 index 0000000000..d5c232c7cc --- /dev/null +++ b/__tests__/html/middleware/shim-v1-v2/activity.add.decorate.html @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/__tests__/html/middleware/shim-v1-v2/activity.add.decorate.js b/__tests__/html/middleware/shim-v1-v2/activity.add.decorate.js new file mode 100644 index 0000000000..613003a438 --- /dev/null +++ b/__tests__/html/middleware/shim-v1-v2/activity.add.decorate.js @@ -0,0 +1,6 @@ +/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */ + +describe('activity middleware', () => { + test('adds a custom activity with decoration', () => + runHTML('./middleware/shim-v1-v2/activity.add.decorate.html')); +}); diff --git a/__tests__/html/middleware/shim-v1-v2/activity.remove.replace.html b/__tests__/html/middleware/shim-v1-v2/activity.remove.replace.html new file mode 100644 index 0000000000..d823ea779a --- /dev/null +++ b/__tests__/html/middleware/shim-v1-v2/activity.remove.replace.html @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/__tests__/html/middleware/shim-v1-v2/activity.remove.replace.js b/__tests__/html/middleware/shim-v1-v2/activity.remove.replace.js new file mode 100644 index 0000000000..11948f47e6 --- /dev/null +++ b/__tests__/html/middleware/shim-v1-v2/activity.remove.replace.js @@ -0,0 +1,6 @@ +/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */ + +describe('activity middleware', () => { + test('removes activity and replaces activity', () => + runHTML('./middleware/shim-v1-v2/activity.remove.replace.html')); +}); diff --git a/__tests__/html/middleware/shim-v1-v2/activity.replace.remove.html b/__tests__/html/middleware/shim-v1-v2/activity.replace.remove.html new file mode 100644 index 0000000000..556c2c1d5c --- /dev/null +++ b/__tests__/html/middleware/shim-v1-v2/activity.replace.remove.html @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/__tests__/html/middleware/shim-v1-v2/activity.replace.remove.js b/__tests__/html/middleware/shim-v1-v2/activity.replace.remove.js new file mode 100644 index 0000000000..cea7bf1d39 --- /dev/null +++ b/__tests__/html/middleware/shim-v1-v2/activity.replace.remove.js @@ -0,0 +1,6 @@ +/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */ + +describe('activity middleware', () => { + test('replaces activity and removes activity', () => + runHTML('./middleware/shim-v1-v2/activity.replace.remove.html')); +}); diff --git a/__tests__/html/middleware/shim-v2-v1/activity.add.decorate.html b/__tests__/html/middleware/shim-v2-v1/activity.add.decorate.html new file mode 100644 index 0000000000..9d083e0adf --- /dev/null +++ b/__tests__/html/middleware/shim-v2-v1/activity.add.decorate.html @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/__tests__/html/middleware/shim-v2-v1/activity.add.decorate.js b/__tests__/html/middleware/shim-v2-v1/activity.add.decorate.js new file mode 100644 index 0000000000..d21e8532aa --- /dev/null +++ b/__tests__/html/middleware/shim-v2-v1/activity.add.decorate.js @@ -0,0 +1,6 @@ +/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */ + +describe('activity middleware', () => { + test('adds a custom activity with decoration', () => + runHTML('./middleware/shim-v2-v1/activity.add.decorate.html')); +}); diff --git a/__tests__/html/middleware/shim-v2-v1/activity.remove.replace.html b/__tests__/html/middleware/shim-v2-v1/activity.remove.replace.html new file mode 100644 index 0000000000..ee81c82ae7 --- /dev/null +++ b/__tests__/html/middleware/shim-v2-v1/activity.remove.replace.html @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/__tests__/html/middleware/shim-v2-v1/activity.remove.replace.js b/__tests__/html/middleware/shim-v2-v1/activity.remove.replace.js new file mode 100644 index 0000000000..0349320ddd --- /dev/null +++ b/__tests__/html/middleware/shim-v2-v1/activity.remove.replace.js @@ -0,0 +1,6 @@ +/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */ + +describe('activity middleware', () => { + test('removes activity and replaces activity', () => + runHTML('./middleware/shim-v2-v1/activity.remove.replace.html')); +}); diff --git a/__tests__/html/middleware/shim-v2-v1/activity.replace.remove.html b/__tests__/html/middleware/shim-v2-v1/activity.replace.remove.html new file mode 100644 index 0000000000..c95896a521 --- /dev/null +++ b/__tests__/html/middleware/shim-v2-v1/activity.replace.remove.html @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/__tests__/html/middleware/shim-v2-v1/activity.replace.remove.js b/__tests__/html/middleware/shim-v2-v1/activity.replace.remove.js new file mode 100644 index 0000000000..cf60737d01 --- /dev/null +++ b/__tests__/html/middleware/shim-v2-v1/activity.replace.remove.js @@ -0,0 +1,6 @@ +/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */ + +describe('activity middleware', () => { + test('replaces activity and removes activity', () => + runHTML('./middleware/shim-v2-v1/activity.replace.remove.html')); +}); diff --git a/__tests__/html/middleware/v1/activity.add.decorate.html b/__tests__/html/middleware/v1/activity.add.decorate.html new file mode 100644 index 0000000000..68a2d5e76f --- /dev/null +++ b/__tests__/html/middleware/v1/activity.add.decorate.html @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/__tests__/html/middleware/v1/activity.add.decorate.js b/__tests__/html/middleware/v1/activity.add.decorate.js new file mode 100644 index 0000000000..74729e1c03 --- /dev/null +++ b/__tests__/html/middleware/v1/activity.add.decorate.js @@ -0,0 +1,5 @@ +/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */ + +describe('activity middleware', () => { + test('adds a custom activity with decoration', () => runHTML('./middleware/v1/activity.add.decorate.html')); +}); diff --git a/__tests__/html/middleware/v1/activity.add.html b/__tests__/html/middleware/v1/activity.add.html new file mode 100644 index 0000000000..444dfd8edf --- /dev/null +++ b/__tests__/html/middleware/v1/activity.add.html @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/__tests__/html/middleware/v1/activity.add.js b/__tests__/html/middleware/v1/activity.add.js new file mode 100644 index 0000000000..abb4b42361 --- /dev/null +++ b/__tests__/html/middleware/v1/activity.add.js @@ -0,0 +1,5 @@ +/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */ + +describe('activity middleware', () => { + test('adds a custom activity', () => runHTML('./middleware/v1/activity.add.html')); +}); diff --git a/__tests__/html/middleware/v1/activity.decorate.html b/__tests__/html/middleware/v1/activity.decorate.html new file mode 100644 index 0000000000..56303cded2 --- /dev/null +++ b/__tests__/html/middleware/v1/activity.decorate.html @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/__tests__/html/middleware/v1/activity.decorate.js b/__tests__/html/middleware/v1/activity.decorate.js new file mode 100644 index 0000000000..e46641c143 --- /dev/null +++ b/__tests__/html/middleware/v1/activity.decorate.js @@ -0,0 +1,5 @@ +/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */ + +describe('activity middleware', () => { + test('decorates an activity by text', () => runHTML('./middleware/v1/activity.decorate.html')); +}); diff --git a/__tests__/html/middleware/v1/activity.remove.html b/__tests__/html/middleware/v1/activity.remove.html new file mode 100644 index 0000000000..c4b7d5eabc --- /dev/null +++ b/__tests__/html/middleware/v1/activity.remove.html @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/__tests__/html/middleware/v1/activity.remove.js b/__tests__/html/middleware/v1/activity.remove.js new file mode 100644 index 0000000000..6f365b7ef9 --- /dev/null +++ b/__tests__/html/middleware/v1/activity.remove.js @@ -0,0 +1,5 @@ +/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */ + +describe('activity middleware', () => { + test('removes an activity by text', () => runHTML('./middleware/v1/activity.remove.html')); +}); diff --git a/__tests__/html/middleware/v1/activity.remove.replace.html b/__tests__/html/middleware/v1/activity.remove.replace.html new file mode 100644 index 0000000000..8685a51dd1 --- /dev/null +++ b/__tests__/html/middleware/v1/activity.remove.replace.html @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/__tests__/html/middleware/v1/activity.remove.replace.js b/__tests__/html/middleware/v1/activity.remove.replace.js new file mode 100644 index 0000000000..e38e292a41 --- /dev/null +++ b/__tests__/html/middleware/v1/activity.remove.replace.js @@ -0,0 +1,5 @@ +/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */ + +describe('activity middleware', () => { + test('removes activity and replaces activity', () => runHTML('./middleware/v1/activity.remove.replace.html')); +}); diff --git a/__tests__/html/middleware/v1/activity.replace.html b/__tests__/html/middleware/v1/activity.replace.html new file mode 100644 index 0000000000..72c600d9c0 --- /dev/null +++ b/__tests__/html/middleware/v1/activity.replace.html @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/__tests__/html/middleware/v1/activity.replace.js b/__tests__/html/middleware/v1/activity.replace.js new file mode 100644 index 0000000000..1a3efce9b0 --- /dev/null +++ b/__tests__/html/middleware/v1/activity.replace.js @@ -0,0 +1,5 @@ +/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */ + +describe('activity middleware', () => { + test('replaces an activity by text', () => runHTML('./middleware/v1/activity.replace.html')); +}); diff --git a/__tests__/html/middleware/v1/activity.replace.remove.html b/__tests__/html/middleware/v1/activity.replace.remove.html new file mode 100644 index 0000000000..64b9d52b24 --- /dev/null +++ b/__tests__/html/middleware/v1/activity.replace.remove.html @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/__tests__/html/middleware/v1/activity.replace.remove.js b/__tests__/html/middleware/v1/activity.replace.remove.js new file mode 100644 index 0000000000..e427c63f21 --- /dev/null +++ b/__tests__/html/middleware/v1/activity.replace.remove.js @@ -0,0 +1,5 @@ +/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */ + +describe('activity middleware', () => { + test('replaces activity and removes activity', () => runHTML('./middleware/v1/activity.replace.remove.html')); +}); diff --git a/__tests__/html/middleware/v1/useCreateActivityRenderer.decorate.html b/__tests__/html/middleware/v1/useCreateActivityRenderer.decorate.html new file mode 100644 index 0000000000..8b5a9f44b5 --- /dev/null +++ b/__tests__/html/middleware/v1/useCreateActivityRenderer.decorate.html @@ -0,0 +1,104 @@ + + + + + + + + + + + + + +
+ + + diff --git a/__tests__/html/middleware/v1/useCreateActivityRenderer.decorate.js b/__tests__/html/middleware/v1/useCreateActivityRenderer.decorate.js new file mode 100644 index 0000000000..eb44aadd44 --- /dev/null +++ b/__tests__/html/middleware/v1/useCreateActivityRenderer.decorate.js @@ -0,0 +1,5 @@ +/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */ + +describe('activity middleware hooks', () => { + test('decorates an activity when used with useCreateActivityRenderer', () => runHTML('./middleware/v1/useCreateActivityRenderer.decorate.html')); +}); diff --git a/__tests__/html/middleware/v1/useRenderAttachment.decorate.html b/__tests__/html/middleware/v1/useRenderAttachment.decorate.html new file mode 100644 index 0000000000..cebb414e82 --- /dev/null +++ b/__tests__/html/middleware/v1/useRenderAttachment.decorate.html @@ -0,0 +1,106 @@ + + + + + + + + + + + + + +
+ + + diff --git a/__tests__/html/middleware/v1/useRenderAttachment.decorate.js b/__tests__/html/middleware/v1/useRenderAttachment.decorate.js new file mode 100644 index 0000000000..b85efbbcd4 --- /dev/null +++ b/__tests__/html/middleware/v1/useRenderAttachment.decorate.js @@ -0,0 +1,5 @@ +/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */ + +describe('activity middleware hooks', () => { + test('decorates an activity when used with useRenderAttachment', () => runHTML('./middleware/v1/useRenderAttachment.decorate.html')); +}); \ No newline at end of file diff --git a/__tests__/html/middleware/v2/activity.add.decorate.html b/__tests__/html/middleware/v2/activity.add.decorate.html new file mode 100644 index 0000000000..be1729af8a --- /dev/null +++ b/__tests__/html/middleware/v2/activity.add.decorate.html @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/__tests__/html/middleware/v2/activity.add.decorate.js b/__tests__/html/middleware/v2/activity.add.decorate.js new file mode 100644 index 0000000000..680476bbb8 --- /dev/null +++ b/__tests__/html/middleware/v2/activity.add.decorate.js @@ -0,0 +1,5 @@ +/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */ + +describe('activity middleware', () => { + test('adds a custom activity with decoration', () => runHTML('./middleware/v2/activity.add.decorate.html')); +}); diff --git a/__tests__/html/middleware/v2/activity.add.html b/__tests__/html/middleware/v2/activity.add.html new file mode 100644 index 0000000000..f5f4bed4da --- /dev/null +++ b/__tests__/html/middleware/v2/activity.add.html @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/__tests__/html/middleware/v2/activity.add.js b/__tests__/html/middleware/v2/activity.add.js new file mode 100644 index 0000000000..81d0090642 --- /dev/null +++ b/__tests__/html/middleware/v2/activity.add.js @@ -0,0 +1,5 @@ +/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */ + +describe('activity middleware', () => { + test('adds a custom activity', () => runHTML('./middleware/v2/activity.add.html')); +}); diff --git a/__tests__/html/middleware/v2/activity.decorate.html b/__tests__/html/middleware/v2/activity.decorate.html new file mode 100644 index 0000000000..df20bb8fc7 --- /dev/null +++ b/__tests__/html/middleware/v2/activity.decorate.html @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/__tests__/html/middleware/v2/activity.decorate.js b/__tests__/html/middleware/v2/activity.decorate.js new file mode 100644 index 0000000000..52861f0946 --- /dev/null +++ b/__tests__/html/middleware/v2/activity.decorate.js @@ -0,0 +1,5 @@ +/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */ + +describe('activity middleware', () => { + test('decorates an activity by text', () => runHTML('./middleware/v2/activity.decorate.html')); +}); diff --git a/__tests__/html/middleware/v2/activity.remove.html b/__tests__/html/middleware/v2/activity.remove.html new file mode 100644 index 0000000000..134c61d3fe --- /dev/null +++ b/__tests__/html/middleware/v2/activity.remove.html @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/__tests__/html/middleware/v2/activity.remove.js b/__tests__/html/middleware/v2/activity.remove.js new file mode 100644 index 0000000000..afdbb0a95a --- /dev/null +++ b/__tests__/html/middleware/v2/activity.remove.js @@ -0,0 +1,5 @@ +/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */ + +describe('activity middleware', () => { + test('removes an activity by text', () => runHTML('./middleware/v2/activity.remove.html')); +}); diff --git a/__tests__/html/middleware/v2/activity.remove.replace.html b/__tests__/html/middleware/v2/activity.remove.replace.html new file mode 100644 index 0000000000..81ccb265b8 --- /dev/null +++ b/__tests__/html/middleware/v2/activity.remove.replace.html @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/__tests__/html/middleware/v2/activity.remove.replace.js b/__tests__/html/middleware/v2/activity.remove.replace.js new file mode 100644 index 0000000000..84b6af87df --- /dev/null +++ b/__tests__/html/middleware/v2/activity.remove.replace.js @@ -0,0 +1,5 @@ +/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */ + +describe('activity middleware', () => { + test('removes activity and replaces activity', () => runHTML('./middleware/v2/activity.remove.replace.html')); +}); diff --git a/__tests__/html/middleware/v2/activity.replace.html b/__tests__/html/middleware/v2/activity.replace.html new file mode 100644 index 0000000000..fc34bfc116 --- /dev/null +++ b/__tests__/html/middleware/v2/activity.replace.html @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/__tests__/html/middleware/v2/activity.replace.js b/__tests__/html/middleware/v2/activity.replace.js new file mode 100644 index 0000000000..190b3d4d51 --- /dev/null +++ b/__tests__/html/middleware/v2/activity.replace.js @@ -0,0 +1,5 @@ +/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */ + +describe('activity middleware', () => { + test('replaces an activity by text', () => runHTML('./middleware/v2/activity.replace.html')); +}); diff --git a/__tests__/html/middleware/v2/activity.replace.remove.html b/__tests__/html/middleware/v2/activity.replace.remove.html new file mode 100644 index 0000000000..0def280739 --- /dev/null +++ b/__tests__/html/middleware/v2/activity.replace.remove.html @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/__tests__/html/middleware/v2/activity.replace.remove.js b/__tests__/html/middleware/v2/activity.replace.remove.js new file mode 100644 index 0000000000..de9df1eb94 --- /dev/null +++ b/__tests__/html/middleware/v2/activity.replace.remove.js @@ -0,0 +1,5 @@ +/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */ + +describe('activity middleware', () => { + test('replaces activity and removes activity', () => runHTML('./middleware/v2/activity.replace.remove.html')); +}); diff --git a/__tests__/html/middleware/v2/activityGrouping.customMiddleware.html b/__tests__/html/middleware/v2/activityGrouping.customMiddleware.html new file mode 100644 index 0000000000..209b3f3e92 --- /dev/null +++ b/__tests__/html/middleware/v2/activityGrouping.customMiddleware.html @@ -0,0 +1,194 @@ + + + + + + + + + + +
+ + + diff --git a/__tests__/html/middleware/v2/activityGrouping.customMiddleware.js b/__tests__/html/middleware/v2/activityGrouping.customMiddleware.js new file mode 100644 index 0000000000..c4b940fa79 --- /dev/null +++ b/__tests__/html/middleware/v2/activityGrouping.customMiddleware.js @@ -0,0 +1,5 @@ +/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */ + +describe('activity grouping', () => { + test('should accept valid or invalid custom middleware', () => runHTML('./middleware/v2/activityGrouping.customMiddleware.html')); +}); diff --git a/__tests__/html/middleware/v2/useCreateActivityRenderer.decorate.html b/__tests__/html/middleware/v2/useCreateActivityRenderer.decorate.html new file mode 100644 index 0000000000..10de734d06 --- /dev/null +++ b/__tests__/html/middleware/v2/useCreateActivityRenderer.decorate.html @@ -0,0 +1,104 @@ + + + + + + + + + + + + + +
+ + + diff --git a/__tests__/html/middleware/v2/useCreateActivityRenderer.decorate.js b/__tests__/html/middleware/v2/useCreateActivityRenderer.decorate.js new file mode 100644 index 0000000000..7364e91156 --- /dev/null +++ b/__tests__/html/middleware/v2/useCreateActivityRenderer.decorate.js @@ -0,0 +1,5 @@ +/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */ + +describe('activity middleware hooks', () => { + test('decorates an activity when used with useCreateActivityRenderer', () => runHTML('./middleware/v2/useCreateActivityRenderer.decorate.html')); +}); diff --git a/__tests__/html/middleware/v2/useRenderAttachment.decorate.html b/__tests__/html/middleware/v2/useRenderAttachment.decorate.html new file mode 100644 index 0000000000..9745651a9f --- /dev/null +++ b/__tests__/html/middleware/v2/useRenderAttachment.decorate.html @@ -0,0 +1,105 @@ + + + + + + + + + + + + + +
+ + + diff --git a/__tests__/html/middleware/v2/useRenderAttachment.decorate.js b/__tests__/html/middleware/v2/useRenderAttachment.decorate.js new file mode 100644 index 0000000000..9c8a4d581b --- /dev/null +++ b/__tests__/html/middleware/v2/useRenderAttachment.decorate.js @@ -0,0 +1,5 @@ +/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */ + +describe('activity middleware hooks', () => { + test('decorates an activity when used with useRenderAttachment', () => runHTML('./middleware/v2/useRenderAttachment.decorate.html')); +}); diff --git a/packages/api/package-lock.json b/packages/api/package-lock.json index fd72611e40..10442004ab 100644 --- a/packages/api/package-lock.json +++ b/packages/api/package-lock.json @@ -12,6 +12,7 @@ "globalize": "1.7.0", "math-random": "2.0.1", "prop-types": "15.8.1", + "react-chain-of-responsibility": "0.1.0", "react-redux": "7.2.9", "redux": "5.0.0", "simple-update-in": "2.2.0" @@ -1809,6 +1810,18 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/runtime-corejs3": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.24.1.tgz", + "integrity": "sha512-T9ko/35G+Bkl+win48GduaPlhSlOjjE5s1TeiEcD+QpxlLQnoEfb/nO/T+TQqkm+ipFwORn+rB8w14iJ/uD0bg==", + "dependencies": { + "core-js-pure": "^3.30.2", + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.22.15", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", @@ -2465,6 +2478,16 @@ "url": "https://opencollective.com/core-js" } }, + "node_modules/core-js-pure": { + "version": "3.36.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.36.1.tgz", + "integrity": "sha512-NXCvHvSVYSrewP0L5OhltzXeWFJLo2AL2TYnj6iLV3Bw8mM62wAQMNgUCRI6EBu6hVVpbCxmOPlxh1Ikw2PfUA==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, "node_modules/csstype": { "version": "3.0.11", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.11.tgz", @@ -3480,6 +3503,19 @@ "react-is": "^16.13.1" } }, + "node_modules/react-chain-of-responsibility": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/react-chain-of-responsibility/-/react-chain-of-responsibility-0.1.0.tgz", + "integrity": "sha512-bNBPtXPOiOOjV8EqVouFRP3Ip0arQtROO8uvoJaOe9CrLp5ehu/zEDq2vxTh9imopPmB7CG/M4ecMbfhYI18XA==", + "dependencies": { + "@babel/runtime-corejs3": "^7.24.1", + "prop-types": "^15.8.1", + "react-chain-of-responsibility": "^0.1.0" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -5245,6 +5281,15 @@ "regenerator-runtime": "^0.14.0" } }, + "@babel/runtime-corejs3": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.24.1.tgz", + "integrity": "sha512-T9ko/35G+Bkl+win48GduaPlhSlOjjE5s1TeiEcD+QpxlLQnoEfb/nO/T+TQqkm+ipFwORn+rB8w14iJ/uD0bg==", + "requires": { + "core-js-pure": "^3.30.2", + "regenerator-runtime": "^0.14.0" + } + }, "@babel/template": { "version": "7.22.15", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", @@ -5763,6 +5808,11 @@ "browserslist": "^4.21.4" } }, + "core-js-pure": { + "version": "3.36.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.36.1.tgz", + "integrity": "sha512-NXCvHvSVYSrewP0L5OhltzXeWFJLo2AL2TYnj6iLV3Bw8mM62wAQMNgUCRI6EBu6hVVpbCxmOPlxh1Ikw2PfUA==" + }, "csstype": { "version": "3.0.11", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.11.tgz", @@ -6519,6 +6569,16 @@ "react-is": "^16.13.1" } }, + "react-chain-of-responsibility": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/react-chain-of-responsibility/-/react-chain-of-responsibility-0.1.0.tgz", + "integrity": "sha512-bNBPtXPOiOOjV8EqVouFRP3Ip0arQtROO8uvoJaOe9CrLp5ehu/zEDq2vxTh9imopPmB7CG/M4ecMbfhYI18XA==", + "requires": { + "@babel/runtime-corejs3": "^7.24.1", + "prop-types": "^15.8.1", + "react-chain-of-responsibility": "^0.1.0" + } + }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", diff --git a/packages/api/package.json b/packages/api/package.json index dc09f1768a..4c904ba835 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -70,6 +70,7 @@ "math-random": "2.0.1", "prop-types": "15.8.1", "react-redux": "7.2.9", + "react-chain-of-responsibility": "0.1.0", "redux": "5.0.0", "simple-update-in": "2.2.0" }, diff --git a/packages/api/src/hooks/Composer.tsx b/packages/api/src/hooks/Composer.tsx index c9be1ed4f3..7e1cc94a59 100644 --- a/packages/api/src/hooks/Composer.tsx +++ b/packages/api/src/hooks/Composer.tsx @@ -66,6 +66,7 @@ import TypingIndicatorMiddleware from '../types/TypingIndicatorMiddleware'; import useMarkAllAsAcknowledged from './useMarkAllAsAcknowledged'; import usePonyfill from '../hooks/usePonyfill'; import WebChatReduxContext, { useDispatch } from './internal/WebChatReduxContext'; +import { isV2Middleware } from '../utils/v2Middleware'; import applyMiddleware, { forLegacyRenderer as applyMiddlewareForLegacyRenderer, @@ -85,6 +86,7 @@ import type { WebChatActivity } from 'botframework-webchat-core'; import type { ReactNode } from 'react'; +import { ActivityMiddlewareProvider } from '../providers/ActivityMiddleware/ActivityMiddleware'; // List of Redux actions factory we are hoisting as Web Chat functions const DISPATCHERS = { @@ -378,30 +380,34 @@ const ComposerCore = ({ [telemetryDimensionsRef] ); + const isUsingActivityMiddlewareV2 = useMemo( + () => singleToArray(activityMiddleware).some(md => isV2Middleware(md)), + [activityMiddleware] + ); + const patchedActivityRenderer = useMemo(() => { activityRenderer && console.warn( 'Web Chat: "activityRenderer" is deprecated and will be removed on 2022-06-15, please use "activityMiddleware" instead.' ); - return ( - activityRenderer || - applyMiddlewareForRenderer( - 'activity', - { strict: false }, - ...singleToArray(activityMiddleware), - () => + return activityRenderer || isUsingActivityMiddlewareV2 + ? undefined + : applyMiddlewareForRenderer( + 'activity', + { strict: false }, + ...singleToArray(activityMiddleware), () => - ({ activity }) => { - if (activity) { - throw new Error(`No renderer for activity of type "${activity.type}"`); - } else { - throw new Error('No activity to render'); + () => + ({ activity }) => { + if (activity) { + throw new Error(`No renderer for activity of type "${activity.type}"`); + } else { + throw new Error('No activity to render'); + } } - } - )({}) - ); - }, [activityMiddleware, activityRenderer]); + )({}); + }, [activityMiddleware, activityRenderer, isUsingActivityMiddlewareV2]); const patchedActivityStatusRenderer = useMemo(() => { activityStatusRenderer && @@ -581,7 +587,8 @@ const ComposerCore = ({ trackDimension, typingIndicatorRenderer: patchedTypingIndicatorRenderer, userID, - username + username, + isUsingActivityMiddlewareV2 }), [ cardActionContext, @@ -609,20 +616,22 @@ const ComposerCore = ({ renderMarkdown, scrollToEndButtonRenderer, sendTypingIndicator, - telemetryDimensionsRef, trackDimension, userID, - username + username, + isUsingActivityMiddlewareV2 ] ); return ( - - {typeof children === 'function' ? children(context) : children} - - - {onTelemetry && } + + + {typeof children === 'function' ? children(context) : children} + + + {onTelemetry && } + ); }; diff --git a/packages/api/src/hooks/internal/WebChatAPIContext.ts b/packages/api/src/hooks/internal/WebChatAPIContext.ts index e62fd162bb..f9f68e091d 100644 --- a/packages/api/src/hooks/internal/WebChatAPIContext.ts +++ b/packages/api/src/hooks/internal/WebChatAPIContext.ts @@ -69,6 +69,7 @@ type WebChatAPIContext = { typingIndicatorRenderer?: any; // TODO userID?: string; username?: string; + isUsingActivityMiddlewareV2: boolean; }; const context = createContext(undefined); diff --git a/packages/api/src/hooks/useCreateActivityRenderer.ts b/packages/api/src/hooks/useCreateActivityRenderer.ts index 55fb552223..831a69e179 100644 --- a/packages/api/src/hooks/useCreateActivityRenderer.ts +++ b/packages/api/src/hooks/useCreateActivityRenderer.ts @@ -1,8 +1,18 @@ -import { ActivityComponentFactory } from '../types/ActivityMiddleware'; +import { type ActivityComponentFactory } from '../types/ActivityMiddleware'; import useCreateActivityRendererInternal from './internal/useCreateActivityRendererInternal'; +import useWebChatAPIContext from './internal/useWebChatAPIContext'; +import { useCreateActivityRendererV2 } from '../providers/ActivityMiddleware/ActivityMiddleware'; // The newer useCreateActivityRenderer() hook does not support override renderAttachment(). // Only the deprecated useRenderActivity() hook support overriding renderAttachment(). export default function useCreateActivityRenderer(): ActivityComponentFactory { - return useCreateActivityRendererInternal(); + const useActivityRendererV1 = useCreateActivityRendererInternal(); + const useActivityRendererV2 = useCreateActivityRendererV2(); + const { isUsingActivityMiddlewareV2 } = useWebChatAPIContext(); + + if (isUsingActivityMiddlewareV2) { + return useActivityRendererV2; + } + + return useActivityRendererV1; } diff --git a/packages/api/src/index.ts b/packages/api/src/index.ts index d1c5aebdf1..62aced1d2d 100644 --- a/packages/api/src/index.ts +++ b/packages/api/src/index.ts @@ -19,9 +19,10 @@ import TypingIndicatorMiddleware, { RenderTypingIndicator } from './types/Typing import WebSpeechPonyfill from './types/WebSpeechPonyfill'; import WebSpeechPonyfillFactory from './types/WebSpeechPonyfillFactory'; -import type { ActivityStatusMiddleware, RenderActivityStatus } from './types/ActivityStatusMiddleware'; +import { type ActivityStatusMiddleware, type RenderActivityStatus } from './types/ActivityStatusMiddleware'; +import { v2Middleware } from './utils/v2Middleware'; -export { Composer, concatMiddleware, defaultStyleOptions, hooks, localize, normalizeStyleOptions }; +export { Composer, concatMiddleware, defaultStyleOptions, hooks, localize, normalizeStyleOptions, v2Middleware }; export type { ActivityComponentFactory, diff --git a/packages/api/src/providers/ActivityMiddleware/ActivityMiddleware.tsx b/packages/api/src/providers/ActivityMiddleware/ActivityMiddleware.tsx new file mode 100644 index 0000000000..0ac6b8410d --- /dev/null +++ b/packages/api/src/providers/ActivityMiddleware/ActivityMiddleware.tsx @@ -0,0 +1,65 @@ +import React, { ReactNode, useMemo } from 'react'; +import PropTypes from 'prop-types'; +import { OneOrMany, singleToArray } from 'botframework-webchat-core'; +// TODO: fix the import location +import { createChainOfResponsibility } from 'react-chain-of-responsibility'; +import ActivityMiddleware, { + ActivityComponentFactory, + ActivityComponentFactoryOptions, + ActivityProps +} from '../../types/ActivityMiddleware'; +import { applyV2MiddlewareShim, middlewareTypeShim } from '../../utils/v2Middleware'; +import useWebChatAPIContext from '../../hooks/internal/useWebChatAPIContext'; + +const { Provider: ActivityMiddlewareProviderInner, useBuildComponentCallback } = createChainOfResponsibility< + ActivityComponentFactoryOptions, + ActivityProps & ActivityComponentFactoryOptions +>(); + +type ActivityMiddlewareProviderProps = Readonly<{ + middleware: OneOrMany; + children?: ReactNode | undefined; +}>; + +const ActivityMiddlewareProvider = ({ middleware, children }: ActivityMiddlewareProviderProps): ReactNode => { + const { isUsingActivityMiddlewareV2 } = useWebChatAPIContext(); + return ( + + {children} + + ); +}; + +ActivityMiddlewareProvider.displayName = 'ActivityMiddlewareProvider'; + +ActivityMiddlewareProvider.defaultProps = { + children: undefined, + middleware: undefined +}; + +ActivityMiddlewareProvider.propTypes = { + children: PropTypes.any, + middleware: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.func), PropTypes.func]) +}; + +function useCreateActivityRendererV2(): ActivityComponentFactory { + const enhancer = useBuildComponentCallback(); + return useMemo( + () => createActivityRendererOptions => { + const Component = enhancer(createActivityRendererOptions); + + if (!Component) { + return false; + } + + return props => ; + }, + [enhancer] + ); +} + +export { ActivityMiddlewareProvider, useCreateActivityRendererV2 }; diff --git a/packages/api/src/types/ActivityMiddleware.ts b/packages/api/src/types/ActivityMiddleware.ts index 341ca3285a..e673b4d324 100644 --- a/packages/api/src/types/ActivityMiddleware.ts +++ b/packages/api/src/types/ActivityMiddleware.ts @@ -33,4 +33,4 @@ type ActivityMiddleware = () => ActivityEnhancer; export default ActivityMiddleware; -export type { ActivityComponentFactory, LegacyActivityRenderer }; +export type { ActivityProps, ActivityComponentFactoryOptions, ActivityComponentFactory, LegacyActivityRenderer }; diff --git a/packages/api/src/utils/v2Middleware.tsx b/packages/api/src/utils/v2Middleware.tsx new file mode 100644 index 0000000000..54ff8f77a9 --- /dev/null +++ b/packages/api/src/utils/v2Middleware.tsx @@ -0,0 +1,60 @@ +import * as React from 'react'; +import useRenderAttachment from '../hooks/useRenderAttachment'; + +const v2MiddlewareSymbol = Symbol('WebChat-v2-middleware'); + +export function isV2Middleware(fn: any) { + return fn instanceof Function && v2MiddlewareSymbol in fn; +} + +export function v2Middleware any>(fn: F): F { + return Object.assign(fn, { [v2MiddlewareSymbol]: true }); +} + +// TODO: improve types in code bellow + +function v2MiddlewareShim(v1Middleware, middlewareTypeHandler) { + return (...init: S) => { + const enhancer = v1Middleware(...init); + return next => { + // handle calling next from v1 in v2 + const nextShim = (props, ...args) => { + if (args.length) { + throw new Error('Additional arguments in next() are not supported when using v2 middlewares'); + } + const Next = next(props); + if (!Next) { + return false; + } + return middlewareTypeHandler.v1(Next); + }; + const fn = enhancer(nextShim); + return props => { + const result = fn(props); + if (!result) { + return false; + } + return middlewareTypeHandler.v2(result); + }; + }; + }; +} + +export const middlewareTypeShim = { + activity: { + v2: result => + function ActivityRendererShim(props) { + // renderAttachmentOverride is not supported anymore + const renderAttachment = useRenderAttachment(); + return result instanceof Function ? result(renderAttachment, props) : result; + }, + v1: Next => + function renderActivity(legacyRenderAttachment, props) { + return ; + } + } +} as const; + +export function applyV2MiddlewareShim(middlewaress, shimType) { + return middlewaress.map(md => (isV2Middleware(md) ? md : v2MiddlewareShim(md, shimType))); +} diff --git a/packages/bundle/src/index-minimal.ts b/packages/bundle/src/index-minimal.ts index f206c11bef..5cab7bf303 100644 --- a/packages/bundle/src/index-minimal.ts +++ b/packages/bundle/src/index-minimal.ts @@ -8,7 +8,7 @@ import { createStoreWithOptions, version } from 'botframework-webchat-core'; -import { StrictStyleOptions, StyleOptions } from 'botframework-webchat-api'; +import { StrictStyleOptions, StyleOptions, v2Middleware } from 'botframework-webchat-api'; import ReactWebChat, { Components, @@ -60,7 +60,8 @@ export { hooks, renderWebChat, version, - withEmoji + withEmoji, + v2Middleware }; export type { StyleOptions, StrictStyleOptions }; @@ -80,7 +81,8 @@ window['WebChat'] = { hooks, ReactWebChat, renderWebChat, - withEmoji + withEmoji, + v2Middleware }; addVersion('minimal');