From d642b89631c92ce0a126eb02de42fae38098bc91 Mon Sep 17 00:00:00 2001 From: William Wong Date: Wed, 10 Jan 2024 11:10:37 -0800 Subject: [PATCH] Add PR validation pipeline to GitHub Actions (#4976) * Add PR validation * Add needs * Compress less files * Fix pipe * Remove cache * Add babel-jest * Add babel.config.json * Add deps * Fix syntax * Fix run jest * Fix Docker * Add Dockerfile * Add serve-test.json * Add sharding * Update matrix name * Add unit tests * Add names * Scale chrome=2 * Use Jest 28 * Fix --testPathPattern * Use babel-jest@28 * Run jest@28 in unit tests * Skip nightly tests * Fix run Jest * Run npm ci * Run npm ci under packages/test/harness/ * Remove jest-version * 20 shards * Add test results * Add needs * Fix docker-compose down * Use a different continue-on-error pattern * Disable fail-fast * Add GitHub Actions reporter * Down to 10 * Add timeout minutes * Add timeout minutes to unit tests * Remove chrome.dockerfile * Use 20 shards * Use 19 shards * Change downloads folder * Run precommit * Rename lint to static code analysis * Use 18 shards * Build during SCA * 20 shards * Upload cobertura-coverage.xml * Merge and print coverage * Add branch coverage * Add lcov and NODE_ENV * Fix lcov file extension * Print Docker logs * Disable coverage * Wait until WebDriver hub is ready * Simplify * Disable pipefail * Enable instrumentation * Fix unit test coverage * Disable Gcovr * Install lcov * Add branch coverage * Better print coverage * Remove Cobertura * Remove pipefail * Upload failing snapshots * Typo * Packing bundle/core src * Add types to unit test * Move types test to packages * Use Node 18 * Clean up and enable secure feed * Better coverage merging * Add tracefile individually * Add mutable performance * Use Node.js 18.18 * Fix flaky * Add comments * Fix flaky * Add entry * Enable Terrapin before setting up Node to improve cache --- .github/workflows/pull-request-validation.yml | 310 ++++++++++++++++++ CHANGELOG.md | 4 + .../html/updateActivity.sameActivityId.html | 3 + .../updateActivity.undefinedActivityId.html | 5 +- .../pass/additional-style-options-in-full.ts | 3 - .../__typescript__/pass/correct-type-dir.tsx | 3 - .../pass/import-component-send-text-box.tsx | 5 - .../pass/import-create-direct-line.tsx | 3 - chrome.dockerfile | 7 - docker-compose-wsl2.yml | 6 +- jest.config.js | 9 +- .../create-direct-line-invalid-bot-agent.tsx | 2 +- .../create-direct-line-invalid-option.tsx | 2 +- .../fail-once/invalid-prop-type-dir.tsx | 4 +- ...ions-suggested-actions-stacked-overflow.ts | 2 +- .../invalid-type-for-use-style-options.tsx | 2 +- ...children-for-react-web-chat-in-minimal.tsx | 8 + .../no-children-for-react-web-chat.tmp.tsx | 4 +- .../no-children-for-react-web-chat.tsx | 4 +- ...ndle-style-options-in-minimal-for-hooks.ts | 2 +- ...no-full-bundle-style-options-in-minimal.ts | 2 +- .../pass/additional-style-options-in-full.ts | 3 + .../pass/composition-with-store.tsx | 3 +- .../__typescript__/pass/correct-type-dir.tsx | 5 + .../pass/import-component-send-text-box.tsx | 7 + .../pass/import-create-direct-line.tsx | 3 + .../pass/render-with-minimal-bundle.tsx | 3 +- .../__typescript__/pass/render-with-store.tsx | 3 +- .../pass/render-with-style-options.tsx | 3 +- .../pass/render-with-style-set.tsx | 3 +- .../types/__typescript__/pass/render.tsx | 3 +- .../use-style-options-with-full-bundle.ts | 2 +- ...ions-suggested-actions-stacked-overflow.ts | 2 +- .../bundle/__tests__}/types/tsconfig.json | 0 .../bundle/__tests__}/types/typescript.js | 0 .../pass/direct-line-activity-from-bot.ts | 2 +- ...ect-line-activity-from-user-send-failed.ts | 2 +- .../direct-line-activity-from-user-sending.ts | 2 +- .../direct-line-activity-from-user-sent.ts | 2 +- packages/core/__tests__/types/tsconfig.json | 5 + packages/core/__tests__/types/typescript.js | 96 ++++++ 41 files changed, 492 insertions(+), 47 deletions(-) create mode 100644 .github/workflows/pull-request-validation.yml delete mode 100644 __tests__/types/__typescript__/pass/additional-style-options-in-full.ts delete mode 100644 __tests__/types/__typescript__/pass/correct-type-dir.tsx delete mode 100644 __tests__/types/__typescript__/pass/import-component-send-text-box.tsx delete mode 100644 __tests__/types/__typescript__/pass/import-create-direct-line.tsx delete mode 100644 chrome.dockerfile rename {__tests__ => packages/bundle/__tests__}/types/__typescript__/fail-once/create-direct-line-invalid-bot-agent.tsx (54%) rename {__tests__ => packages/bundle/__tests__}/types/__typescript__/fail-once/create-direct-line-invalid-option.tsx (72%) rename {__tests__ => packages/bundle/__tests__}/types/__typescript__/fail-once/invalid-prop-type-dir.tsx (57%) rename {__tests__ => packages/bundle/__tests__}/types/__typescript__/fail-once/invalid-style-options-suggested-actions-stacked-overflow.ts (57%) rename {__tests__ => packages/bundle/__tests__}/types/__typescript__/fail-once/invalid-type-for-use-style-options.tsx (64%) create mode 100644 packages/bundle/__tests__/types/__typescript__/fail-once/no-children-for-react-web-chat-in-minimal.tsx rename __tests__/types/__typescript__/fail-once/no-children-for-react-web-chat-in-minimal.tsx => packages/bundle/__tests__/types/__typescript__/fail-once/no-children-for-react-web-chat.tmp.tsx (63%) rename {__tests__ => packages/bundle/__tests__}/types/__typescript__/fail-once/no-children-for-react-web-chat.tsx (63%) rename {__tests__ => packages/bundle/__tests__}/types/__typescript__/fail-once/no-full-bundle-style-options-in-minimal-for-hooks.ts (58%) rename {__tests__ => packages/bundle/__tests__}/types/__typescript__/fail-once/no-full-bundle-style-options-in-minimal.ts (64%) create mode 100644 packages/bundle/__tests__/types/__typescript__/pass/additional-style-options-in-full.ts rename {__tests__ => packages/bundle/__tests__}/types/__typescript__/pass/composition-with-store.tsx (73%) create mode 100644 packages/bundle/__tests__/types/__typescript__/pass/correct-type-dir.tsx create mode 100644 packages/bundle/__tests__/types/__typescript__/pass/import-component-send-text-box.tsx create mode 100644 packages/bundle/__tests__/types/__typescript__/pass/import-create-direct-line.tsx rename {__tests__ => packages/bundle/__tests__}/types/__typescript__/pass/render-with-minimal-bundle.tsx (70%) rename {__tests__ => packages/bundle/__tests__}/types/__typescript__/pass/render-with-store.tsx (68%) rename {__tests__ => packages/bundle/__tests__}/types/__typescript__/pass/render-with-style-options.tsx (74%) rename {__tests__ => packages/bundle/__tests__}/types/__typescript__/pass/render-with-style-set.tsx (87%) rename {__tests__ => packages/bundle/__tests__}/types/__typescript__/pass/render.tsx (64%) rename {__tests__ => packages/bundle/__tests__}/types/__typescript__/pass/use-style-options-with-full-bundle.ts (65%) rename {__tests__ => packages/bundle/__tests__}/types/__typescript__/pass/valid-style-options-suggested-actions-stacked-overflow.ts (81%) rename {__tests__ => packages/bundle/__tests__}/types/tsconfig.json (100%) rename {__tests__ => packages/bundle/__tests__}/types/typescript.js (100%) rename {__tests__ => packages/core/__tests__}/types/__typescript__/pass/direct-line-activity-from-bot.ts (85%) rename {__tests__ => packages/core/__tests__}/types/__typescript__/pass/direct-line-activity-from-user-send-failed.ts (86%) rename {__tests__ => packages/core/__tests__}/types/__typescript__/pass/direct-line-activity-from-user-sending.ts (86%) rename {__tests__ => packages/core/__tests__}/types/__typescript__/pass/direct-line-activity-from-user-sent.ts (86%) create mode 100644 packages/core/__tests__/types/tsconfig.json create mode 100644 packages/core/__tests__/types/typescript.js diff --git a/.github/workflows/pull-request-validation.yml b/.github/workflows/pull-request-validation.yml new file mode 100644 index 0000000000..0214611b28 --- /dev/null +++ b/.github/workflows/pull-request-validation.yml @@ -0,0 +1,310 @@ +name: Pull request validation + +on: + pull_request: + branches: + - main + + paths-ignore: + - .github + - .vscode + + push: + branches: + - feat-github-workflow # Keeping the branch here so we can try out something later quickly + + workflow_dispatch: {} + +defaults: + run: + shell: bash + +env: + CI_PULL_REQUEST: 1 # Skip nightly tests + NODE_ENV: test # Add instrumentation code + node-version: 18.18 # Need to bump jest@29 to resolve something in https://github.com/facebook/react-native/issues/35701 + skip-secure-feed: false + +jobs: + build: + name: Build + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - if: "env.skip-secure-feed != 'true'" + name: Enable secure feed + run: npx https://aka.ms/EnableSecureFeed + + - name: Use Node.js ${{ env.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ env.node-version }} + cache: npm + + - run: npm clean-install + + - run: npm run bootstrap + + - run: npm run build --if-present + + - name: Pack Docker artifact + run: | + zip docker.zip -r@ < /tmp/wd-status.json + + [[ $? -eq 0 ]] && cat /tmp/wd-status.json | jq -r 'if (.value.ready != true) then halt_error(1) else empty end' + [[ $? -eq 0 ]] && break + + sleep 1 + done + + - name: Run jest --shard=${{ format('{0}/{1}', matrix.shard-index, matrix.shard-count) }} + run: | + ./node_modules/.bin/jest \ + --ci \ + --coverage true \ + --forceExit \ + --logHeapUsage \ + --runInBand \ + --shard=${{ format('{0}/{1}', matrix.shard-index, matrix.shard-count) }} + timeout-minutes: 10 + + - if: always() + name: Print Docker logs + run: docker-compose -f docker-compose-wsl2.yml logs + + - if: always() + name: Append ID to test result + run: | + ls -laR . + + mv jest.json jest-${{ matrix.shard-index }}.json + mv lcov.info lcov-${{ matrix.shard-index }}.info + mv nunit3.xml nunit3-${{ matrix.shard-index }}.xml + mv result.trx result-${{ matrix.shard-index }}.trx + working-directory: ./coverage + + - if: always() + name: Upload test results + uses: actions/upload-artifact@v3 + with: + name: test-result + path: | + ./coverage/jest-*.json + ./coverage/lcov-*.info + ./coverage/nunit3-*.xml + ./coverage/result-*.trx + + - if: failure() + name: Upload test snapshot diffs + uses: actions/upload-artifact@v3 + with: + name: test-snapshot-diff + path: ./__tests__/__image_snapshots__/*/__diff_output__/* + + merge-test-result: + if: always() + name: Merge test result + needs: + - html-test + - unit-test + runs-on: ubuntu-latest + + steps: + - name: Download test results + uses: actions/download-artifact@v3 + with: + name: test-result + + - name: Install lcov + run: sudo apt install -y lcov + + - name: Merge lcov-*.info + run: | + lcov \ + --rc lcov_branch_coverage=1 \ + --add-tracefile lcov-1.info \ + --add-tracefile lcov-2.info \ + --add-tracefile lcov-3.info \ + --add-tracefile lcov-4.info \ + --add-tracefile lcov-5.info \ + --add-tracefile lcov-6.info \ + --add-tracefile lcov-7.info \ + --add-tracefile lcov-8.info \ + --add-tracefile lcov-9.info \ + --add-tracefile lcov-10.info \ + --add-tracefile lcov-11.info \ + --add-tracefile lcov-12.info \ + --add-tracefile lcov-13.info \ + --add-tracefile lcov-14.info \ + --add-tracefile lcov-15.info \ + --add-tracefile lcov-16.info \ + --add-tracefile lcov-17.info \ + --add-tracefile lcov-18.info \ + --add-tracefile lcov-19.info \ + --add-tracefile lcov-20.info \ + --add-tracefile lcov-unit.info \ + --output-file lcov.info + + - if: always() + name: Print coverage list + run: lcov --rc lcov_branch_coverage=1 --list lcov.info + + - if: always() + name: Print coverage summary + run: | + echo \`\`\` >> $GITHUB_STEP_SUMMARY + lcov --rc lcov_branch_coverage=1 --summary lcov.info | tee --append $GITHUB_STEP_SUMMARY + echo \`\`\` >> $GITHUB_STEP_SUMMARY diff --git a/CHANGELOG.md b/CHANGELOG.md index 244b8693bd..f3848be3ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +### Changed + +- Moved pull request validation pipeline to GitHub Actions, by [@compulim](https://github.com/compulim), in PR [#4976](https://github.com/microsoft/BotFramework-WebChat/pull/4976) + ## [4.16.0] - 2023-11-16 ### Breaking changes diff --git a/__tests__/html/updateActivity.sameActivityId.html b/__tests__/html/updateActivity.sameActivityId.html index fbb282f993..e1c0470657 100644 --- a/__tests__/html/updateActivity.sameActivityId.html +++ b/__tests__/html/updateActivity.sameActivityId.html @@ -68,6 +68,9 @@ // WHEN: All images (in the carousel) are loaded. await pageConditions.allImagesLoaded(); + // WHEN: Scroll to bottom completed. + await pageConditions.scrollToBottomCompleted(); + // THEN: It should show 3 messages: 2 outgoing messages and 1 incoming message (carousel). await host.snapshot(); }); diff --git a/__tests__/html/updateActivity.undefinedActivityId.html b/__tests__/html/updateActivity.undefinedActivityId.html index 59d9c18042..c92a8dc5c1 100644 --- a/__tests__/html/updateActivity.undefinedActivityId.html +++ b/__tests__/html/updateActivity.undefinedActivityId.html @@ -1,4 +1,4 @@ - + @@ -61,6 +61,9 @@ // WHEN: All images are loaded. await pageConditions.allImagesLoaded(); + // WHEN: Scroll to bottom completed. + await pageConditions.scrollToBottomCompleted(); + // THEN: It should show 5 messages in total. await host.snapshot(); }); diff --git a/__tests__/types/__typescript__/pass/additional-style-options-in-full.ts b/__tests__/types/__typescript__/pass/additional-style-options-in-full.ts deleted file mode 100644 index 2547b57b02..0000000000 --- a/__tests__/types/__typescript__/pass/additional-style-options-in-full.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { createStyleSet } from '../../../../packages/bundle'; - -createStyleSet({ cardEmphasisBackgroundColor: 'orange' }); diff --git a/__tests__/types/__typescript__/pass/correct-type-dir.tsx b/__tests__/types/__typescript__/pass/correct-type-dir.tsx deleted file mode 100644 index b3800be14d..0000000000 --- a/__tests__/types/__typescript__/pass/correct-type-dir.tsx +++ /dev/null @@ -1,3 +0,0 @@ -import ReactWebChat from '../../../../packages/bundle'; - -; diff --git a/__tests__/types/__typescript__/pass/import-component-send-text-box.tsx b/__tests__/types/__typescript__/pass/import-component-send-text-box.tsx deleted file mode 100644 index e25efe31aa..0000000000 --- a/__tests__/types/__typescript__/pass/import-component-send-text-box.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { Components } from '../../../../packages/bundle'; - -const { SendTextBox } = Components; - -; diff --git a/__tests__/types/__typescript__/pass/import-create-direct-line.tsx b/__tests__/types/__typescript__/pass/import-create-direct-line.tsx deleted file mode 100644 index f2ca1ffd23..0000000000 --- a/__tests__/types/__typescript__/pass/import-create-direct-line.tsx +++ /dev/null @@ -1,3 +0,0 @@ -import { createDirectLine } from '../../../../packages/bundle'; - -createDirectLine({ token: 'faketoken' }); diff --git a/chrome.dockerfile b/chrome.dockerfile deleted file mode 100644 index 60b685cc01..0000000000 --- a/chrome.dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -# https://github.com/SeleniumHQ/docker-selenium -# https://hub.docker.com/r/selenium/standalone-chrome/tags/ - -FROM selenium/node-chrome:110.0 - -ADD __tests__/html/assets/uploads /home/seluser/Downloads -ADD __tests__/setup/local /home/seluser/Downloads diff --git a/docker-compose-wsl2.yml b/docker-compose-wsl2.yml index 3e55b37bca..ec7b236f10 100644 --- a/docker-compose-wsl2.yml +++ b/docker-compose-wsl2.yml @@ -4,9 +4,7 @@ services: # On Windows, run with COMPOSE_CONVERT_WINDOWS_PATHS=1 chrome: - build: - context: ./ - dockerfile: chrome.dockerfile + image: selenium/node-chrome:110.0 depends_on: - selenium-hub - webchat @@ -18,6 +16,8 @@ services: SE_OPTS: '--log-level WARNING' SE_NODE_SESSION_TIMEOUT: '300' shm_size: '2.5gb' + volumes: + - ./__tests__/setup/local/:/home/seluser/Downloads selenium-hub: image: selenium/hub:4.8.1 diff --git a/jest.config.js b/jest.config.js index f0bed07004..7441abd785 100644 --- a/jest.config.js +++ b/jest.config.js @@ -75,6 +75,12 @@ module.exports = { filename: join(__dirname, 'coverage/nunit3.xml'), jestResultFilename: join(__dirname, 'coverage/jest.json') } + ], + [ + 'github-actions', + { + silent: false + } ] ], setupFilesAfterEnv: [ @@ -93,7 +99,8 @@ module.exports = { '/__tests__/html/__jest__', '/__tests__/html/assets', '/__tests__/setup/', - '/__tests__/types/__typescript__', + '/packages/bundle/__tests__/types/__typescript__/', + '/packages/core/__tests__/types/__typescript__/', '/packages/directlinespeech/__tests__/utilities/', '/packages/playground/', '/samples/' diff --git a/__tests__/types/__typescript__/fail-once/create-direct-line-invalid-bot-agent.tsx b/packages/bundle/__tests__/types/__typescript__/fail-once/create-direct-line-invalid-bot-agent.tsx similarity index 54% rename from __tests__/types/__typescript__/fail-once/create-direct-line-invalid-bot-agent.tsx rename to packages/bundle/__tests__/types/__typescript__/fail-once/create-direct-line-invalid-bot-agent.tsx index 19edbd1c0e..1d19cac582 100644 --- a/__tests__/types/__typescript__/fail-once/create-direct-line-invalid-bot-agent.tsx +++ b/packages/bundle/__tests__/types/__typescript__/fail-once/create-direct-line-invalid-bot-agent.tsx @@ -1,4 +1,4 @@ -import { createDirectLine } from '../../../../packages/bundle'; +import { createDirectLine } from '../../../../lib/index'; // "botAgent" is a forbidden option. createDirectLine({ botAgent: '123' }); diff --git a/__tests__/types/__typescript__/fail-once/create-direct-line-invalid-option.tsx b/packages/bundle/__tests__/types/__typescript__/fail-once/create-direct-line-invalid-option.tsx similarity index 72% rename from __tests__/types/__typescript__/fail-once/create-direct-line-invalid-option.tsx rename to packages/bundle/__tests__/types/__typescript__/fail-once/create-direct-line-invalid-option.tsx index 1a39038f8c..c4b6fa5ad1 100644 --- a/__tests__/types/__typescript__/fail-once/create-direct-line-invalid-option.tsx +++ b/packages/bundle/__tests__/types/__typescript__/fail-once/create-direct-line-invalid-option.tsx @@ -1,4 +1,4 @@ -import { createDirectLine } from '../../../../packages/bundle'; +import { createDirectLine } from '../../../../lib/index'; // Object literal may only specify known properties, and 'invalid' does not exist in type 'Omit'. createDirectLine({ invalid: true }); diff --git a/__tests__/types/__typescript__/fail-once/invalid-prop-type-dir.tsx b/packages/bundle/__tests__/types/__typescript__/fail-once/invalid-prop-type-dir.tsx similarity index 57% rename from __tests__/types/__typescript__/fail-once/invalid-prop-type-dir.tsx rename to packages/bundle/__tests__/types/__typescript__/fail-once/invalid-prop-type-dir.tsx index 8deb2e082f..9e79e58125 100644 --- a/__tests__/types/__typescript__/fail-once/invalid-prop-type-dir.tsx +++ b/packages/bundle/__tests__/types/__typescript__/fail-once/invalid-prop-type-dir.tsx @@ -1,4 +1,6 @@ -import ReactWebChat from '../../../../packages/bundle'; +import React from 'react'; + +import ReactWebChat from '../../../../lib/index'; // "dir" must be a string of "ltr' | 'rtl' | 'auto'. ; diff --git a/__tests__/types/__typescript__/fail-once/invalid-style-options-suggested-actions-stacked-overflow.ts b/packages/bundle/__tests__/types/__typescript__/fail-once/invalid-style-options-suggested-actions-stacked-overflow.ts similarity index 57% rename from __tests__/types/__typescript__/fail-once/invalid-style-options-suggested-actions-stacked-overflow.ts rename to packages/bundle/__tests__/types/__typescript__/fail-once/invalid-style-options-suggested-actions-stacked-overflow.ts index 69814abf8c..728a4d4661 100644 --- a/__tests__/types/__typescript__/fail-once/invalid-style-options-suggested-actions-stacked-overflow.ts +++ b/packages/bundle/__tests__/types/__typescript__/fail-once/invalid-style-options-suggested-actions-stacked-overflow.ts @@ -1,4 +1,4 @@ -import { createStyleSet } from '../../../../packages/bundle'; +import { createStyleSet } from '../../../../lib/index'; // Related to #4081. createStyleSet({ suggestedActionsStackedOverflow: 'string' }); diff --git a/__tests__/types/__typescript__/fail-once/invalid-type-for-use-style-options.tsx b/packages/bundle/__tests__/types/__typescript__/fail-once/invalid-type-for-use-style-options.tsx similarity index 64% rename from __tests__/types/__typescript__/fail-once/invalid-type-for-use-style-options.tsx rename to packages/bundle/__tests__/types/__typescript__/fail-once/invalid-type-for-use-style-options.tsx index 4493101f34..924f88479d 100644 --- a/__tests__/types/__typescript__/fail-once/invalid-type-for-use-style-options.tsx +++ b/packages/bundle/__tests__/types/__typescript__/fail-once/invalid-type-for-use-style-options.tsx @@ -1,4 +1,4 @@ -import { hooks } from '../../../../packages/bundle'; +import { hooks } from '../../../../lib/index'; const [styleOptions] = hooks.useStyleOptions(); diff --git a/packages/bundle/__tests__/types/__typescript__/fail-once/no-children-for-react-web-chat-in-minimal.tsx b/packages/bundle/__tests__/types/__typescript__/fail-once/no-children-for-react-web-chat-in-minimal.tsx new file mode 100644 index 0000000000..ea6ebbd874 --- /dev/null +++ b/packages/bundle/__tests__/types/__typescript__/fail-once/no-children-for-react-web-chat-in-minimal.tsx @@ -0,0 +1,8 @@ +import React from 'react'; + +import ReactWebChat from '../../../../lib/index-minimal'; + +// should not contains any children. + +
Hello, World
+
; diff --git a/__tests__/types/__typescript__/fail-once/no-children-for-react-web-chat-in-minimal.tsx b/packages/bundle/__tests__/types/__typescript__/fail-once/no-children-for-react-web-chat.tmp.tsx similarity index 63% rename from __tests__/types/__typescript__/fail-once/no-children-for-react-web-chat-in-minimal.tsx rename to packages/bundle/__tests__/types/__typescript__/fail-once/no-children-for-react-web-chat.tmp.tsx index a6a1b5bf65..6ae8e3f886 100644 --- a/__tests__/types/__typescript__/fail-once/no-children-for-react-web-chat-in-minimal.tsx +++ b/packages/bundle/__tests__/types/__typescript__/fail-once/no-children-for-react-web-chat.tmp.tsx @@ -1,4 +1,6 @@ -import ReactWebChat from '../../../../packages/bundle/lib/index-minimal'; +import React from 'react'; + +import ReactWebChat from '../../../../lib/index'; // should not contains any children. diff --git a/__tests__/types/__typescript__/fail-once/no-children-for-react-web-chat.tsx b/packages/bundle/__tests__/types/__typescript__/fail-once/no-children-for-react-web-chat.tsx similarity index 63% rename from __tests__/types/__typescript__/fail-once/no-children-for-react-web-chat.tsx rename to packages/bundle/__tests__/types/__typescript__/fail-once/no-children-for-react-web-chat.tsx index 258b9340f2..6ae8e3f886 100644 --- a/__tests__/types/__typescript__/fail-once/no-children-for-react-web-chat.tsx +++ b/packages/bundle/__tests__/types/__typescript__/fail-once/no-children-for-react-web-chat.tsx @@ -1,4 +1,6 @@ -import ReactWebChat from '../../../../packages/bundle'; +import React from 'react'; + +import ReactWebChat from '../../../../lib/index'; // should not contains any children. diff --git a/__tests__/types/__typescript__/fail-once/no-full-bundle-style-options-in-minimal-for-hooks.ts b/packages/bundle/__tests__/types/__typescript__/fail-once/no-full-bundle-style-options-in-minimal-for-hooks.ts similarity index 58% rename from __tests__/types/__typescript__/fail-once/no-full-bundle-style-options-in-minimal-for-hooks.ts rename to packages/bundle/__tests__/types/__typescript__/fail-once/no-full-bundle-style-options-in-minimal-for-hooks.ts index 7b713a0383..b5b89209f9 100644 --- a/__tests__/types/__typescript__/fail-once/no-full-bundle-style-options-in-minimal-for-hooks.ts +++ b/packages/bundle/__tests__/types/__typescript__/fail-once/no-full-bundle-style-options-in-minimal-for-hooks.ts @@ -1,4 +1,4 @@ -import { hooks } from '../../../../packages/bundle/lib/index-minimal'; +import { hooks } from '../../../../lib/index-minimal'; const [styleOptions] = hooks.useStyleOptions(); diff --git a/__tests__/types/__typescript__/fail-once/no-full-bundle-style-options-in-minimal.ts b/packages/bundle/__tests__/types/__typescript__/fail-once/no-full-bundle-style-options-in-minimal.ts similarity index 64% rename from __tests__/types/__typescript__/fail-once/no-full-bundle-style-options-in-minimal.ts rename to packages/bundle/__tests__/types/__typescript__/fail-once/no-full-bundle-style-options-in-minimal.ts index 15873a7973..9db592dce6 100644 --- a/__tests__/types/__typescript__/fail-once/no-full-bundle-style-options-in-minimal.ts +++ b/packages/bundle/__tests__/types/__typescript__/fail-once/no-full-bundle-style-options-in-minimal.ts @@ -1,4 +1,4 @@ -import { createStyleSet } from '../../../../packages/bundle/lib/index-minimal'; +import { createStyleSet } from '../../../../lib/index-minimal'; // "cardEmphasisBackgroundColor" is a style options only available in full bundle. createStyleSet({ cardEmphasisBackgroundColor: 'orange' }); diff --git a/packages/bundle/__tests__/types/__typescript__/pass/additional-style-options-in-full.ts b/packages/bundle/__tests__/types/__typescript__/pass/additional-style-options-in-full.ts new file mode 100644 index 0000000000..e12aa7c5a0 --- /dev/null +++ b/packages/bundle/__tests__/types/__typescript__/pass/additional-style-options-in-full.ts @@ -0,0 +1,3 @@ +import { createStyleSet } from '../../../../lib/index'; + +createStyleSet({ cardEmphasisBackgroundColor: 'orange' }); diff --git a/__tests__/types/__typescript__/pass/composition-with-store.tsx b/packages/bundle/__tests__/types/__typescript__/pass/composition-with-store.tsx similarity index 73% rename from __tests__/types/__typescript__/pass/composition-with-store.tsx rename to packages/bundle/__tests__/types/__typescript__/pass/composition-with-store.tsx index c58e0e81c4..336f0e5dbf 100644 --- a/__tests__/types/__typescript__/pass/composition-with-store.tsx +++ b/packages/bundle/__tests__/types/__typescript__/pass/composition-with-store.tsx @@ -1,6 +1,7 @@ +import React from 'react'; import ReactDOM from 'react-dom'; -import { Components, createStore } from '../../../../packages/bundle'; +import { Components, createStore } from '../../../../lib/index'; const { BasicWebChat, Composer } = Components; diff --git a/packages/bundle/__tests__/types/__typescript__/pass/correct-type-dir.tsx b/packages/bundle/__tests__/types/__typescript__/pass/correct-type-dir.tsx new file mode 100644 index 0000000000..f384830536 --- /dev/null +++ b/packages/bundle/__tests__/types/__typescript__/pass/correct-type-dir.tsx @@ -0,0 +1,5 @@ +import React from 'react'; + +import ReactWebChat from '../../../../lib/index'; + +; diff --git a/packages/bundle/__tests__/types/__typescript__/pass/import-component-send-text-box.tsx b/packages/bundle/__tests__/types/__typescript__/pass/import-component-send-text-box.tsx new file mode 100644 index 0000000000..15606accc0 --- /dev/null +++ b/packages/bundle/__tests__/types/__typescript__/pass/import-component-send-text-box.tsx @@ -0,0 +1,7 @@ +import React from 'react'; + +import { Components } from '../../../../lib/index'; + +const { SendTextBox } = Components; + +; diff --git a/packages/bundle/__tests__/types/__typescript__/pass/import-create-direct-line.tsx b/packages/bundle/__tests__/types/__typescript__/pass/import-create-direct-line.tsx new file mode 100644 index 0000000000..42810d5ea7 --- /dev/null +++ b/packages/bundle/__tests__/types/__typescript__/pass/import-create-direct-line.tsx @@ -0,0 +1,3 @@ +import { createDirectLine } from '../../../../lib/index'; + +createDirectLine({ token: 'faketoken' }); diff --git a/__tests__/types/__typescript__/pass/render-with-minimal-bundle.tsx b/packages/bundle/__tests__/types/__typescript__/pass/render-with-minimal-bundle.tsx similarity index 70% rename from __tests__/types/__typescript__/pass/render-with-minimal-bundle.tsx rename to packages/bundle/__tests__/types/__typescript__/pass/render-with-minimal-bundle.tsx index 43c6180145..9178e46e6c 100644 --- a/__tests__/types/__typescript__/pass/render-with-minimal-bundle.tsx +++ b/packages/bundle/__tests__/types/__typescript__/pass/render-with-minimal-bundle.tsx @@ -1,6 +1,7 @@ +import React from 'react'; import ReactDOM from 'react-dom'; -import ReactWebChat, { createDirectLine } from '../../../../packages/bundle/lib/index-minimal'; +import ReactWebChat, { createDirectLine } from '../../../../lib/index-minimal'; const directLine = createDirectLine({ token: '...' }); const styleOptions = { accent: 'black' }; diff --git a/__tests__/types/__typescript__/pass/render-with-store.tsx b/packages/bundle/__tests__/types/__typescript__/pass/render-with-store.tsx similarity index 68% rename from __tests__/types/__typescript__/pass/render-with-store.tsx rename to packages/bundle/__tests__/types/__typescript__/pass/render-with-store.tsx index 2f80f185fc..cfb47be094 100644 --- a/__tests__/types/__typescript__/pass/render-with-store.tsx +++ b/packages/bundle/__tests__/types/__typescript__/pass/render-with-store.tsx @@ -1,6 +1,7 @@ +import React from 'react'; import ReactDOM from 'react-dom'; -import { Components, createStore } from '../../../../packages/bundle'; +import { Components, createStore } from '../../../../lib/index'; const { Composer } = Components; diff --git a/__tests__/types/__typescript__/pass/render-with-style-options.tsx b/packages/bundle/__tests__/types/__typescript__/pass/render-with-style-options.tsx similarity index 74% rename from __tests__/types/__typescript__/pass/render-with-style-options.tsx rename to packages/bundle/__tests__/types/__typescript__/pass/render-with-style-options.tsx index 3f7d1d0aea..6f048c476d 100644 --- a/__tests__/types/__typescript__/pass/render-with-style-options.tsx +++ b/packages/bundle/__tests__/types/__typescript__/pass/render-with-style-options.tsx @@ -1,6 +1,7 @@ +import React from 'react'; import ReactDOM from 'react-dom'; -import ReactWebChat, { createDirectLine } from '../../../../packages/bundle'; +import ReactWebChat, { createDirectLine } from '../../../../lib/index'; const directLine = createDirectLine({ token: '...' }); const styleOptions = { accent: 'black', cardEmphasisBackgroundColor: 'orange' }; diff --git a/__tests__/types/__typescript__/pass/render-with-style-set.tsx b/packages/bundle/__tests__/types/__typescript__/pass/render-with-style-set.tsx similarity index 87% rename from __tests__/types/__typescript__/pass/render-with-style-set.tsx rename to packages/bundle/__tests__/types/__typescript__/pass/render-with-style-set.tsx index 2c7aa8f9c4..23675540ef 100644 --- a/__tests__/types/__typescript__/pass/render-with-style-set.tsx +++ b/packages/bundle/__tests__/types/__typescript__/pass/render-with-style-set.tsx @@ -1,6 +1,7 @@ +import React from 'react'; import ReactDOM from 'react-dom'; -import ReactWebChat, { createDirectLine, createStyleSet } from '../../../../packages/bundle/lib/index-minimal'; +import ReactWebChat, { createDirectLine, createStyleSet } from '../../../../lib/index-minimal'; const directLine = createDirectLine({ token: '...' }); const styleOptions = { accent: 'black', cardEmphasisBackgroundColor: 'orange' }; diff --git a/__tests__/types/__typescript__/pass/render.tsx b/packages/bundle/__tests__/types/__typescript__/pass/render.tsx similarity index 64% rename from __tests__/types/__typescript__/pass/render.tsx rename to packages/bundle/__tests__/types/__typescript__/pass/render.tsx index 2c2ff1637c..2a6fb70043 100644 --- a/__tests__/types/__typescript__/pass/render.tsx +++ b/packages/bundle/__tests__/types/__typescript__/pass/render.tsx @@ -1,6 +1,7 @@ +import React from 'react'; import ReactDOM from 'react-dom'; -import ReactWebChat, { createDirectLine } from '../../../../packages/bundle'; +import ReactWebChat, { createDirectLine } from '../../../../lib/index'; const directLine = createDirectLine({ token: '...' }); diff --git a/__tests__/types/__typescript__/pass/use-style-options-with-full-bundle.ts b/packages/bundle/__tests__/types/__typescript__/pass/use-style-options-with-full-bundle.ts similarity index 65% rename from __tests__/types/__typescript__/pass/use-style-options-with-full-bundle.ts rename to packages/bundle/__tests__/types/__typescript__/pass/use-style-options-with-full-bundle.ts index 89a7fb4045..d898987f89 100644 --- a/__tests__/types/__typescript__/pass/use-style-options-with-full-bundle.ts +++ b/packages/bundle/__tests__/types/__typescript__/pass/use-style-options-with-full-bundle.ts @@ -1,4 +1,4 @@ -import { hooks } from '../../../../packages/bundle'; +import { hooks } from '../../../../lib/index'; const [styleOptions] = hooks.useStyleOptions(); diff --git a/__tests__/types/__typescript__/pass/valid-style-options-suggested-actions-stacked-overflow.ts b/packages/bundle/__tests__/types/__typescript__/pass/valid-style-options-suggested-actions-stacked-overflow.ts similarity index 81% rename from __tests__/types/__typescript__/pass/valid-style-options-suggested-actions-stacked-overflow.ts rename to packages/bundle/__tests__/types/__typescript__/pass/valid-style-options-suggested-actions-stacked-overflow.ts index 30ee59aecb..968804ef8b 100644 --- a/__tests__/types/__typescript__/pass/valid-style-options-suggested-actions-stacked-overflow.ts +++ b/packages/bundle/__tests__/types/__typescript__/pass/valid-style-options-suggested-actions-stacked-overflow.ts @@ -1,4 +1,4 @@ -import { createStyleSet } from '../../../../packages/bundle'; +import { createStyleSet } from '../../../../lib/index'; // Related to #4081. createStyleSet({ suggestedActionsStackedOverflow: 'auto' }); diff --git a/__tests__/types/tsconfig.json b/packages/bundle/__tests__/types/tsconfig.json similarity index 100% rename from __tests__/types/tsconfig.json rename to packages/bundle/__tests__/types/tsconfig.json diff --git a/__tests__/types/typescript.js b/packages/bundle/__tests__/types/typescript.js similarity index 100% rename from __tests__/types/typescript.js rename to packages/bundle/__tests__/types/typescript.js diff --git a/__tests__/types/__typescript__/pass/direct-line-activity-from-bot.ts b/packages/core/__tests__/types/__typescript__/pass/direct-line-activity-from-bot.ts similarity index 85% rename from __tests__/types/__typescript__/pass/direct-line-activity-from-bot.ts rename to packages/core/__tests__/types/__typescript__/pass/direct-line-activity-from-bot.ts index 8c0e66b471..48684c8f4f 100644 --- a/__tests__/types/__typescript__/pass/direct-line-activity-from-bot.ts +++ b/packages/core/__tests__/types/__typescript__/pass/direct-line-activity-from-bot.ts @@ -1,4 +1,4 @@ -import type { WebChatActivity } from '../../../../packages/core'; +import type { WebChatActivity } from '../../../../lib/index'; // All activities from bot must be from server. const activity: WebChatActivity = { diff --git a/__tests__/types/__typescript__/pass/direct-line-activity-from-user-send-failed.ts b/packages/core/__tests__/types/__typescript__/pass/direct-line-activity-from-user-send-failed.ts similarity index 86% rename from __tests__/types/__typescript__/pass/direct-line-activity-from-user-send-failed.ts rename to packages/core/__tests__/types/__typescript__/pass/direct-line-activity-from-user-send-failed.ts index 791d641723..01b94e8d4b 100644 --- a/__tests__/types/__typescript__/pass/direct-line-activity-from-user-send-failed.ts +++ b/packages/core/__tests__/types/__typescript__/pass/direct-line-activity-from-user-send-failed.ts @@ -1,4 +1,4 @@ -import type { WebChatActivity } from '../../../../packages/core'; +import type { WebChatActivity } from '../../../../lib/index'; // All activities that failed to send, are activities that never reach the server (a.k.a. activity-in-transit). const activity: WebChatActivity = { diff --git a/__tests__/types/__typescript__/pass/direct-line-activity-from-user-sending.ts b/packages/core/__tests__/types/__typescript__/pass/direct-line-activity-from-user-sending.ts similarity index 86% rename from __tests__/types/__typescript__/pass/direct-line-activity-from-user-sending.ts rename to packages/core/__tests__/types/__typescript__/pass/direct-line-activity-from-user-sending.ts index bb3658db05..cb68e8e30c 100644 --- a/__tests__/types/__typescript__/pass/direct-line-activity-from-user-sending.ts +++ b/packages/core/__tests__/types/__typescript__/pass/direct-line-activity-from-user-sending.ts @@ -1,4 +1,4 @@ -import type { WebChatActivity } from '../../../../packages/core'; +import type { WebChatActivity } from '../../../../lib/index'; // All activities that are sending, are activities that did not reach the server yet (a.k.a. activity-in-transit). const activity: WebChatActivity = { diff --git a/__tests__/types/__typescript__/pass/direct-line-activity-from-user-sent.ts b/packages/core/__tests__/types/__typescript__/pass/direct-line-activity-from-user-sent.ts similarity index 86% rename from __tests__/types/__typescript__/pass/direct-line-activity-from-user-sent.ts rename to packages/core/__tests__/types/__typescript__/pass/direct-line-activity-from-user-sent.ts index e9f473274e..07a781b794 100644 --- a/__tests__/types/__typescript__/pass/direct-line-activity-from-user-sent.ts +++ b/packages/core/__tests__/types/__typescript__/pass/direct-line-activity-from-user-sent.ts @@ -1,4 +1,4 @@ -import type { WebChatActivity } from '../../../../packages/core'; +import type { WebChatActivity } from '../../../../lib/index'; // All activities which are "sent", must be from server. const activity: WebChatActivity = { diff --git a/packages/core/__tests__/types/tsconfig.json b/packages/core/__tests__/types/tsconfig.json new file mode 100644 index 0000000000..aee0ec940f --- /dev/null +++ b/packages/core/__tests__/types/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "strict": true + } +} diff --git a/packages/core/__tests__/types/typescript.js b/packages/core/__tests__/types/typescript.js new file mode 100644 index 0000000000..b0fe9c7597 --- /dev/null +++ b/packages/core/__tests__/types/typescript.js @@ -0,0 +1,96 @@ +const { join, relative } = require('path'); +const { readdir } = require('fs').promises; + +const ts = require('typescript'); + +function compile(...filenames) { + const program = ts.createProgram(filenames, { + allowSyntheticDefaultImports: true, + jsx: 'react', + noEmit: true, + skipLibCheck: true, + strict: true + }); + + const emitResult = program.emit(); + const allDiagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics); + const errors = []; + + allDiagnostics.forEach(diagnostic => { + if (diagnostic.file) { + const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start); + const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); + + errors.push(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`); + } else { + errors.push(ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n')); + } + }); + + return errors; +} + +describe('compiling TypeScript files', () => { + describe('in /pass/ folder', () => { + let results; + + beforeEach(async () => { + const path = join(__dirname, '__typescript__/pass/'); + let files = []; + + try { + files = await readdir(path); + } catch (error) { + if (error.code !== 'ENOENT') { + throw error; + } + } + + results = {}; + + files.forEach(file => { + const fullPath = join(path, file); + + results[relative(path, fullPath)] = { errors: compile(fullPath) }; + }); + }); + + test('should pass', () => { + for (const filename of Object.keys(results)) { + expect(results).toHaveProperty([filename, 'errors'], []); + expect(results).toHaveProperty([filename, 'errors', 'length'], 0); + } + }); + }); + + describe('in /fail-once/ folder', () => { + let results; + + beforeEach(async () => { + const path = join(__dirname, '__typescript__/fail-once/'); + let files = []; + + try { + files = await readdir(path); + } catch (error) { + if (error.code !== 'ENOENT') { + throw error; + } + } + + results = {}; + + files.forEach(file => { + const fullPath = join(path, file); + + results[relative(path, fullPath)] = { errors: compile(fullPath) }; + }); + }); + + test('should fail only once', () => { + for (const filename of Object.keys(results)) { + expect(results).toHaveProperty([filename, 'errors', 'length'], 1); + } + }); + }); +});