{"id":13459176,"url":"https://github.com/airtap/airtap","last_synced_at":"2025-05-13T19:13:23.813Z","repository":{"id":29291825,"uuid":"121137018","full_name":"airtap/airtap","owner":"airtap","description":"Run TAP unit tests in 1789+ browsers.","archived":false,"fork":false,"pushed_at":"2025-04-01T19:48:24.000Z","size":1309,"stargazers_count":1372,"open_issues_count":8,"forks_count":43,"subscribers_count":18,"default_branch":"main","last_synced_at":"2025-04-25T22:59:58.221Z","etag":null,"topics":["airtap","browsers","javascript","nodejs","npm-package","sauce-labs","sauceconnect","test-anything-protocol","unit-testing","zuul"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/airtap.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-02-11T15:28:08.000Z","updated_at":"2025-01-18T22:33:54.000Z","dependencies_parsed_at":"2024-06-18T12:24:10.374Z","dependency_job_id":"a473ae7b-d9a2-493d-9d86-7cbf647138ae","html_url":"https://github.com/airtap/airtap","commit_stats":{"total_commits":763,"total_committers":60,"mean_commits":"12.716666666666667","dds":0.6631716906946264,"last_synced_commit":"96ed561f2415bb5f92496cc782ef54448e1ac517"},"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/airtap%2Fairtap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/airtap%2Fairtap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/airtap%2Fairtap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/airtap%2Fairtap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/airtap","download_url":"https://codeload.github.com/airtap/airtap/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250907700,"owners_count":21506069,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["airtap","browsers","javascript","nodejs","npm-package","sauce-labs","sauceconnect","test-anything-protocol","unit-testing","zuul"],"created_at":"2024-07-31T09:01:08.428Z","updated_at":"2025-04-25T23:00:03.119Z","avatar_url":"https://github.com/airtap.png","language":"JavaScript","readme":"# airtap\n\n**Run TAP unit tests in 1789+ browsers.** Airtap is a command-line interface to unit test your JavaScript in browsers, using a TAP-producing harness like `tape`. Start testing locally and seamlessly move to browsers in the cloud for full coverage. Airtap runs browsers concurrently and lets you iterate quickly during development. Don't just claim your JavaScript supports \"all browsers\", prove it with tests!\n\n[![npm](https://img.shields.io/npm/v/airtap.svg)](https://www.npmjs.com/package/airtap)\n[![Node version](https://img.shields.io/node/v/airtap.svg)](https://www.npmjs.com/package/airtap)\n[![Test](https://img.shields.io/github/actions/workflow/status/airtap/airtap/test.yml?label=test)](https://github.com/airtap/airtap/actions/workflows/test.yml)\n[![Standard](https://img.shields.io/badge/standard-informational?logo=javascript\\\u0026logoColor=fff)](https://standardjs.com)\n[![Common Changelog](https://common-changelog.org/badge.svg)](https://common-changelog.org)\n\n## Install\n\nWith [npm](https://npmjs.org) do:\n\n```\nnpm install airtap --save-dev\n```\n\nIf you are upgrading or migrating from [`zuul`](https://github.com/defunctzombie/zuul): please see the [upgrade guide](./UPGRADING.md).\n\n## Getting Started\n\nYou'll need an entry point for your tests like `test.js`. For a complete example see [`airtap-demo`](https://github.com/airtap/demo). If you already have an entry point, go ahead and run it with:\n\n```\nairtap test.js\n```\n\nOut of the box, this will launch the default browser on your system. To keep the browser open and automatically reload when you make changes to your test files, run:\n\n```\nairtap --live test.js\n```\n\n### Adding Browsers\n\nIn order to run more browsers, create a `.airtap.yml` file in your working directory, containing at least one provider and browser. For example:\n\n```yaml\nproviders:\n  - airtap-system\n\nbrowsers:\n  - name: chrome\n  - name: ff\n```\n\nProviders discover browsers on a particular platform or remote service. In the above example, [`airtap-system`][airtap-system] finds browsers installed on your machine which Airtap then matches against the specified `browsers`. Providers are npm packages that must be installed separately from the main `airtap` package. So that would be:\n\n```\nnpm install airtap airtap-system --save-dev\n```\n\nYou can include multiple providers and let Airtap find the best matching browser(s):\n\n```yaml\nproviders:\n  - airtap-playwright\n  - airtap-system\n\nbrowsers:\n  - name: ff\n    version: 78\n```\n\nYou can also match browsers by provider:\n\n\u003cdetails\u003e\u003csummary\u003eClick to expand\u003c/summary\u003e\n\n```yaml\nbrowsers:\n  - name: ff\n    provider: airtap-system\n```\n\n\u003c/details\u003e\n\nAirtap, providers and browsers are tied together by [manifests](https://github.com/airtap/browser-manifest). They define the name and other metadata of browsers. You can see these manifests by running `airtap -l` or `-la` which is short for `--list-browsers --all`. For example:\n\n\u003cdetails\u003e\u003csummary\u003eClick to expand\u003c/summary\u003e\n\n```\n$ airtap -la\n- name: electron\n  title: Electron 9.0.5\n  version: 9.0.5\n  options:\n    headless: true\n  provider: airtap-electron\n```\n\n\u003c/details\u003e\n\nAirtap can match browsers on any manifest property, with the exception of `options` which exists to customize the browser behavior. Options are specific to a provider. For example, the `airtap-playwright` provider supports disabling headless mode and setting custom command-line arguments:\n\n```yaml\nbrowsers:\n  - name: chromium\n    options:\n      headless: false\n      launch:\n        args: [--lang=en-US]\n```\n\nFor more information on the `browsers` field, see [Configuration](#configuration).\n\n## Available Providers\n\n| **Package**                              | **Description**                                    |\n| :--------------------------------------- | :------------------------------------------------- |\n| [`airtap-system`][airtap-system]         | Locally installed browsers on Linux, Mac \u0026 Windows |\n| [`airtap-playwright`][airtap-playwright] | Playwright (headless Chromium, FF and WebKit)      |\n| [`airtap-sauce`][airtap-sauce]           | Remote browsers in Sauce Labs                      |\n| [`airtap-electron`][airtap-electron]     | Electron                                           |\n| [`airtap-default`][airtap-default]       | Default browser                                    |\n| [`airtap-manual`][airtap-manual]         | Manually open a URL in a browser of choice         |\n\n## Cloud Testing With Sauce Labs\n\nThe [`airtap-sauce`][airtap-sauce] provider runs browsers on [Sauce Labs](https://saucelabs.com/). Sauce Labs offers quite a few browsers, with a wide range of versions and platforms.\n\n_Open source projects can use the [free for open source](https://saucelabs.com/opensauce) version of Sauce Labs._\n\n### 1. Set Credentials\n\nAirtap needs to know your Sauce Labs credentials. You don't want to commit these sensitive credentials to your git repository. Instead set them via the environment as `SAUCE_USERNAME` and `SAUCE_ACCESS_KEY`.\n\n### 2. Select Browsers\n\nAdd the `airtap-sauce` provider and wanted browsers to `.airtap.yml`:\n\n```yaml\nproviders:\n  - airtap-sauce\n\nbrowsers:\n  - name: chrome\n  - name: ios_saf\n  - name: ie\n```\n\n### 3. Set Hostname\n\nAirtap runs a server to serve JavaScript test files to browsers. The `airtap-sauce` provider establishes a tunnel to your local machine so that Sauce Labs can find that server. For this to work, some browsers need a custom loopback hostname, because they don't route `localhost` through the tunnel. Add the following to your [`hosts`](https://en.wikipedia.org/wiki/Hosts_%28file%29) file:\n\n```\n127.0.0.1 airtap.local\n```\n\nYou are now ready to run your tests in the cloud with `airtap test.js`.\n\n## Continuous Integration\n\nAfter making sure your tests pass when initiated from your local machine, you can setup continuous integration to run your tests whenever changes are committed. Any CI service that supports Node.js will work.\n\n[![Sauce Test Status](https://saucelabs.com/browser-matrix/level-js.svg)](https://saucelabs.com/u/level-js)\n\n### Travis CI\n\n#### 1. Setup Travis\n\nTake a look at the Travis [getting started](http://about.travis-ci.org/docs/user/languages/javascript-with-nodejs/) guide for Node.js. At minimum we need to create a `.travis.yml` file containing:\n\n```yaml\nlanguage: node_js\nnode_js:\n  - 12\naddons:\n  hosts:\n    - airtap.local\n```\n\n#### 2. Add Test Script\n\nAdd the following to your `package.json`:\n\n```json\n{\n  \"scripts\": {\n    \"test\": \"airtap test.js\"\n  }\n}\n```\n\n#### 3. Enable Code Coverage\n\nOptionally enable code coverage with the `--coverage` flag. This will collect code coverage per browser into the `.nyc-output/` folder in [Istanbul](https://istanbul.js.org/) 1.0 format. Afterwards you can generate reports with [`nyc report`](https://github.com/istanbuljs/nyc), which takes care of merging code coverage from multiple browsers.\n\nA typical setup for Travis looks like:\n\n```json\n{\n  \"scripts\": {\n    \"test\": \"airtap --coverage test.js\"\n  }\n}\n```\n\nYou can choose to post the results to [`coveralls`](https://coveralls.io/) (or similar) by adding a step to `.travis.yml`:\n\n```yaml\nafter_success: npm run coverage\n```\n\n```json\n{\n  \"scripts\": {\n    \"test\": \"airtap --coverage test.js\",\n    \"coverage\": \"nyc report --reporter=text-lcov | coveralls\"\n  }\n}\n```\n\n#### 4. Set Credentials\n\nSkip this step if you're not using the [`airtap-sauce`][airtap-sauce] provider. Same as when initiating tests locally, we need to get Sauce Labs credentials to Travis. Luckily Travis has a feature called [secure environment variables](http://about.travis-ci.org/docs/user/build-configuration/#Secure-environment-variables). You'll need to set 2 of those: `SAUCE_USERNAME` and `SAUCE_ACCESS_KEY`.\n\n### GitHub Actions\n\nShould work in theory :)\n\n## CLI\n\nUsage: `airtap [options] \u003cfiles\u003e`. Supports multiple `files`. They can be paths relative to the working directory or glob patterns (e.g. `airtap test/*.js`). Options:\n\n```\n-v --version          Print version and exit\n-l --list-browsers    List (effective or --all) browsers\n-a --all              Test or list all available browsers\n   --coverage         Enable code coverage analysis\n   --live             Keep browsers open to allow repeated test runs\n-c --concurrency \u003cn\u003e  Number of browsers to test concurrently, default 5\n-r --retries \u003cn\u003e      Number of retries when running a browser, default 6\n-t --timeout \u003cn\u003e      How long to wait for test results, default 5m. Can\n                      be a number in milliseconds or a string with unit.\n-p --preset \u003cpreset\u003e  Select a configuration preset\n-s --server \u003cscript\u003e  Path to script that runs a support server\n   --loopback \u003chost\u003e  Custom hostname that equals or resolves to 127.0.0.1\n   --verbose          Enable airtap debug output\n   --silly            Enable all debug output\n-h --help             Print help and exit.\n```\n\n\u003cdetails\u003e\u003csummary\u003eExamples (click to expand)\u003c/summary\u003e\n\nList all available browsers:\n\n```\nairtap -la\n```\n\nTest browsers specified in .airtap.yml:\n\n```\nairtap test.js\n```\n\nTest all available browsers (careful):\n\n```\nairtap -a test.js\n```\n\nTest multiple files:\n\n```\nairtap \"test/*.js\"\n```\n\n\u003c/details\u003e\n\n## Configuration\n\nAirtap consumes a YAML config file at `.airtap.yml` in the working directory. The following fields are available.\n\n### `providers` (array)\n\n### `browsers` (array)\n\nList of browsers to test in the cloud. Each entry should contain a `name` property. Additional properties like `version` and `platform` may be specified depending on the provider.\n\nThe `version` property defaults to `latest` and can be a specific version number, the keyword `latest`, the keyword `oldest`, or (for Firefox and Chrome) one of the keywords `beta`  or `dev`.\n\n```yaml\nbrowsers:\n  - name: chrome\n  - name: firefox\n    version: beta\n```\n\n#### Specific version of a browser on a specific platform\n\nOnly supported by the `airtap-sauce` provider at the time of writing, as other providers do not run browsers on a particular platform.\n\n```yaml\nbrowsers:\n  - name: chrome\n    version: 28\n    platform: Windows XP\n```\n\n#### Range of versions of a browser\n\n```yaml\nbrowsers:\n  - name: firefox\n    version: 14..latest\n  - name: ie\n    version: 9..11\n```\n\n#### Range of versions with negative start index.\n\nThis example would test the latest three stable versions of Firefox (latest - 2, latest - 1, latest).\n\n```yaml\nbrowsers:\n  - name: firefox\n    version: -2..latest\n```\n\n#### Disjoint versions\n\n```yaml\nbrowsers:\n  - name: firefox\n    version: [19, 20]\n```\n\n#### Disjoint with ranges\n\n```yaml\nbrowsers:\n  - name: firefox\n    version: [19, 20, 23..latest]\n  - name: chrome\n    version: [-1..latest, beta]\n```\n\n#### Float version numbers\n\n```yaml\nbrowsers:\n  - name: ios_saf\n    version: '8.0..latest'\n```\n\nFloat version numbers should be quoted.\n\n### `browserify` (array)\n\nYou can set any of the items in the following list, and they'll be passed to [`browserify`](https://github.com/browserify/browserify).\n\n- `plugin`\n- `external`\n- `ignore`\n- `exclude`\n- `transform`\n- `add`\n- `require`\n\nThey can be repeated and accept options.\n\n```yaml\nbrowserify:\n  - require: ./some-file.js\n    expose: intimidate\n  - transform: brfs\n  - transform: jadeify\n```\n\nYou can also customize what's passed to `browserify(options)`.\n\n```yaml\nbrowserify:\n  - options:\n      node: true\n```\n\n#### IE support\n\nTo support Internet Explorer, older versions of the [`buffer`](https://github.com/feross/buffer) and [`stream-browserify`](https://github.com/browserify/stream-browserify) polyfills are required. Use the following configuration and run `npm install buffer@4 stream-browserify@2`:\n\n```yaml\n# Use buffer@4 and stream-browserify@2 to support IE\nbrowserify:\n  - require: 'buffer/'\n    expose: 'buffer'\n  - require: 'stream-browserify'\n    expose: 'stream'\n```\n\nThis is not officially supported. There may be other reasons that IE will not work.\n\n### `server` (string or object)\n\nThis field can point to an optional shell command or JavaScript file to run as a support server. It will be started before all tests and stopped afterwards. This allows testing websockets and other network requests. Your command will be run with the `AIRTAP_SUPPORT_PORT` environment variable set to a port number you must use. If your server does not listen on this port it will be unreachable (on browser providers that use a tunnel).\n\n```yaml\nserver: ./test/support/server.js\n```\n\nWe recommend writing simple support servers using [`http`](https://nodejs.org/api/http.html) or [`express`](http://expressjs.com/). For shell commands you can use `$AIRTAP_SUPPORT_PORT` in the arguments, which will be substituted:\n\n```yaml\nserver: \"python -m SimpleHTTPServer $AIRTAP_SUPPORT_PORT\"\n```\n\n### Firefox Profile\n\nThe [`airtap-sauce`][airtap-sauce] provider supports running Firefox instances with custom user profiles. This allows you to configure anything you can change in `about:config` programmatically for a test run. You can set these options with a section under any Firefox browser entry:\n\n```yaml\nbrowsers:\n  - name: firefox\n    options:\n      profile:\n        webgl.force-enabled: true\n```\n\n## ESM Support\n\nBy default airtap doesn't support ESM, but you can configure it to work with ESM and CJS using the following config:\n```yml\nbrowserify:\n  - transform: babelify\n    global: true\n    presets: ['@babel/preset-env']\n    plugins: ['@babel/plugin-syntax-import-assertions']\n```\nYou'll need to install `babelify`, `@babel/preset-env` and `@babel/plugin-syntax-import-assertions`. Note that other global browserify configs might break this and that the `global` parameter might not be required.\n\n## Who Uses Airtap?\n\n**Lots of folks!** Collectively, packages that depend on Airtap get 100's of millions of downloads per month!\n\n- [`level`](https://github.com/Level/level) (and dependencies)\n- [`webtorrent`](https://github.com/webtorrent/webtorrent) (and dependencies)\n- [`simple-peer`](https://github.com/feross/simple-peer)\n- [`buffer`](https://github.com/feross/buffer)\n- [`stream-http`](https://github.com/jhiesey/stream-http)\n- [`readable-stream`](https://github.com/nodejs/readable-stream)\n- _Send a PR to add your package to the list!_\n\n## Contributing\n\nAirtap is an **OPEN Open Source Project**. This means that:\n\n\u003e Individuals making significant and valuable contributions are given commit-access to the project to contribute as they see fit. This project is more like an open wiki than a standard guarded open source project.\n\nSee the [contribution guide](CONTRIBUTING.md) for more details.\n\n## License\n\nMIT © [Roman Shtylman](https://github.com/defunctzombie), [Zuul contributors](https://github.com/defunctzombie/zuul/graphs/contributors) and [Airtap contributors](https://github.com/airtap).\n\n[airtap-system]: https://github.com/airtap/system\n\n[airtap-playwright]: https://github.com/airtap/playwright\n\n[airtap-sauce]: https://github.com/airtap/sauce\n\n[airtap-electron]: https://github.com/airtap/electron\n\n[airtap-default]: https://github.com/airtap/default\n\n[airtap-manual]: https://github.com/airtap/manual\n","funding_links":[],"categories":["JavaScript","工具"],"sub_categories":["调试"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fairtap%2Fairtap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fairtap%2Fairtap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fairtap%2Fairtap/lists"}