Contributing
August 24, 2023 ยท View on GitHub
Note: The master branch is being locked, and there won't be any more releases from that branch. Kindly initiate new pull requests against the next branch instead.
We'd love for you to contribute to our source code and to make Webex Javascript SDK even better than it is today! If you would like to contribute to this repository by adding features, enhancements or bug fixes, you must follow our process:
- Let core members know about your proposal by posting a message in the contributor's Webex space
- A core member will review your proposal and if necessary may suggest to have a meeting to better understand your approach
- You are welcomed you join our weekly review meeting (Thursdays, 11:30a-12:30p PST) to propose your contribution as well
- If your proposal is approved you should start coding at this point
- We recommend opening a draft PR to receive feedback before finalizing your solution
- When opening a draft PR, specify with PR comments where in the code you would like to get feedback
- Before opening a PR ensure all PR guidelines are followed
- Let core members know about your PR by posting a message in the contributor's Webex space
- Core members will review the pull request and provide feedback when necessary
- If a PR is too large, you may be asked to break it down into multiple smaller-scoped PRs
- Once the PR is approved by a core member, it will be merged
- Celebrate! Your code is released ๐๐๐ป
Table of Contents
- Contributing
Reporting Issues
Please reach out to our developer support team for any issues you may be experiencing with the SDK.
Contributing Code
Build Dependencies
Before you can build the Cisco Webex JS SDK, you will need the following dependencies:
- Node.js (LTS)
- We recommend using nvm (or nvs on Windows (not WSL)) to easily switch between Node.js versions
- Run
nvm useto set your node version to the one this package expects- If the required node version is not installed,
nvm/nvswill tell you the command needed to install it
- If the required node version is not installed,
- Install the latest npm to enable security audits using
npm install -g npm@latest
- Git
- node-gyp
- This is used during the dependency install process and is used to compile some native add-on modules
- Install with
npm install -g node-gyp- On Windows (not WSL), follow Option 1 on node-gyp's repo, as this will automatically install python 2 and necessary build dependencies
- Python 2.7
- This is also used during the dependency install process
- Attempting to update dependencies with a Python 3.x environment will fail
- jq
- jq processes JSON objects in bash. We use this command throughout our tooling
- Follow these instructions on how to install
jqin your system
NOTE FOR WINDOWS 10
We suggest using Windows Subsystem for Linux (WSL) for the best experience on Windows. We've seen multiple tooling/package related errors when trying to build on a regular Windows environment. The build errors are a result of third-party node_modules that we do not maintain. These issues are not seen when using WSL.
Building the SDK
Ensure that you have followed all the steps outlined in Build Dependencies.
Fork the webex-js-sdk repository and git clone your fork:
git clone https://github.com/your-username/webex-js-sdk.git
Install tooling dependencies with:
yarn install
Build the SDK:
yarn run build
If at any point your out-of-the-box builds or failing or if you are tests are failing with complaints of an invalid node version, the following commands will reset and rebuild everything:
yarn
By default npm uses sh which does not support the glob syntax and as such distsrc and srcdist will fail with No such file or directory. To fix this you can set npm to use bash instead using:
npm config set script-shell "/bin/bash"
Environment Variables
You will need to create a file called .env that defines, at a minimum:
WEBEX_CLIENT_IDWEBEX_CLIENT_SECRETWEBEX_REDIRECT_URIWEBEX_SCOPE
You can get these values by registering a new integration on Cisco Webex for Developers.
Advanced Environment Variables
The JS SDK allows you to customize your experience via configuration and environment variables. In general, external developers will not need to set any of the URL related environment variables.
| Environment Variable | Details | Default |
|---|---|---|
ATLAS_SERVICE_URL | Used to populate the atlasServiceUrl pre discovery config | https://atlas-a.wbx2.com/admin/api/v1 |
CLIENT_LOGS_SERVICE_URL | Used to populate the clientLogsServiceUrl pre discovery config | https://client-logs-a.wbx2.com/api/v1 |
CONVERSATION_SERVICE | Used for validating an auth token | https://conv-a.wbx2.com/conversation/api/v1 |
ENABLE_MERCURY_LOGGING | When set, will log all mercury messages | undefined |
ENABLE_VERBOSE_NETWORK_LOGGING | Utilized to enable interceptor logging | undefined |
ENCRYPTION_SERVICE_URL | Used for plugin-board tests | https://encryption-a.wbx2.com |
HYDRA_SERVICE_URL | Stores the public hydra api url for managing Webex resources. | https://api.ciscospark.com/v1/ |
IDBROKER_BASE_URL | Used throughout the SDK as the endpoint for authorization | https://idbroker.webex.com |
IDENTITY_BASE_URL | Used to communicate with the identity api | https://identity.webex.com |
MERCURY_FORCE_CLOSE_DELAY | Milliseconds to wait for a before declaring the socket dead | 2000 |
MERCURY_PING_INTERVAL | Milliseconds between pings sent up the socket | 15000 |
MERCURY_PONG_TIMEOUT | Milliseconds to wait for a pong before declaring the connection dead | 14000 |
METRICS_SERVICE_URL | Used to populate the metricsServiceUrl pre discovery config | https://metrics-a.wbx2.com/metrics/api/v1 |
U2C_SERVICE_URL | Stores the service catalog collecting url, typically the U2C service. | https://u2c.wbx2.com/u2c/api/v1 |
WEBEX_ACCESS_TOKEN | Used to provide access token when using "webex/env" | undefined |
WEBEX_AUTHORIZE_URL | Populates the Authorization URL which prompts for user's password. | https://idbroker.webex.com/idb/oauth2/v1/authorize |
WEBEX_AUTHORIZATION_STRING | This is the authorization url for the integration from Cisco Webex for Developers | undefined |
WEBEX_CLIENT_ID | The Webex client ID used to authorize | undefined |
WEBEX_CLIENT_SECRET | The Webex client secret used to authorize | undefined |
WEBEX_CONVERSATION_CLUSTER_SERVICE | Service identifier used to lookup conversation servers in hostmap | identityLookup |
WEBEX_CONVERSATION_DEFAULT_CLUSTER | Cluster used to convert from "us" cluster to actual cluster | urn:TEAM:us-east-2_a:identityLookup |
WEBEX_LOG_LEVEL | Maximum log level that should be printed to the console. | log |
WEBEX_REDIRECT_URI | The URI to redirect to after authorization | undefined |
WEBEX_SCOPE | The Webex scope the users will authorize with | undefined |
WDM_SERVICE_URL | The WDM service url before the catalog is downloaded | https://wdm-a.wbx2.com/wdm/api/v1 |
WHISTLER_API_SERVICE_URL | The url to the whistler test service | https://whistler-prod.allnint.ciscospark.com/api/v1 |
WHISTLER | Run (meetings) tests using Whistler users | FALSE |
JENKINS | Run specific tests that should be run on (internal) Jenkins | FALSE |
Running Tests
yarn run test is the entrypoint to our test runner, but its not practical to use without parameters; the full suite would take over two hours to run and cross talk would probably cause tests to break each other.
Get the full test-runner docs via
yarn run test --help.
A local development flow might look like
-
Edit source code in
MYPACKAGE. -
Use
yarn run buildto build all packages . -
Use
yarn run test --packages @webex/MYPACKAGE --nodeto run the tests for just that package only in nodejs (Usually, we don't need to test both in node and the browser during development). -
Repeat steps 1-3 until the tests pass.
yarn run build is a bit tedious when making lots of changes, so instead, we can use yarn run distsrc to point each package's main entry at the raw src and let babel compile on the fly.
-
At the start of development, run
yarn run distsrconce. -
Edit source code in
MYPACKAGE. -
Use
yarn run test --packages @webex/MYPACKAGE --nodeto run the tests for just that package only in nodejs. -
Optionally, add environment variables to mimize logging and show any test specific logging, ie:
- WEBEX_LOG_LEVEL - set this to "log" to minimize the default verbose output
- DEBUG - if your test source includes the debug package set this to the appropriate string to enable debug output
For exampe if you want to run only the plugin-messages test, and see the package specific logging, your command line would be:
WEBEX_LOG_LEVEL=log DEBUG=messages yarn run test --packages @webex/plugin-messages --node
-
Repeat steps 2-3 until the tests pass.
If you use VS Code, we've created a configuration to utilize the built-in debugger
- Set breakpoints within the package you're working on
- Select the
Test packageconfiguration - Enter the package you'd like to test (i.e.
MYPACKAGE)- The configuration already prepends
@webex/for you unlike the cli command, so justplugin-teamsis fine
- The configuration already prepends
- Add any optional flags (i.e.
--node)- If you don't want to add any flags, just add a space (current workaround)
-
Run
yarn run srcdistto restore the package.jsons to avoid committing those changes.
You can use the --unit, --integration, --automation, and --documentation switches to control what types of tests you run and --node and --browser to control which environments your tests run in.
The --packages flags will allow you to test multiple packages in one command instead of separate commands for each package --packages @webex/plugin-meetings @webex/plugin-rooms @webex/plugin-teams. Packages are still tested synchronously to allow for proper output to the terminal.
--browser --karma-debug will run the browser tests with {singleRun: false}, thus allowing automatic rerunning every time you save a file (though, karma does eventually get confused and you need to interrupt and restart the command).
You can use the --browsers (not to be confused with the --browser tag) allows you to specify which browsers you want to run locally. This is restricted to what browsers are installed and available to you on your OS.
The default browsers that launch are Headless version of Firefox and Chrome, so --browsers Chrome Edge will only launch a normal version of Chrome along with Edge. If you add defaults to the browsers flag, it will also launch ChromeHeadless and FirefoxHeadless along with other browsers you've specified. All browsers include flags to enable WebRTC features and permissions.
To run tests on Sauce Labs locally, you'll need to add a inline environment variable, SAUCE=true. Like mentioned above you can specify which browsers you'd like to test on with the --browser flag, but with Sauce Labs service available to you, you can also specify which OS you'd like to test on. With the --os flag you have the option on testing on Mac and Windows. You can filter down the browsers that get launched by using the --browsers flag, so if you use --os Windows --browsers Edge IE it will launch only Edge and IE. Specifying just --browsers with SAUCE=true will launch that browsers in all available OSs, so --browsers Firefox will launch Firefox in Mac and Windows.
The default Sauce Labs configuration "
SAUCE=true yarn run test" is the latest versions ofChromeandFirefoxon bothMacandWindows, along withEdgeandIE 11on Windows, andSafarion Mac
--os Macwill launchChrome,Firefox, andSafari
--os Windowswill launchChrome,Firefox,Edge, andIE 11
--os LinuxWILL NEED--browsers Firefoxas Sauce Labs only supportsFirefox 45for Linux. This is why it's also not included by default and requires two flags
See more scripts at
SCRIPTS.mdto learn how to run tests and more.
Running Samples Locally
git clone git@github.com:webex/webex-js-sdk.git
cd webex-js-sdk
yarn install
yarn run build
yarn run samples:serve
NOTE: This installs all of the SDK's tooling dependencies, so you'll need
libgcryptand (possibly)graphicsmagick.
Mac
- You can install these with
brew install graphicsmagick libgcrypt.Ubuntu
- You can install these with
sudo apt-get install graphicsmagick libgcrypt-devWindows
- You can install
graphicsmagickusing either scoop or Chocolatey
- scoop:
scoop install graphicsmagick- chocolatey:
choco install graphicsmagick- Also globally install
win-node-envto resolveNODE_ENVwindows related command issues
Head to https://localhost:8000/ to use the samples
NOTE: The samples use a self-signed certificate generated by Webpack Dev Server. Some browsers such as Google Chrome (or any other Chromium-based browser) may not allow access by default for security reasons. You may need to configure browser settings to allow these at your own risk by enabling the
chrome://flags/#allow-insecure-localhostflag.
Samples Tests
The samples tests are run by https://webdriver.io which spins up two browser instances and has them communicate between each other.
These tests are run with yarn run samples:test.
We have found that due to the h.264 codec downloading in Firefox, the best way to run these test is on Sauce Labs.
You can run them on Sauce Labs with SAUCE=true yarn run samples:test.
To run a specific sample test instead of the full suite, append the --spec flag to the samples:test command and the path to the specific test
yarn run samples:test --spec docs/samples/browser-call-with-screenshare
If an error occurs when running the above command that appears to be related to a missing Selenium driver, the following command should install the needed external dependencies:
./node_modules/.bin/selenium-standalone install
Latest versions of chrome and firefox need to be installed for selenium to launch correctly.
Local Samples Tests
If you wish to run the samples tests locally, we suggest changing from the Chrome-to-Firefox multi-remote setup to Chrome-to-Chrome.
You can do so by modifying the wdio.conf.js file.
Simply change the browserFirefox's capabilities object to the same as browserChrome (the Chrome instance).
When you run, you should see two instances of Chrome open.
Mobile Samples Tests (Sauce)
NOTE: You will need to off VPN for localhost to tunnel correctly
SAUCE=true yarn run samples:test:mobile
- You will need to alias
localhostwhich will require you to modify yourhostsfile and add that alias to your.envfile with the nameLOCALHOST_ALIAS. - By default, the config will use
local.localhostas the alias ifLOCALHOST_ALIASisn't provided.- on macOS/Linux, you will add
127.0.0.1 local.localhostto/etc/hosts - on Windows, you will add
127.0.0.1 local.localhosttoc:\Windows\System32\Drivers\etc\hosts
- on macOS/Linux, you will add
Local Mobile Samples Tests
NOTE: You will need to off VPN for localhost to tunnel correctly Testing on a iDevice only works on macOS due to the lockdown of
safaridriver, you should probably switch to two Android devices and changes to thewdio.conf.mobile.jsor swap the iDevice config for a different browser installed on the machine.
yarn run samples:test:mobile
By default the config will look for both a Android and iOS device attached to the system. If you wish to test on a specific/singular device and use Chrome installed on your machine, you can pass either IOS=true or ANDROID=true environment variables to the command above.
Ex. ANDROID=true yarn run samples:test:mobile will open Chrome on your local machine and Chrome on your attached Android device.
This process is more involved and requires both devices to be wired to the laptop/machine.
Machine/Laptop
- You will need to alias
localhostwhich will require you to modify yourhostsfile and add that alias to your.envfile with the nameLOCALHOST_ALIAS.. - By default, the config will use
local.localhostas the alias ifLOCALHOST_ALIASisn't provided.- on macOS/Linux, you will add
127.0.0.1 local.localhostto/etc/hosts - on Windows, you will add
127.0.0.1 local.localhosttoc:\Windows\System32\Drivers\etc\hosts
- on macOS/Linux, you will add
- For iDevices, you'll need to enable
safaridriversafaridriver --enable(macOS only)
- For Android, you'll need
adbinstalled- You can run
adb deviceswhich will autostart the server and show you the devices connected
- You can run
iOS
- You will need to make sure that the device has already been trusted to be used by the machine/laptop or else it will not be discovered when webdriverio attempts to connect to the device
- You will need to enable remote debugging on your device
- Settings > Safari > Advanced > Remote automation
Android
- On your device, you'll need to enable Developer Options & USB Debugging
- Settings > About Phone > Tap
Build Numbertill Developer Options is enabled - Settings > Developer Options > USB Debugging > Enable USB Debugging
- Settings > About Phone > Tap
- You will need to make sure that USB Debugging has trusted the machine/laptop or else it will not be discovered when webdriverio attempts to connect to the device
Git Commit Guidelines
We follow the Conventional Commits specification when writing commits and are run/linted through conventional changelog to generate the changelog. Please adhere to the following guidelines when formatting your commit messages.
Commit Message Format
Each commit message consists of a header, a body and a footer. The header has a special format that includes a type, a scope and a subject:
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
The header is mandatory and the scope of the header is optional.
Any line of the commit message cannot be longer 100 characters! This allows the message to be easier to read on GitHub as well as in various git tools.
Revert
If the commit reverts a previous commit, it should begin with revert:, followed by the header of the reverted commit. In the body it should say: This reverts commit <hash>., where the hash is the SHA of the commit being reverted.
Type
Examples can be found on the Conventional Commits website
The following types will cause a version bump:
- fix: Patches a bug in the code and directly corresponds to the PATCH
- perf: A code change that improves performance and corresponds to the PATCH
- feat: Describes a new feature and corresponds to the MINOR
- BREAKING CHANGE: a commit that has a footer
BREAKING CHANGE:, or appends a!after the type/scope, introduces a breaking API change (correlating with MAJOR in semantic versioning).
Appending a
!and/or aBREAKING CHANGE:footer to ANY TYPE will denote a BREAKING CHANGE and will cause a MAJOR bump
The following types will not cause a version bump:
- build: Changes that affect the build system or external dependencies
- ci: Changes to our CI configuration files and scripts
- docs: Documentation only changes
- refactor: A code change that neither fixes a bug, adds a feature, nor changes affecting the public API and corresponds to the PATCH
- style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
- test: Adding missing tests or correcting existing tests
Scope
The scope should indicate what is being changed. Generally, these should match package names. For example, http-core, common, webex, etc. Other than package names, tooling tends to be the most common.
Subject
The subject contains succinct description of the change:
- use the imperative, present tense: "change" not "changed" nor "changes"
- don't capitalize first letter
- no dot (.) at the end
Body
Just as in the subject the imperative, present tense: "change" not "changed" nor "changes". The body should include the motivation for the change and contrast this with previous behavior.
Footer
The footer should contain any information about Breaking changes and is also the place to reference GitHub issues that this commit closes.
Breaking Changes should start with the word BREAKING CHANGE: with a space or two newlines. The rest of the commit message is then used for this.
Special Commit Messages
These are commit messages that will have an impact on how the build pipeline behaves. They are not to be used without prior approval.
All of these commit messages should include an explanation for why you're using them. You'll need to commit with -n or --no-verify to bypass the commit message linter.
For example
git commit -m "docs(webex-core): [skip npm] - docs change" --no-verify
[skip npm]
This will run through the all the GitHub Checks, but will skip any version bumping, tagging, and subsequent publishing to npm after a pull request is merged.
[skip ci]
This will skip the CircleCI pipeline entirely.
Submitting a Pull Request
Prior to developing a new feature, be sure to search the Pull Requests for your idea to ensure you're not creating a duplicate change. Then, create a development branch in your forked repository for your idea and start coding!
When you're ready to submit your change, first check that new commits haven't been made in the upstream's master branch. If there are new commits, rebase your development branch to ensure a fast-forward merge when your Pull Request is approved:
# Fetch upstream master and update your local master branch
git fetch upstream
git checkout master
git merge upstream/master
# Rebase your development branch
git checkout feature
git rebase master
Finally, open a new Pull Request with your changes. Be sure to mention the issues this request addresses in the body of the request. Once your request is opened, a developer will review, comment, and, when approved, merge your changes!
Pull Request Checklist
Before you open that new pull request, make sure to have completed the following checklist:
- Code follows the style guidelines of this project
- I have performed a self-review of my own code
- I have commented my code, particularly in hard-to-understand areas
- I have made corresponding changes to the documentation
- My changes generate no new warnings
- I have added tests that prove my fix is effective or that my feature works
- New and existing unit tests pass locally with my changes
- Any dependent changes have been merged and published in downstream modules