Skip to content

Latest commit

 

History

History
314 lines (244 loc) · 17.5 KB

CONTRIBUTING.md

File metadata and controls

314 lines (244 loc) · 17.5 KB

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com.

When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repositories using our CLA.

Thank you

Thanks for your interest in improving Web Chat. We invest heavily in engineering excellence to reduce our workloads and enable us to move faster. To start the development, please familiarize yourself with the development process and these automation tools.

If you need to build this project for customization purposes, we strongly advise you to refer to our samples. If you cannot find any samples that fulfill your customization needs and you don't know how to do that, please send your dream to us.

Forking Web Chat to make your own customizations means you will lose access to our latest features and security updates. Maintaining forks also introduces chores that are substantially more complicated than a version bump.

Preparing the environment

There are 2 steps to prepare the environment: install tools and prepare the repository.

Installing tools

Please install the following in the development environment:

Preparing the repository

To keep our main repository clean and easy to maintain, all changes must done in a fork.

npm clean-install

Building the project

Default build flavor is development. Please read BUILD_SCRIPTS.md about different build flavors.

There are two ways to build: one-off and continuous build.

  • For one-off building, run npm run build
  • For continuous building
    • For the first time, run npm run build
    • Then, run npm start

The bundle output will be located at:

Trying out the build

There are multiple ways to try out the build:

  • Using ChromeDriver (recommended)
    • Run npm start, wait until stable
    • In a new terminal window, run npm run browser
      • Browse to simple.html
  • Using webchat-loader
    • Navigate to https://compulim.github.io/webchat-loader/
    • In the version dropdown, select http://localhost:5000/webchat-es5.js
      • If you do not see this options, make sure you have run npm start and can access the URL
    • Selecting a bot to use
      • If you do not own a bot or prefer to use our bots, select "[Public] MockBot" or other bots from the presets
      • If you have your own Direct Line or Direct Line App Service Extension bot:
        • Check "Direct Line via Web Socket" or "Direct Line App Service Extension" in the "Protocol" section
          • For "Direct Line App Service Extension", set the host name to your bot
        • If you have the Direct Line secret of your bot, type it in the "Secret" box
        • Otherwise, type the token in the "Token" box
      • If you have a Direct Line Speech bot:
        • Select the region of your resource in the "Speech region" box
        • Type the subscription key in the "Speech key" box, or the authorization token in the "Speech token" box
    • Selecting speech options for non-Direct Line Speech bot:
      • If you do not need to use speech, clear "Speech key" and "Speech token"
      • If you own a Cognitive Services Speech Services resource:
        • Select the region of your resource in the "Speech region" box
        • Type the subscription key in the "Speech key" box, or the authorization token in the "Speech token" box
      • If you do not own Cognitive Services Speech Services resource, click "MockBot" below the "Speech key" box
  • Write your own HTML page to load Web Chat
    • Using a HTML page is recommended over using the playground or loader for development, for faster loading and quick reproduce ability
    • <script src="http://localhost:5000/webchat.js"></script>
  • Create a new React app and symlink or load tarballs from these packages, in the following order:
    1. /packages/core
    2. /packages/api
    3. /packages/component
    4. /packages/directlinespeech
    5. /packages/bundle

How to contribute to our code

  1. Use test driven development
  2. Fix the issue or implement the new feature
  3. Run static code analysis
  4. Final checks

Test driven development

We care about software quality. Quality checking prevents regressions, reduces maintenance costs, minimizes chores, and enables us to move faster.

For bugs, write test page(s) to reproduce the bug, then fix it. This will prevent future regressions.

For features, write test page(s) to try out the feature. Write new test pages to verify different sub-features, e.g. rendering in carousel layout vs. rendering in stacked layout. Also write tests for both happy and unhappy paths. This will future-proof the work and protect the investment.

Writing a test

Start by copying the test page template from /__tests__/html/simple.html and simple.js. Additionally, follow other test pages to learn about our page object model.

We prefer using end-to-end visual regression tests (VRT) for pixel-perfect and whole feature verification. Unit tests should be written for utility functions. For VRT, we use pixelmatch via jest-image-snapshot.

Running tests manually

Download ChromeDriver and extract to the project root.

Run npm run browser. It will open a new browser window to http://localhost:5001/**tests**/html/. Then, navigate to the test file.

When tests have completed successfully, the page should display a green check.

Transcript with a green check showing test succeeded

If the test pages take any screenshots, run them in Jest to save the screenshots to /__tests__/__image_snapshots__/html/.

Running tests automatically

For test environment convergence and stability, Web Chat uses Docker for hosting the test environment. Please install the following components:

  1. On Windows, install Windows Subsystem for Linux 2 (a.k.a. WSL 2)
  2. Docker Desktop
  3. (Optional) Install watchman to improve Jest performance
  4. Run npm run docker. It will start a Docker Compose with Selenium Grid and 4 nodes of Chrome
  5. In a new terminal, run npm test to start Jest. When Jest runs the test pages, it will take screenshots of new tests and save it under /__tests__/__image_snapshots__/html

Troubleshooting test suites

We run test suites on every PR and require 100% pass rate. If test suites do not complete successfully, the cause may be:

  • New changes are causing failure(s) in existing tests
  • Intermittent services issues
  • Test reliability issue, please see #2938
  • Polluted development environment, for example:
    • Outdated node_modules content
    • Outdated Node.js or NPM

When the test suites fail:

  • Identify whether the tests fail WITHOUT any code changes
    • Make a fresh clone of BotFramework-WebChat and run the test suites without any changes. If the fresh clone tests pass, this means the latest code changes are causing failures.
  • Identify whether the failure is intermittent
    • Run the (failing) test suites again, potentially using Jest filters (F for failed tests)

If existing test suites fail without any code changes, please determine the following:

  • Test suites always fail, even after repeated runs
    • The service may have been updated, causing the test suite failures. Please file an issue on the Web Chat repository.
  • Test suites fail intermittently
    • Service reliability problems (e.g. for DirectLine, or Mockbot) may be the cause. Please file an issue on the Web Chat repository.
    • Test reliability problems may be the cause. If so, please comment on #2938 and include:
      • Failing test names/files
      • Failing screencaps, if available. These images can be retrieved from __diff_output__
      • Error messages

To debug race conditions:

  1. Append location.reload() to the test code to continually reload the test page until it fails
  2. Navigate to the test page on http://localhost:5001/tests/<testname> and wait until the test fails, after which the automatic reloading will stop

General tips on race conditions or intermittent test failures:

  • After sending a message, wait for responses from the bot, using await pageConditions.minNumActivitiesShown(2)
  • After a long message is shown, wait for scroll to complete, using await pageConditions.scrollToBottomCompleted()
  • Remove or speed up animations and media progress bars
    • If your screenshot is taken with a GIF animation, such as the spinner next to "Connecting..." prompt, you will want to replace it using styleOptions:
      • styleOptions: { spinnerAnimationBackgroundImage: 'url(/assets/staticspinner.png)' }

Static code analysis

Run npm run precommit for static code analysis.

To ignore any ESLint errors, please use eslint-disable-next-line instead of disabling a specific rule for the whole file. Comments are required on why the rule is disabled.

Final checks

There are checks that automation will not be able to capture. For example:

  • Transparency
    • Summarize test updates or changes as a part of the pull request
    • If there are ONLY test changes, summarize those changes in CHANGELOG.md as well
    • Fill out the pull request form with details
  • Hygiene
    • Make sure imports, members, variables, etc, are sorted alphabetically
    • Avoid one-off variables, prefer JavaScript shorthands, shorter and faster code
    • CSS
      • Remove unneeded CSS styles
      • Use CSS BEM and always namespace with webchat__, for example, webchat__block__element--modifier
      • Articles on CSS BEM
    • Only use local assets
      • All assets must be self-contained and not loaded from any external URLs. This includes both Web Chat assets and test assets
    • No logging to console. Only exceptions:
      • Deprecation notes
      • Warnings
      • Errors
    • No global pollution, for example:
      • No taborder with numbers other than 0 or -1
      • Minimize z-index usage
      • Be mindful when using CSS styles in a component with content from end-developers. CSS styles may leak into the content, for example:
        • Set CSS as high in the DOM tree as possible, for example:
          • <section>
              <header>Header</header>
              <p>First</p>
              <p>Second</p>
              <footer>Footer</p>
            </section>
          • Setting font-family in <section> produces fewer lines of code than setting font-family in <header>, <p>, and <footer>, due to the cascade effect
  • Inclusivity
    • All features must be accessible. Please refer to docs/ACCESSIBILITY.md
      • Tab order, content readability, assistive technology-only text, color contrast, etc. must be maintained
      • Assistive technology and browser compatibility
        • NVDA/JAWS: Chrome and Firefox
        • Narrator: Microsoft Edge and Internet Explorer 11
        • VoiceOver: Safari on macOS and iOS/iPadOS
        • TalkBack: Chrome on Android
    • All strings must be localized and all formats internationalized
  • Tests
    • Tests are important to reduce maintenence burden
    • Pull requests without tests will not be approved or merged into the project
    • When fixing a bug, a new test must be added to reproduce the bug to protect regressions
    • For feature work, please add as many tests as needed to future-proof the feature and protect the investment
    • Avoid using sleeps. Instead, use fake timer
    • Prioritize short, numerous tests to maximize test parallelism
      • Avoid single, monolithic tests as much as possible
  • Ensure that changes are secure by default
  • Benchmark
    • Performance should not drop significantly
    • Bundle size should not increase significantly
    • Code coverage should not decrease significantly
    • Backward compatibility should be maintained for 2 years
  • Cross browser compatibility
    • Windows 10
      • Chrome
      • Microsoft Edge Chromium
      • Firefox
      • Internet Explorer 11 (except speech features)
    • Safari on macOS
    • Safari on iOS or iPadOS
    • Chrome on Android
  • Include feature documentation, samples, live demo, published demos bots, etc.
    • All samples must also come with a hosted live demo
    • Please discuss with us if a specific bot is needed for the live demo

Summary

The following is a quick summary on how to approach when fixing a bug or implementing a new feature.

Fixing bugs

Write the bug repro as a test before fixing the bug.

  1. Clone and prepare the repository or reset an existing one
    • To reset, run git clean -fdx
  2. Run continuous build by running npm start
  3. Reproduce the bug on a test page under __tests__/html/this.is.the.bug.html
  4. Run npm run browser and navigate to the test page
    • Make sure the test(s) fail as described in the repro
  5. Fix the bug
  6. Tests should succeed after bug fixes are compiled and reloaded in the browser
  7. Run all test suites:
    • Run npm run docker, followed by npm test in a new terminal
  8. Do final checks
  9. Submit a pull request

Implementing new features

Write the user story while implementing the feature.

  1. Clone and prepare the repository or reset an existing one
    • To reset, run git clean -fdx
  2. Run continuous build by running npm start
  3. Clone the test page __tests__/html/simple.html to feature.subfeature.scenario.html and use it as a playground
  4. Run npm run browser and navigate to the test page
  5. Implement the feature and update/add test pages as needed
    • Test pages should include cases that need more attention, and unhappy paths
  6. Run all test suites:
    • Run npm run docker, followed by npm test in a new terminal
  7. For prominent features
    • Write a new sample with a README.md, following our samples format
      • This is the user story and proof-of-record on how the feature will work
      • Update samples/README.md to include the new sample in the list
    • Add design docs to /docs
  8. Do final checks
  9. Submit a pull request

Additional context

Articles related to CSS Block Element Modifier methodology

Adding languages

To add a new language to our localization list, please refer to docs/LOCALIZATION.md.