From d9d9407d3559af627d680e2fe789e83f04f117ee Mon Sep 17 00:00:00 2001
From: Jonas Gloning <34194370+jonasgloning@users.noreply.github.com>
Date: Wed, 21 Jun 2023 14:57:31 +0200
Subject: [PATCH] test(e2e): run datachannel serialization tests
---
.github/workflows/browserstack.yml | 39 +
browserstack.err | 1 +
e2e/.eslintrc | 5 +
e2e/alice.html | 5 +
e2e/bob.html | 5 +
e2e/commit_data.js | 1385 ++++
e2e/data.js | 72 +
e2e/datachannel/arraybuffers.js | 37 +
e2e/datachannel/arrays.js | 15 +
e2e/datachannel/arrays_json.js | 19 +
e2e/datachannel/numbers.js | 16 +
e2e/datachannel/objects.js | 16 +
e2e/datachannel/serialization.html | 27 +
e2e/datachannel/serialization.js | 70 +
e2e/datachannel/serialization.page.ts | 71 +
e2e/datachannel/serialization.spec.ts | 34 +
e2e/datachannel/serialization_json.html | 26 +
e2e/datachannel/serialization_json.js | 70 +
e2e/datachannel/serialization_json.spec.ts | 31 +
e2e/datachannel/strings.js | 17 +
e2e/datachannel/strings_json.js | 19 +
e2e/package.json | 3 +
e2e/style.css | 26 +
e2e/tsconfig.json | 70 +
e2e/types.d.ts | 11 +
e2e/wdio.bstack.conf.ts | 71 +
e2e/wdio.local.conf.ts | 23 +
e2e/wdio.shared.conf.ts | 250 +
jest.config.cjs | 1 +
package-lock.json | 7701 +++++++++++++++++++-
package.json | 19 +-
tsconfig.json | 3 +-
32 files changed, 9853 insertions(+), 305 deletions(-)
create mode 100644 .github/workflows/browserstack.yml
create mode 100644 browserstack.err
create mode 100644 e2e/.eslintrc
create mode 100644 e2e/alice.html
create mode 100644 e2e/bob.html
create mode 100644 e2e/commit_data.js
create mode 100644 e2e/data.js
create mode 100644 e2e/datachannel/arraybuffers.js
create mode 100644 e2e/datachannel/arrays.js
create mode 100644 e2e/datachannel/arrays_json.js
create mode 100644 e2e/datachannel/numbers.js
create mode 100644 e2e/datachannel/objects.js
create mode 100644 e2e/datachannel/serialization.html
create mode 100644 e2e/datachannel/serialization.js
create mode 100644 e2e/datachannel/serialization.page.ts
create mode 100644 e2e/datachannel/serialization.spec.ts
create mode 100644 e2e/datachannel/serialization_json.html
create mode 100644 e2e/datachannel/serialization_json.js
create mode 100644 e2e/datachannel/serialization_json.spec.ts
create mode 100644 e2e/datachannel/strings.js
create mode 100644 e2e/datachannel/strings_json.js
create mode 100644 e2e/package.json
create mode 100644 e2e/style.css
create mode 100644 e2e/tsconfig.json
create mode 100644 e2e/types.d.ts
create mode 100644 e2e/wdio.bstack.conf.ts
create mode 100644 e2e/wdio.local.conf.ts
create mode 100644 e2e/wdio.shared.conf.ts
diff --git a/.github/workflows/browserstack.yml b/.github/workflows/browserstack.yml
new file mode 100644
index 000000000..9430f91cf
--- /dev/null
+++ b/.github/workflows/browserstack.yml
@@ -0,0 +1,39 @@
+name: "BrowserStack Test"
+on: [push, pull_request]
+jobs:
+ ubuntu-job:
+ name: "BrowserStack Test on Ubuntu"
+ runs-on: ubuntu-latest # Can be self-hosted runner also
+ steps:
+ - name: "BrowserStack Env Setup" # Invokes the setup-env action
+ uses: browserstack/github-actions/setup-env@master
+ with:
+ username: ${{ secrets.BROWSERSTACK_USERNAME }}
+ access-key: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}
+
+ - name: "BrowserStack Local Tunnel Setup" # Invokes the setup-local action
+ uses: browserstack/github-actions/setup-local@master
+ with:
+ local-testing: start
+ local-identifier: peerjs-${{ github.run_id }}-${{ github.run_attempt }}
+
+ # The next 3 steps are for building the web application to be tested and starting the web server on the runner environment
+
+ - name: "Checkout the repository"
+ uses: actions/checkout@v2
+
+ - name: "Building web application to be tested"
+ run: npm install && npm run build
+
+ - name: "Running application under test"
+ run: npx http-server -p 3000 --cors &
+
+ - name: "Running test on BrowserStack" # Invokes the actual test script that would run on BrowserStack browsers
+ run: npm run e2e:bstack # See sample test script above
+ env:
+ BROWSERSTACK_LOCAL_IDENTIFIER: peerjs-${{ github.run_id }}-${{ github.run_attempt }}
+
+ - name: "BrowserStackLocal Stop" # Terminating the BrowserStackLocal tunnel connection
+ uses: browserstack/github-actions/setup-local@master
+ with:
+ local-testing: stop
diff --git a/browserstack.err b/browserstack.err
new file mode 100644
index 000000000..a6e141486
--- /dev/null
+++ b/browserstack.err
@@ -0,0 +1 @@
+[object Object]
\ No newline at end of file
diff --git a/e2e/.eslintrc b/e2e/.eslintrc
new file mode 100644
index 000000000..bb7dd23eb
--- /dev/null
+++ b/e2e/.eslintrc
@@ -0,0 +1,5 @@
+{
+ "env": {
+ "browser": true
+ }
+}
diff --git a/e2e/alice.html b/e2e/alice.html
new file mode 100644
index 000000000..96430e8eb
--- /dev/null
+++ b/e2e/alice.html
@@ -0,0 +1,5 @@
+
+
+ Alice
+
+
diff --git a/e2e/bob.html b/e2e/bob.html
new file mode 100644
index 000000000..00a8ea492
--- /dev/null
+++ b/e2e/bob.html
@@ -0,0 +1,5 @@
+
+
+ Bob
+
+
diff --git a/e2e/commit_data.js b/e2e/commit_data.js
new file mode 100644
index 000000000..e34736003
--- /dev/null
+++ b/e2e/commit_data.js
@@ -0,0 +1,1385 @@
+export const commit_data = [
+ {
+ created_at: "2013-11-07T19:41:25-08:00",
+ payload: { issue_id: 22111847, comment_id: 28032260 },
+ public: true,
+ type: "IssueCommentEvent",
+ url: "https://github.com/peers/peerjs/issues/101#issuecomment-28032260",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 7292898,
+ name: "peerjs",
+ url: "https://github.com/peers/peerjs",
+ description: "Peer-to-peer data in the browser.",
+ homepage: "https://peerjs.com",
+ watchers: 1647,
+ stargazers: 1647,
+ forks: 145,
+ fork: false,
+ size: 2188,
+ owner: "peers",
+ private: false,
+ open_issues: 20,
+ has_issues: true,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2012-12-22T23:28:47-08:00",
+ pushed_at: "2013-11-09T22:58:31-08:00",
+ master_branch: "master",
+ organization: "peers",
+ },
+ },
+ {
+ created_at: "2013-11-07T19:35:50-08:00",
+ payload: { issue_id: 22196839, comment_id: 28031970 },
+ public: true,
+ type: "IssueCommentEvent",
+ url: "https://github.com/peers/peerjs/issues/103#issuecomment-28031970",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 7292898,
+ name: "peerjs",
+ url: "https://github.com/peers/peerjs",
+ description: "Peer-to-peer data in the browser.",
+ homepage: "https://peerjs.com",
+ watchers: 1647,
+ stargazers: 1647,
+ forks: 145,
+ fork: false,
+ size: 2188,
+ owner: "peers",
+ private: false,
+ open_issues: 20,
+ has_issues: true,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2012-12-22T23:28:47-08:00",
+ pushed_at: "2013-11-09T22:58:31-08:00",
+ master_branch: "master",
+ organization: "peers",
+ },
+ },
+ {
+ created_at: "2013-11-02T15:18:51-07:00",
+ payload: {
+ ref: "0.3.3",
+ ref_type: "tag",
+ master_branch: "master",
+ description: "Peer-to-peer data in the browser.",
+ },
+ public: true,
+ type: "CreateEvent",
+ url: "https://github.com/peers/peerjs/tree/0.3.3",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 7292898,
+ name: "peerjs",
+ url: "https://github.com/peers/peerjs",
+ description: "Peer-to-peer data in the browser.",
+ homepage: "https://peerjs.com",
+ watchers: 1647,
+ stargazers: 1647,
+ forks: 145,
+ fork: false,
+ size: 2188,
+ owner: "peers",
+ private: false,
+ open_issues: 20,
+ has_issues: true,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2012-12-22T23:28:47-08:00",
+ pushed_at: "2013-11-09T22:58:31-08:00",
+ master_branch: "master",
+ organization: "peers",
+ },
+ },
+ {
+ created_at: "2013-11-02T15:18:49-07:00",
+ payload: {
+ shas: [
+ [
+ "9976990c61c0f9c3c44f1de2a997ff8f21013d2a",
+ "really.ez@gmail.com",
+ "Bump to 0.3.3",
+ "ericz",
+ true,
+ ],
+ ],
+ size: 1,
+ ref: "refs/heads/master",
+ head: "9976990c61c0f9c3c44f1de2a997ff8f21013d2a",
+ },
+ public: true,
+ type: "PushEvent",
+ url: "https://github.com/peers/peerjs/compare/c9adf5076e...9976990c61",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 7292898,
+ name: "peerjs",
+ url: "https://github.com/peers/peerjs",
+ description: "Peer-to-peer data in the browser.",
+ homepage: "https://peerjs.com",
+ watchers: 1647,
+ stargazers: 1647,
+ forks: 145,
+ fork: false,
+ size: 2188,
+ owner: "peers",
+ private: false,
+ open_issues: 20,
+ has_issues: true,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2012-12-22T23:28:47-08:00",
+ pushed_at: "2013-11-09T22:58:31-08:00",
+ master_branch: "master",
+ organization: "peers",
+ },
+ },
+ {
+ created_at: "2013-11-02T15:15:18-07:00",
+ payload: {
+ shas: [
+ [
+ "ec1424c0f264ea5d8ce08ac2cc9ea2bd027a6a71",
+ "really.ez@gmail.com",
+ "Errant comma",
+ "ericz",
+ true,
+ ],
+ [
+ "c9adf5076ea41df60231e11d032f371939228609",
+ "really.ez@gmail.com",
+ "Dont throw exception on failures",
+ "ericz",
+ true,
+ ],
+ ],
+ size: 2,
+ ref: "refs/heads/master",
+ head: "c9adf5076ea41df60231e11d032f371939228609",
+ },
+ public: true,
+ type: "PushEvent",
+ url: "https://github.com/peers/peerjs/compare/bb1045bf92...c9adf5076e",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 7292898,
+ name: "peerjs",
+ url: "https://github.com/peers/peerjs",
+ description: "Peer-to-peer data in the browser.",
+ homepage: "https://peerjs.com",
+ watchers: 1647,
+ stargazers: 1647,
+ forks: 145,
+ fork: false,
+ size: 2188,
+ owner: "peers",
+ private: false,
+ open_issues: 20,
+ has_issues: true,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2012-12-22T23:28:47-08:00",
+ pushed_at: "2013-11-09T22:58:31-08:00",
+ master_branch: "master",
+ organization: "peers",
+ },
+ },
+ {
+ created_at: "2013-11-02T15:02:02-07:00",
+ payload: {
+ shas: [
+ [
+ "bb1045bf92fbaef6e2156c3ac47015f70af5d866",
+ "really.ez@gmail.com",
+ "Fix errant comma",
+ "ericz",
+ true,
+ ],
+ ],
+ size: 1,
+ ref: "refs/heads/master",
+ head: "bb1045bf92fbaef6e2156c3ac47015f70af5d866",
+ },
+ public: true,
+ type: "PushEvent",
+ url: "https://github.com/peers/peerjs/compare/2db1c59998...bb1045bf92",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 7292898,
+ name: "peerjs",
+ url: "https://github.com/peers/peerjs",
+ description: "Peer-to-peer data in the browser.",
+ homepage: "https://peerjs.com",
+ watchers: 1647,
+ stargazers: 1647,
+ forks: 145,
+ fork: false,
+ size: 2188,
+ owner: "peers",
+ private: false,
+ open_issues: 20,
+ has_issues: true,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2012-12-22T23:28:47-08:00",
+ pushed_at: "2013-11-09T22:58:31-08:00",
+ master_branch: "master",
+ organization: "peers",
+ },
+ },
+ {
+ created_at: "2013-11-02T14:56:14-07:00",
+ payload: {
+ shas: [
+ [
+ "2db1c599987753079d197f73272a9e40e9290f73",
+ "really.ez@gmail.com",
+ "Remove errant comma",
+ "ericz",
+ true,
+ ],
+ ],
+ size: 1,
+ ref: "refs/heads/master",
+ head: "2db1c599987753079d197f73272a9e40e9290f73",
+ },
+ public: true,
+ type: "PushEvent",
+ url: "https://github.com/peers/peerjs/compare/214a14cc10...2db1c59998",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 7292898,
+ name: "peerjs",
+ url: "https://github.com/peers/peerjs",
+ description: "Peer-to-peer data in the browser.",
+ homepage: "https://peerjs.com",
+ watchers: 1647,
+ stargazers: 1647,
+ forks: 145,
+ fork: false,
+ size: 2188,
+ owner: "peers",
+ private: false,
+ open_issues: 20,
+ has_issues: true,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2012-12-22T23:28:47-08:00",
+ pushed_at: "2013-11-09T22:58:31-08:00",
+ master_branch: "master",
+ organization: "peers",
+ },
+ },
+ {
+ created_at: "2013-11-02T14:56:13-07:00",
+ payload: {
+ shas: [
+ [
+ "841921c349aff234b022bb966774d00ae22fef5e",
+ "really.ez@gmail.com",
+ "Errant comma",
+ "ericz",
+ true,
+ ],
+ ],
+ size: 1,
+ ref: "refs/heads/better-supports",
+ head: "841921c349aff234b022bb966774d00ae22fef5e",
+ },
+ public: true,
+ type: "PushEvent",
+ url: "https://github.com/peers/peerjs/compare/ccd80612ae...841921c349",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 7292898,
+ name: "peerjs",
+ url: "https://github.com/peers/peerjs",
+ description: "Peer-to-peer data in the browser.",
+ homepage: "https://peerjs.com",
+ watchers: 1647,
+ stargazers: 1647,
+ forks: 145,
+ fork: false,
+ size: 2188,
+ owner: "peers",
+ private: false,
+ open_issues: 20,
+ has_issues: true,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2012-12-22T23:28:47-08:00",
+ pushed_at: "2013-11-09T22:58:31-08:00",
+ master_branch: "master",
+ organization: "peers",
+ },
+ },
+ {
+ created_at: "2013-11-01T11:41:34-07:00",
+ payload: {
+ shas: [
+ [
+ "37350aaef3763d5a1bc63c4903f0f34ea9780d36",
+ "really.ez@gmail.com",
+ "Fix",
+ "Eric Zhang",
+ true,
+ ],
+ ],
+ size: 1,
+ ref: "refs/heads/master",
+ head: "37350aaef3763d5a1bc63c4903f0f34ea9780d36",
+ },
+ public: true,
+ type: "PushEvent",
+ url: "https://github.com/HackBerkeley/ascam/compare/7d76223acc...37350aaef3",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 5557070,
+ name: "ascam",
+ url: "https://github.com/HackBerkeley/ascam",
+ description: "Ascii Webcam",
+ homepage: "",
+ watchers: 1,
+ stargazers: 1,
+ forks: 1,
+ fork: true,
+ size: 1973,
+ owner: "HackBerkeley",
+ private: false,
+ open_issues: 0,
+ has_issues: false,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2012-08-25T20:19:01-07:00",
+ pushed_at: "2013-11-01T11:41:33-07:00",
+ master_branch: "master",
+ organization: "HackBerkeley",
+ },
+ },
+ {
+ created_at: "2013-10-31T10:56:20-07:00",
+ payload: { issue_id: 13813188, comment_id: 27509702 },
+ public: true,
+ type: "IssueCommentEvent",
+ url: "https://github.com/peers/peerjs/pull/45#issuecomment-27509702",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 7292898,
+ name: "peerjs",
+ url: "https://github.com/peers/peerjs",
+ description: "Peer-to-peer data in the browser.",
+ homepage: "https://peerjs.com",
+ watchers: 1647,
+ stargazers: 1647,
+ forks: 145,
+ fork: false,
+ size: 2188,
+ owner: "peers",
+ private: false,
+ open_issues: 20,
+ has_issues: true,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2012-12-22T23:28:47-08:00",
+ pushed_at: "2013-11-09T22:58:31-08:00",
+ master_branch: "master",
+ organization: "peers",
+ },
+ },
+ {
+ created_at: "2013-10-26T22:53:49-07:00",
+ payload: { issue_id: 21646195, comment_id: 27163465 },
+ public: true,
+ type: "IssueCommentEvent",
+ url: "https://github.com/peers/peerjs-server/issues/25#issuecomment-27163465",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 7452705,
+ name: "peerjs-server",
+ url: "https://github.com/peers/peerjs-server",
+ description: "Server for PeerJS",
+ homepage: "https://peerjs.com",
+ watchers: 328,
+ stargazers: 328,
+ forks: 56,
+ fork: false,
+ size: 389,
+ owner: "peers",
+ private: false,
+ open_issues: 12,
+ has_issues: true,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2013-01-04T22:49:08-08:00",
+ pushed_at: "2013-10-24T00:40:28-07:00",
+ master_branch: "master",
+ organization: "peers",
+ },
+ },
+ {
+ created_at: "2013-10-25T11:04:07-07:00",
+ payload: { action: "closed", issue: 16608955, number: 68 },
+ public: true,
+ type: "IssuesEvent",
+ url: "https://github.com/peers/peerjs/issues/68",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 7292898,
+ name: "peerjs",
+ url: "https://github.com/peers/peerjs",
+ description: "Peer-to-peer data in the browser.",
+ homepage: "https://peerjs.com",
+ watchers: 1647,
+ stargazers: 1647,
+ forks: 145,
+ fork: false,
+ size: 2188,
+ owner: "peers",
+ private: false,
+ open_issues: 20,
+ has_issues: true,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2012-12-22T23:28:47-08:00",
+ pushed_at: "2013-11-09T22:58:31-08:00",
+ master_branch: "master",
+ organization: "peers",
+ },
+ },
+ {
+ created_at: "2013-10-25T11:02:50-07:00",
+ payload: { issue_id: 21379154, comment_id: 27113277 },
+ public: true,
+ type: "IssueCommentEvent",
+ url: "https://github.com/peers/peerjs/issues/91#issuecomment-27113277",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 7292898,
+ name: "peerjs",
+ url: "https://github.com/peers/peerjs",
+ description: "Peer-to-peer data in the browser.",
+ homepage: "https://peerjs.com",
+ watchers: 1647,
+ stargazers: 1647,
+ forks: 145,
+ fork: false,
+ size: 2188,
+ owner: "peers",
+ private: false,
+ open_issues: 20,
+ has_issues: true,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2012-12-22T23:28:47-08:00",
+ pushed_at: "2013-11-09T22:58:31-08:00",
+ master_branch: "master",
+ organization: "peers",
+ },
+ },
+ {
+ created_at: "2013-10-25T11:01:53-07:00",
+ payload: { action: "closed", issue: 21531959, number: 96 },
+ public: true,
+ type: "IssuesEvent",
+ url: "https://github.com/peers/peerjs/issues/96",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 7292898,
+ name: "peerjs",
+ url: "https://github.com/peers/peerjs",
+ description: "Peer-to-peer data in the browser.",
+ homepage: "https://peerjs.com",
+ watchers: 1647,
+ stargazers: 1647,
+ forks: 145,
+ fork: false,
+ size: 2188,
+ owner: "peers",
+ private: false,
+ open_issues: 20,
+ has_issues: true,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2012-12-22T23:28:47-08:00",
+ pushed_at: "2013-11-09T22:58:31-08:00",
+ master_branch: "master",
+ organization: "peers",
+ },
+ },
+ {
+ created_at: "2013-10-25T11:01:25-07:00",
+ payload: { issue_id: 21379154, comment_id: 27113184 },
+ public: true,
+ type: "IssueCommentEvent",
+ url: "https://github.com/peers/peerjs/issues/91#issuecomment-27113184",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 7292898,
+ name: "peerjs",
+ url: "https://github.com/peers/peerjs",
+ description: "Peer-to-peer data in the browser.",
+ homepage: "https://peerjs.com",
+ watchers: 1647,
+ stargazers: 1647,
+ forks: 145,
+ fork: false,
+ size: 2188,
+ owner: "peers",
+ private: false,
+ open_issues: 20,
+ has_issues: true,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2012-12-22T23:28:47-08:00",
+ pushed_at: "2013-11-09T22:58:31-08:00",
+ master_branch: "master",
+ organization: "peers",
+ },
+ },
+ {
+ created_at: "2013-10-25T10:42:32-07:00",
+ payload: { issue_id: 21531959, comment_id: 27111740 },
+ public: true,
+ type: "IssueCommentEvent",
+ url: "https://github.com/peers/peerjs/issues/96#issuecomment-27111740",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 7292898,
+ name: "peerjs",
+ url: "https://github.com/peers/peerjs",
+ description: "Peer-to-peer data in the browser.",
+ homepage: "https://peerjs.com",
+ watchers: 1647,
+ stargazers: 1647,
+ forks: 145,
+ fork: false,
+ size: 2188,
+ owner: "peers",
+ private: false,
+ open_issues: 20,
+ has_issues: true,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2012-12-22T23:28:47-08:00",
+ pushed_at: "2013-11-09T22:58:31-08:00",
+ master_branch: "master",
+ organization: "peers",
+ },
+ },
+ {
+ created_at: "2013-10-25T10:42:13-07:00",
+ payload: { issue_id: 21531959, comment_id: 27111710 },
+ public: true,
+ type: "IssueCommentEvent",
+ url: "https://github.com/peers/peerjs/issues/96#issuecomment-27111710",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 7292898,
+ name: "peerjs",
+ url: "https://github.com/peers/peerjs",
+ description: "Peer-to-peer data in the browser.",
+ homepage: "https://peerjs.com",
+ watchers: 1647,
+ stargazers: 1647,
+ forks: 145,
+ fork: false,
+ size: 2188,
+ owner: "peers",
+ private: false,
+ open_issues: 20,
+ has_issues: true,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2012-12-22T23:28:47-08:00",
+ pushed_at: "2013-11-09T22:58:31-08:00",
+ master_branch: "master",
+ organization: "peers",
+ },
+ },
+ {
+ created_at: "2013-10-25T10:36:48-07:00",
+ payload: { issue_id: 21568882, comment_id: 27111312 },
+ public: true,
+ type: "IssueCommentEvent",
+ url: "https://github.com/peers/peerjs/issues/97#issuecomment-27111312",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 7292898,
+ name: "peerjs",
+ url: "https://github.com/peers/peerjs",
+ description: "Peer-to-peer data in the browser.",
+ homepage: "https://peerjs.com",
+ watchers: 1647,
+ stargazers: 1647,
+ forks: 145,
+ fork: false,
+ size: 2188,
+ owner: "peers",
+ private: false,
+ open_issues: 20,
+ has_issues: true,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2012-12-22T23:28:47-08:00",
+ pushed_at: "2013-11-09T22:58:31-08:00",
+ master_branch: "master",
+ organization: "peers",
+ },
+ },
+ {
+ created_at: "2013-10-23T15:52:46-07:00",
+ payload: { issue_id: 21487688, comment_id: 26953214 },
+ public: true,
+ type: "IssueCommentEvent",
+ url: "https://github.com/peers/peerjs/issues/95#issuecomment-26953214",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 7292898,
+ name: "peerjs",
+ url: "https://github.com/peers/peerjs",
+ description: "Peer-to-peer data in the browser.",
+ homepage: "https://peerjs.com",
+ watchers: 1647,
+ stargazers: 1647,
+ forks: 145,
+ fork: false,
+ size: 2188,
+ owner: "peers",
+ private: false,
+ open_issues: 20,
+ has_issues: true,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2012-12-22T23:28:47-08:00",
+ pushed_at: "2013-11-09T22:58:31-08:00",
+ master_branch: "master",
+ organization: "peers",
+ },
+ },
+ {
+ created_at: "2013-10-22T20:07:24-07:00",
+ payload: { action: "opened", issue: 21431237, number: 93 },
+ public: true,
+ type: "IssuesEvent",
+ url: "https://github.com/peers/peerjs/issues/93",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 7292898,
+ name: "peerjs",
+ url: "https://github.com/peers/peerjs",
+ description: "Peer-to-peer data in the browser.",
+ homepage: "https://peerjs.com",
+ watchers: 1647,
+ stargazers: 1647,
+ forks: 145,
+ fork: false,
+ size: 2188,
+ owner: "peers",
+ private: false,
+ open_issues: 20,
+ has_issues: true,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2012-12-22T23:28:47-08:00",
+ pushed_at: "2013-11-09T22:58:31-08:00",
+ master_branch: "master",
+ organization: "peers",
+ },
+ },
+ {
+ created_at: "2013-10-22T19:15:46-07:00",
+ payload: { issue_id: 21259595, comment_id: 26875922 },
+ public: true,
+ type: "IssueCommentEvent",
+ url: "https://github.com/peers/peerjs/issues/89#issuecomment-26875922",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 7292898,
+ name: "peerjs",
+ url: "https://github.com/peers/peerjs",
+ description: "Peer-to-peer data in the browser.",
+ homepage: "https://peerjs.com",
+ watchers: 1647,
+ stargazers: 1647,
+ forks: 145,
+ fork: false,
+ size: 2188,
+ owner: "peers",
+ private: false,
+ open_issues: 20,
+ has_issues: true,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2012-12-22T23:28:47-08:00",
+ pushed_at: "2013-11-09T22:58:31-08:00",
+ master_branch: "master",
+ organization: "peers",
+ },
+ },
+ {
+ created_at: "2013-10-22T19:06:59-07:00",
+ payload: { issue_id: 20917093, comment_id: 26875655 },
+ public: true,
+ type: "IssueCommentEvent",
+ url: "https://github.com/peers/peerjs/issues/86#issuecomment-26875655",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 7292898,
+ name: "peerjs",
+ url: "https://github.com/peers/peerjs",
+ description: "Peer-to-peer data in the browser.",
+ homepage: "https://peerjs.com",
+ watchers: 1647,
+ stargazers: 1647,
+ forks: 145,
+ fork: false,
+ size: 2188,
+ owner: "peers",
+ private: false,
+ open_issues: 20,
+ has_issues: true,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2012-12-22T23:28:47-08:00",
+ pushed_at: "2013-11-09T22:58:31-08:00",
+ master_branch: "master",
+ organization: "peers",
+ },
+ },
+ {
+ created_at: "2013-10-22T10:42:17-07:00",
+ payload: { issue_id: 21337614, comment_id: 26824752 },
+ public: true,
+ type: "IssueCommentEvent",
+ url: "https://github.com/peers/peerjs/issues/90#issuecomment-26824752",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 7292898,
+ name: "peerjs",
+ url: "https://github.com/peers/peerjs",
+ description: "Peer-to-peer data in the browser.",
+ homepage: "https://peerjs.com",
+ watchers: 1647,
+ stargazers: 1647,
+ forks: 145,
+ fork: false,
+ size: 2188,
+ owner: "peers",
+ private: false,
+ open_issues: 20,
+ has_issues: true,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2012-12-22T23:28:47-08:00",
+ pushed_at: "2013-11-09T22:58:31-08:00",
+ master_branch: "master",
+ organization: "peers",
+ },
+ },
+ {
+ created_at: "2013-10-21T21:00:18-07:00",
+ payload: { issue_id: 21337614, comment_id: 26775684 },
+ public: true,
+ type: "IssueCommentEvent",
+ url: "https://github.com/peers/peerjs/issues/90#issuecomment-26775684",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 7292898,
+ name: "peerjs",
+ url: "https://github.com/peers/peerjs",
+ description: "Peer-to-peer data in the browser.",
+ homepage: "https://peerjs.com",
+ watchers: 1647,
+ stargazers: 1647,
+ forks: 145,
+ fork: false,
+ size: 2188,
+ owner: "peers",
+ private: false,
+ open_issues: 20,
+ has_issues: true,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2012-12-22T23:28:47-08:00",
+ pushed_at: "2013-11-09T22:58:31-08:00",
+ master_branch: "master",
+ organization: "peers",
+ },
+ },
+ {
+ created_at: "2013-10-19T02:06:52-07:00",
+ payload: {
+ ref: "0.3.1",
+ ref_type: "tag",
+ master_branch: "master",
+ description: "Peer-to-peer data in the browser.",
+ },
+ public: true,
+ type: "CreateEvent",
+ url: "https://github.com/peers/peerjs/tree/0.3.1",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 7292898,
+ name: "peerjs",
+ url: "https://github.com/peers/peerjs",
+ description: "Peer-to-peer data in the browser.",
+ homepage: "https://peerjs.com",
+ watchers: 1647,
+ stargazers: 1647,
+ forks: 145,
+ fork: false,
+ size: 2188,
+ owner: "peers",
+ private: false,
+ open_issues: 20,
+ has_issues: true,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2012-12-22T23:28:47-08:00",
+ pushed_at: "2013-11-09T22:58:31-08:00",
+ master_branch: "master",
+ organization: "peers",
+ },
+ },
+ {
+ created_at: "2013-10-19T02:06:43-07:00",
+ payload: { ref: "0.3.1", ref_type: "tag" },
+ public: true,
+ type: "DeleteEvent",
+ url: "https://github.com/",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 7292898,
+ name: "peerjs",
+ url: "https://github.com/peers/peerjs",
+ description: "Peer-to-peer data in the browser.",
+ homepage: "https://peerjs.com",
+ watchers: 1647,
+ stargazers: 1647,
+ forks: 145,
+ fork: false,
+ size: 2188,
+ owner: "peers",
+ private: false,
+ open_issues: 20,
+ has_issues: true,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2012-12-22T23:28:47-08:00",
+ pushed_at: "2013-11-09T22:58:31-08:00",
+ master_branch: "master",
+ organization: "peers",
+ },
+ },
+ {
+ created_at: "2013-10-19T02:05:42-07:00",
+ payload: {
+ shas: [
+ [
+ "720eb3e881220f78eaca3d715ce7afe9324d1a3e",
+ "really.ez@gmail.com",
+ "0.3.1",
+ "ericz",
+ true,
+ ],
+ [
+ "79e10688c56524479f3b2c0cb069c4ac7e065b57",
+ "really.ez@gmail.com",
+ "Set maxRetransmits to 0 when reliable false",
+ "ericz",
+ true,
+ ],
+ ],
+ size: 2,
+ ref: "refs/heads/master",
+ head: "79e10688c56524479f3b2c0cb069c4ac7e065b57",
+ },
+ public: true,
+ type: "PushEvent",
+ url: "https://github.com/peers/peerjs/compare/b474a4cba6...79e10688c5",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 7292898,
+ name: "peerjs",
+ url: "https://github.com/peers/peerjs",
+ description: "Peer-to-peer data in the browser.",
+ homepage: "https://peerjs.com",
+ watchers: 1647,
+ stargazers: 1647,
+ forks: 145,
+ fork: false,
+ size: 2188,
+ owner: "peers",
+ private: false,
+ open_issues: 20,
+ has_issues: true,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2012-12-22T23:28:47-08:00",
+ pushed_at: "2013-11-09T22:58:31-08:00",
+ master_branch: "master",
+ organization: "peers",
+ },
+ },
+ {
+ created_at: "2013-10-19T02:02:15-07:00",
+ payload: {
+ ref: "0.3.1",
+ ref_type: "tag",
+ master_branch: "master",
+ description: "Peer-to-peer data in the browser.",
+ },
+ public: true,
+ type: "CreateEvent",
+ url: "https://github.com/peers/peerjs/tree/0.3.1",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 7292898,
+ name: "peerjs",
+ url: "https://github.com/peers/peerjs",
+ description: "Peer-to-peer data in the browser.",
+ homepage: "https://peerjs.com",
+ watchers: 1647,
+ stargazers: 1647,
+ forks: 145,
+ fork: false,
+ size: 2188,
+ owner: "peers",
+ private: false,
+ open_issues: 20,
+ has_issues: true,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2012-12-22T23:28:47-08:00",
+ pushed_at: "2013-11-09T22:58:31-08:00",
+ master_branch: "master",
+ organization: "peers",
+ },
+ },
+ {
+ created_at: "2013-10-19T02:02:13-07:00",
+ payload: {
+ shas: [
+ [
+ "b474a4cba6156dabd1312cd25a520b4286e362f6",
+ "really.ez@gmail.com",
+ "Setting reliable to false by default",
+ "ericz",
+ true,
+ ],
+ ],
+ size: 1,
+ ref: "refs/heads/master",
+ head: "b474a4cba6156dabd1312cd25a520b4286e362f6",
+ },
+ public: true,
+ type: "PushEvent",
+ url: "https://github.com/peers/peerjs/compare/93fc4931b2...b474a4cba6",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 7292898,
+ name: "peerjs",
+ url: "https://github.com/peers/peerjs",
+ description: "Peer-to-peer data in the browser.",
+ homepage: "https://peerjs.com",
+ watchers: 1647,
+ stargazers: 1647,
+ forks: 145,
+ fork: false,
+ size: 2188,
+ owner: "peers",
+ private: false,
+ open_issues: 20,
+ has_issues: true,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2012-12-22T23:28:47-08:00",
+ pushed_at: "2013-11-09T22:58:31-08:00",
+ master_branch: "master",
+ organization: "peers",
+ },
+ },
+ {
+ created_at: "2013-10-19T01:53:16-07:00",
+ payload: {
+ shas: [
+ [
+ "3949c236345171987b9291059fbaf9024eeca680",
+ "really.ez@gmail.com",
+ "0.3.1",
+ "ericz",
+ true,
+ ],
+ [
+ "93fc4931b24c0261c5fda71e0441a5ee8bda70b2",
+ "really.ez@gmail.com",
+ "Update reliable doc",
+ "ericz",
+ true,
+ ],
+ ],
+ size: 2,
+ ref: "refs/heads/master",
+ head: "93fc4931b24c0261c5fda71e0441a5ee8bda70b2",
+ },
+ public: true,
+ type: "PushEvent",
+ url: "https://github.com/peers/peerjs/compare/cd287e2fae...93fc4931b2",
+ actor: "ericz",
+ actor_attributes: {
+ login: "ericz",
+ type: "User",
+ gravatar_id: "c584ef7fe434331f7068ea49cacd88b9",
+ name: "Eric Zhang",
+ company: "Lever",
+ blog: "https://twitter.com/reallyez",
+ location: "Berkeley",
+ email: "eric@ericzhang.com",
+ },
+ repository: {
+ id: 7292898,
+ name: "peerjs",
+ url: "https://github.com/peers/peerjs",
+ description: "Peer-to-peer data in the browser.",
+ homepage: "https://peerjs.com",
+ watchers: 1647,
+ stargazers: 1647,
+ forks: 145,
+ fork: false,
+ size: 2188,
+ owner: "peers",
+ private: false,
+ open_issues: 20,
+ has_issues: true,
+ has_downloads: true,
+ has_wiki: true,
+ language: "JavaScript",
+ created_at: "2012-12-22T23:28:47-08:00",
+ pushed_at: "2013-11-09T22:58:31-08:00",
+ master_branch: "master",
+ organization: "peers",
+ },
+ },
+];
diff --git a/e2e/data.js b/e2e/data.js
new file mode 100644
index 000000000..004e52574
--- /dev/null
+++ b/e2e/data.js
@@ -0,0 +1,72 @@
+export const numbers = [
+ 0,
+ 1,
+ -1,
+ //
+ Math.PI,
+ -Math.PI,
+ //8 bit
+ 0x7f,
+ 0x0f,
+ //16 bit
+ 0x7fff,
+ 0x0fff,
+ //32 bit
+ 0x7fffffff,
+ 0x0fffffff,
+ //64 bit
+ // 0x7FFFFFFFFFFFFFFF,
+ // eslint-disable-next-line no-loss-of-precision
+ 0x0fffffffffffffff,
+];
+export const long_string = "ThisIsÁTèstString".repeat(100000);
+export const strings = [
+ "",
+ "hello",
+ "café",
+ "中文",
+ "broccoli🥦līp𨋢grin😃ok",
+ "\u{10ffff}",
+];
+
+export { commit_data } from "./commit_data.js";
+
+export const typed_arrays = [
+ new Uint8Array(),
+ new Uint8Array([0]),
+ new Uint8Array([0, 1, 2, 3, 4, 6, 7]),
+ new Uint8Array([0, 1, 2, 3, 4, 6, 78, 9, 10, 11, 12, 13, 14, 15]),
+ new Uint8Array([
+ 0, 1, 2, 3, 4, 6, 78, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 30, 31,
+ ]),
+ new Int32Array([0].map((x) => -x)),
+ new Int32Array([0, 1, 2, 3, 4, 6, 7].map((x) => -x)),
+ new Int32Array(
+ [0, 1, 2, 3, 4, 6, 78, 9, 10, 11, 12, 13, 14, 15].map((x) => -x),
+ ),
+ new Int32Array(
+ [
+ 0, 1, 2, 3, 4, 6, 78, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 30, 31,
+ ].map((x) => -x),
+ ),
+];
+
+export const typed_array_view = new Uint8Array(typed_arrays[6].buffer, 4);
+
+export const array_buffers = [
+ new Uint8Array(),
+ new Uint8Array([0]),
+ new Uint8Array([0, 1, 2, 3, 4, 6, 7]),
+ new Uint8Array([0, 1, 2, 3, 4, 6, 78, 9, 10, 11, 12, 13, 14, 15]),
+ new Uint8Array([
+ 0, 1, 2, 3, 4, 6, 78, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 30, 31,
+ ]),
+].map((x) => x.buffer);
+
+export const dates = [
+ new Date(Date.UTC(2024, 1, 1, 1, 1, 1, 1)),
+ new Date(Date.UTC(1, 1, 1, 1, 1, 1, 1)),
+];
diff --git a/e2e/datachannel/arraybuffers.js b/e2e/datachannel/arraybuffers.js
new file mode 100644
index 000000000..5147891b2
--- /dev/null
+++ b/e2e/datachannel/arraybuffers.js
@@ -0,0 +1,37 @@
+import { typed_arrays, typed_array_view, array_buffers } from "../data.js";
+import { expect } from "https://esm.sh/v126/chai@4.3.7/X-dHMvZXhwZWN0/es2021/chai.bundle.mjs";
+
+/** @param {unknown[]} received */
+window.check = (received) => {
+ for (const [i, typed_array] of typed_arrays.entries()) {
+ expect(received[i]).to.be.an.instanceof(ArrayBuffer);
+ expect(received[i]).to.deep.equal(typed_array.buffer);
+ }
+ for (const [i, array_buffer] of array_buffers.entries()) {
+ expect(received[typed_arrays.length + i]).to.be.an.instanceof(ArrayBuffer);
+ expect(received[typed_arrays.length + i]).to.deep.equal(array_buffer);
+ }
+
+ const received_typed_array_view =
+ received[typed_arrays.length + array_buffers.length];
+ expect(new Uint8Array(received_typed_array_view)).to.deep.equal(
+ typed_array_view,
+ );
+ for (const [i, v] of new Uint8Array(received_typed_array_view).entries()) {
+ expect(v).to.deep.equal(typed_array_view[i]);
+ }
+};
+/**
+ * @param {import("../peerjs").DataConnection} dataConnection
+ */
+window.send = (dataConnection) => {
+ for (const typed_array of typed_arrays) {
+ dataConnection.send(typed_array);
+ }
+ for (const array_buffer of array_buffers) {
+ dataConnection.send(array_buffer);
+ }
+ dataConnection.send(typed_array_view);
+};
+
+window["connect-btn"].disabled = false;
diff --git a/e2e/datachannel/arrays.js b/e2e/datachannel/arrays.js
new file mode 100644
index 000000000..015fbe060
--- /dev/null
+++ b/e2e/datachannel/arrays.js
@@ -0,0 +1,15 @@
+import { commit_data } from "../data.js";
+import { expect } from "https://esm.sh/v126/chai@4.3.7/X-dHMvZXhwZWN0/es2021/chai.bundle.mjs";
+
+/** @param {unknown[]} received */
+window.check = (received) => {
+ expect(received).to.deep.equal([[], commit_data]);
+};
+/**
+ * @param {import("../peerjs").DataConnection} dataConnection
+ */
+window.send = (dataConnection) => {
+ dataConnection.send([]);
+ dataConnection.send(commit_data);
+};
+window["connect-btn"].disabled = false;
diff --git a/e2e/datachannel/arrays_json.js b/e2e/datachannel/arrays_json.js
new file mode 100644
index 000000000..625dd2d31
--- /dev/null
+++ b/e2e/datachannel/arrays_json.js
@@ -0,0 +1,19 @@
+/**
+ * JSON transfer does not chunk, commit_data is too large to send
+ */
+
+import { commit_data } from "../data.js";
+import { expect } from "https://esm.sh/v126/chai@4.3.7/X-dHMvZXhwZWN0/es2021/chai.bundle.mjs";
+
+/** @param {unknown[]} received */
+window.check = (received) => {
+ expect(received).to.deep.equal([[], commit_data.slice(0, 2)]);
+};
+/**
+ * @param {import("../peerjs").DataConnection} dataConnection
+ */
+window.send = (dataConnection) => {
+ dataConnection.send([]);
+ dataConnection.send(commit_data.slice(0, 2));
+};
+window["connect-btn"].disabled = false;
diff --git a/e2e/datachannel/numbers.js b/e2e/datachannel/numbers.js
new file mode 100644
index 000000000..8a468d535
--- /dev/null
+++ b/e2e/datachannel/numbers.js
@@ -0,0 +1,16 @@
+import { numbers } from "../data.js";
+import { expect } from "https://esm.sh/v126/chai@4.3.7/X-dHMvZXhwZWN0/es2021/chai.bundle.mjs";
+
+/** @param {unknown[]} received */
+window.check = (received) => {
+ expect(received).to.deep.equal(numbers);
+};
+/**
+ * @param {import("../peerjs").DataConnection} dataConnection
+ */
+window.send = (dataConnection) => {
+ for (const number of numbers) {
+ dataConnection.send(number);
+ }
+};
+window["connect-btn"].disabled = false;
diff --git a/e2e/datachannel/objects.js b/e2e/datachannel/objects.js
new file mode 100644
index 000000000..42725c77e
--- /dev/null
+++ b/e2e/datachannel/objects.js
@@ -0,0 +1,16 @@
+import { commit_data } from "../data.js";
+import { expect } from "https://esm.sh/v126/chai@4.3.7/X-dHMvZXhwZWN0/es2021/chai.bundle.mjs";
+
+/** @param {unknown[]} received */
+window.check = (received) => {
+ expect(received).to.deep.equal(commit_data);
+};
+/**
+ * @param {import("../peerjs").DataConnection} dataConnection
+ */
+window.send = (dataConnection) => {
+ for (const commit of commit_data) {
+ dataConnection.send(commit);
+ }
+};
+window["connect-btn"].disabled = false;
diff --git a/e2e/datachannel/serialization.html b/e2e/datachannel/serialization.html
new file mode 100644
index 000000000..8f181c366
--- /dev/null
+++ b/e2e/datachannel/serialization.html
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+ Serialization
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/e2e/datachannel/serialization.js b/e2e/datachannel/serialization.js
new file mode 100644
index 000000000..b3a47a65c
--- /dev/null
+++ b/e2e/datachannel/serialization.js
@@ -0,0 +1,70 @@
+/**
+ * @type {typeof import("../peerjs").Peer}
+ */
+const Peer = window.Peer;
+
+document.getElementsByTagName("title")[0].innerText =
+ window.location.hash.substring(1);
+
+const checkBtn = document.getElementById("check-btn");
+const sendBtn = document.getElementById("send-btn");
+const receiverIdInput = document.getElementById("receiver-id");
+const connectBtn = document.getElementById("connect-btn");
+const messages = document.getElementById("messages");
+const result = document.getElementById("result");
+const errorMessage = document.getElementById("error-message");
+
+const peer = new Peer();
+const received = [];
+/**
+ * @type {import("../peerjs").DataConnection}
+ */
+let dataConnection;
+peer
+ .once("open", (id) => {
+ messages.textContent = `Your Peer ID: ${id}`;
+ })
+ .once("error", (error) => {
+ errorMessage.textContent = JSON.stringify(error);
+ })
+ .once("connection", (connection) => {
+ dataConnection = connection;
+ dataConnection.on("data", (data) => {
+ console.log(data);
+ received.push(data);
+ });
+ dataConnection.once("close", () => {
+ messages.textContent = "Closed!";
+ });
+ });
+
+connectBtn.addEventListener("click", () => {
+ const receiverId = receiverIdInput.value;
+ if (receiverId) {
+ dataConnection = peer.connect(receiverId);
+ dataConnection.once("open", () => {
+ messages.textContent = "Connected!";
+ });
+ }
+});
+
+checkBtn.addEventListener("click", async () => {
+ try {
+ window.check(received);
+ result.textContent = "Success!";
+ } catch (e) {
+ result.textContent = "Failed!";
+ errorMessage.textContent = JSON.stringify(e.message);
+ } finally {
+ messages.textContent = "Checked!";
+ }
+});
+
+sendBtn.addEventListener("click", () => {
+ dataConnection.once("error", (err) => {
+ errorMessage.innerText = err.toString();
+ });
+ window.send(dataConnection);
+ dataConnection.close({ flush: true });
+ messages.textContent = "Sent!";
+});
diff --git a/e2e/datachannel/serialization.page.ts b/e2e/datachannel/serialization.page.ts
new file mode 100644
index 000000000..1113cd8e0
--- /dev/null
+++ b/e2e/datachannel/serialization.page.ts
@@ -0,0 +1,71 @@
+import { browser, $ } from "@wdio/globals";
+class SerializationPage {
+ get sendBtn() {
+ return $("button[id='send-btn']");
+ }
+
+ get checkBtn() {
+ return $("button[id='check-btn']");
+ }
+ get connectBtn() {
+ return $("button[id='connect-btn']");
+ }
+
+ get receiverId() {
+ return $("input[id='receiver-id']");
+ }
+
+ get messages() {
+ return $("div[id='messages']");
+ }
+
+ get errorMessage() {
+ return $("div[id='error-message']");
+ }
+
+ get result() {
+ return $("div[id='result']");
+ }
+
+ waitForMessage(right: string) {
+ return browser.waitUntil(
+ async () => {
+ const messages = await this.messages.getText();
+ return messages.startsWith(right);
+ },
+ { timeoutMsg: `Expected message to start with ${right}`, timeout: 10000 },
+ );
+ }
+
+ async open(testFile: string, json: boolean = false) {
+ await browser.switchWindow("Alice");
+ await browser.url(
+ `/e2e/datachannel/serialization${
+ json ? "_json" : ""
+ }.html?test=${testFile}#Alice`,
+ );
+ await this.connectBtn.waitForEnabled();
+
+ await browser.switchWindow("Bob");
+ await browser.url(
+ `/e2e/datachannel/serialization${
+ json ? "_json" : ""
+ }.html?test=${testFile}#Bob`,
+ );
+ await this.connectBtn.waitForEnabled();
+ }
+ async init() {
+ await browser.url("/e2e/alice.html");
+ await browser.waitUntil(async () => {
+ const title = await browser.getTitle();
+ return title === "Alice";
+ });
+ await browser.newWindow("/e2e/bob.html");
+ await browser.waitUntil(async () => {
+ const title = await browser.getTitle();
+ return title === "Bob";
+ });
+ }
+}
+
+export default new SerializationPage();
diff --git a/e2e/datachannel/serialization.spec.ts b/e2e/datachannel/serialization.spec.ts
new file mode 100644
index 000000000..557f90134
--- /dev/null
+++ b/e2e/datachannel/serialization.spec.ts
@@ -0,0 +1,34 @@
+import P from "./serialization.page.js";
+import { browser, expect } from "@wdio/globals";
+
+const serializationTest = (testFile: string) => async () => {
+ await P.open(testFile);
+ await P.waitForMessage("Your Peer ID: ");
+ const bobId = (await P.messages.getText()).split("Your Peer ID: ")[1];
+ await browser.switchWindow("Alice");
+ await P.waitForMessage("Your Peer ID: ");
+ await P.receiverId.setValue(bobId);
+ await P.connectBtn.click();
+ await P.waitForMessage("Connected!");
+ await P.sendBtn.click();
+ await P.waitForMessage("Sent!");
+ await browser.switchWindow("Bob");
+ await P.waitForMessage("Closed!");
+ await P.checkBtn.click();
+ await P.waitForMessage("Checked!");
+
+ await expect(await P.errorMessage.getText()).toBe("");
+ await expect(await P.result.getText()).toBe("Success!");
+};
+describe("DataChannel:Default", () => {
+ beforeAll(async () => {
+ await P.init();
+ });
+ it("should transfer numbers", serializationTest("./numbers.js"));
+ /** ordering bug: chunked string not in order */
+ // it('should transfer strings', serializationTest("./strings.js"))
+ it("should transfer objects", serializationTest("./objects.js"));
+ it("should transfer arrays", serializationTest("./arrays.js"));
+ /** can't send bug */
+ // it('should transfer typed arrays / array buffers', serializationTest("./arraybuffers.js"))
+});
diff --git a/e2e/datachannel/serialization_json.html b/e2e/datachannel/serialization_json.html
new file mode 100644
index 000000000..c572915ff
--- /dev/null
+++ b/e2e/datachannel/serialization_json.html
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+ Serialization
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/e2e/datachannel/serialization_json.js b/e2e/datachannel/serialization_json.js
new file mode 100644
index 000000000..830e9fa2b
--- /dev/null
+++ b/e2e/datachannel/serialization_json.js
@@ -0,0 +1,70 @@
+/**
+ * @type {typeof import('../peerjs').Peer}
+ */
+const Peer = window.Peer;
+
+document.getElementsByTagName("title")[0].innerText =
+ window.location.hash.substring(1);
+
+const checkBtn = document.getElementById("check-btn");
+const sendBtn = document.getElementById("send-btn");
+const receiverIdInput = document.getElementById("receiver-id");
+const connectBtn = document.getElementById("connect-btn");
+const messages = document.getElementById("messages");
+const result = document.getElementById("result");
+const errorMessage = document.getElementById("error-message");
+
+const peer = new Peer();
+const received = [];
+/**
+ * @type {import('../peerjs').DataConnection}
+ */
+let dataConnection;
+peer
+ .once("open", (id) => {
+ messages.textContent = `Your Peer ID: ${id}`;
+ })
+ .once("error", (error) => {
+ errorMessage.textContent = error;
+ })
+ .once("connection", (connection) => {
+ dataConnection = connection;
+ dataConnection.on("data", (data) => {
+ console.log(data);
+ received.push(data);
+ });
+ dataConnection.once("close", () => {
+ messages.textContent = "Closed!";
+ });
+ });
+
+connectBtn.addEventListener("click", () => {
+ const receiverId = receiverIdInput.value;
+ if (receiverId) {
+ dataConnection = peer.connect(receiverId, { serialization: "json" });
+ dataConnection.once("open", () => {
+ messages.textContent = "Connected!";
+ });
+ }
+});
+
+checkBtn.addEventListener("click", async () => {
+ try {
+ window.check(received);
+ result.textContent = "Success!";
+ } catch (e) {
+ result.textContent = "Failed!";
+ errorMessage.textContent = JSON.stringify(e.message);
+ } finally {
+ messages.textContent = "Checked!";
+ }
+});
+
+sendBtn.addEventListener("click", () => {
+ dataConnection.once("error", (err) => {
+ errorMessage.innerText = err.toString();
+ });
+ window.send(dataConnection);
+ dataConnection.close({ flush: true });
+ messages.textContent = "Sent!";
+});
diff --git a/e2e/datachannel/serialization_json.spec.ts b/e2e/datachannel/serialization_json.spec.ts
new file mode 100644
index 000000000..e0f1a060b
--- /dev/null
+++ b/e2e/datachannel/serialization_json.spec.ts
@@ -0,0 +1,31 @@
+import P from "./serialization.page.js";
+import { browser, expect } from "@wdio/globals";
+
+const serializationTest = (testFile: string) => async () => {
+ await P.open(testFile, true);
+ await P.waitForMessage("Your Peer ID: ");
+ const bobId = (await P.messages.getText()).split("Your Peer ID: ")[1];
+ await browser.switchWindow("Alice");
+ await P.waitForMessage("Your Peer ID: ");
+ await P.receiverId.setValue(bobId);
+ await P.connectBtn.click();
+ await P.waitForMessage("Connected!");
+ await P.sendBtn.click();
+ await P.waitForMessage("Sent!");
+ await browser.switchWindow("Bob");
+ await P.waitForMessage("Closed!");
+ await P.checkBtn.click();
+ await P.waitForMessage("Checked!");
+
+ await expect(await P.errorMessage.getText()).toBe("");
+ await expect(await P.result.getText()).toBe("Success!");
+};
+describe("DataChannel:JSON", () => {
+ beforeAll(async () => {
+ await P.init();
+ });
+ it("should transfer numbers", serializationTest("./numbers.js"));
+ it("should transfer strings", serializationTest("./strings_json.js"));
+ it("should transfer objects", serializationTest("./objects.js"));
+ it("should transfer arrays", serializationTest("./arrays_json.js"));
+});
diff --git a/e2e/datachannel/strings.js b/e2e/datachannel/strings.js
new file mode 100644
index 000000000..440e2b527
--- /dev/null
+++ b/e2e/datachannel/strings.js
@@ -0,0 +1,17 @@
+import { strings, long_string } from "../data.js";
+import { expect } from "https://esm.sh/v126/chai@4.3.7/X-dHMvZXhwZWN0/es2021/chai.bundle.mjs";
+
+/** @param {unknown[]} received */
+window.check = (received) => {
+ expect(received).to.deep.equal([long_string, ...strings]);
+};
+/**
+ * @param {import("../peerjs").DataConnection} dataConnection
+ */
+window.send = (dataConnection) => {
+ dataConnection.send(long_string);
+ for (const string of strings) {
+ dataConnection.send(string);
+ }
+};
+window["connect-btn"].disabled = false;
diff --git a/e2e/datachannel/strings_json.js b/e2e/datachannel/strings_json.js
new file mode 100644
index 000000000..7505f819d
--- /dev/null
+++ b/e2e/datachannel/strings_json.js
@@ -0,0 +1,19 @@
+/**
+ * JSON transfer does not chunk, large_string is too large to send
+ */
+import { strings, long_string } from "../data.js";
+import { expect } from "https://esm.sh/v126/chai@4.3.7/X-dHMvZXhwZWN0/es2021/chai.bundle.mjs";
+
+/** @param {unknown[]} received */
+window.check = (received) => {
+ expect(received).to.deep.equal(strings);
+};
+/**
+ * @param {import("../peerjs").DataConnection} dataConnection
+ */
+window.send = (dataConnection) => {
+ for (const string of strings) {
+ dataConnection.send(string);
+ }
+};
+window["connect-btn"].disabled = false;
diff --git a/e2e/package.json b/e2e/package.json
new file mode 100644
index 000000000..bedb411a9
--- /dev/null
+++ b/e2e/package.json
@@ -0,0 +1,3 @@
+{
+ "type": "module"
+}
diff --git a/e2e/style.css b/e2e/style.css
new file mode 100644
index 000000000..d1a2ca20d
--- /dev/null
+++ b/e2e/style.css
@@ -0,0 +1,26 @@
+body {
+ font-family: Arial, sans-serif;
+ max-width: 800px;
+ margin: 0 auto;
+ padding: 20px;
+}
+
+#inputs {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px;
+ align-items: center;
+}
+
+button {
+ background-color: #007bff;
+ color: white;
+ border: none;
+ padding: 8px 16px;
+ border-radius: 4px;
+ cursor: pointer;
+}
+
+button:hover {
+ background-color: #0056b3;
+}
diff --git a/e2e/tsconfig.json b/e2e/tsconfig.json
new file mode 100644
index 000000000..2efd5043e
--- /dev/null
+++ b/e2e/tsconfig.json
@@ -0,0 +1,70 @@
+{
+ "compilerOptions": {
+ /* Visit https://aka.ms/tsconfig.json to read more about this file */
+
+ /* Basic Options */
+ // "incremental": true, /* Enable incremental compilation */
+ "target": "ES2022" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
+ "module": "ESNext" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
+ // "lib": [], /* Specify library files to be included in the compilation. */
+ // "allowJs": true, /* Allow javascript files to be compiled. */
+ // "checkJs": true, /* Report errors in .js files. */
+ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
+ // "declaration": true, /* Generates corresponding '.d.ts' file. */
+ // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
+ // "sourceMap": true, /* Generates corresponding '.map' file. */
+ // "outFile": "./", /* Concatenate and emit output to single file. */
+ // "outDir": "./", /* Redirect output structure to the directory. */
+ // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
+ // "composite": true, /* Enable project compilation */
+ // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
+ // "removeComments": true, /* Do not emit comments to output. */
+ // "noEmit": true, /* Do not emit outputs. */
+ // "importHelpers": true, /* Import emit helpers from 'tslib'. */
+ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
+ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
+
+ /* Strict Type-Checking Options */
+ "strict": true /* Enable all strict type-checking options. */,
+ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
+ // "strictNullChecks": true, /* Enable strict null checks. */
+ // "strictFunctionTypes": true, /* Enable strict checking of function types. */
+ // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
+ // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
+ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
+ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
+
+ /* Additional Checks */
+ // "noUnusedLocals": true, /* Report errors on unused locals. */
+ // "noUnusedParameters": true, /* Report errors on unused parameters. */
+ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
+ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
+ // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
+
+ /* Module Resolution Options */
+ "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
+ // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
+ // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
+ // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
+ // "typeRoots": [], /* List of folders to include type definitions from. */
+ "types": ["node", "@wdio/globals/types", "@wdio/jasmine-framework"],
+ "allowSyntheticDefaultImports": true /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */,
+ // "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
+ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
+ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
+
+ /* Source Map Options */
+ // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
+ // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
+ // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
+ // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
+
+ /* Experimental Options */
+ // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
+ // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
+
+ /* Advanced Options */
+ "skipLibCheck": true /* Skip type checking of declaration files. */,
+ "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
+ }
+}
diff --git a/e2e/types.d.ts b/e2e/types.d.ts
new file mode 100644
index 000000000..a75618d71
--- /dev/null
+++ b/e2e/types.d.ts
@@ -0,0 +1,11 @@
+/* eslint no-unused-vars: 0 */
+
+declare module "https://esm.sh/v126/chai@4.3.7/X-dHMvZXhwZWN0/es2021/chai.bundle.mjs" {
+ export = chai;
+}
+
+interface Window {
+ "connect-btn": HTMLButtonElement;
+ send: (dataConnection: import("../../peerjs").DataConnection) => void;
+ check: (received: unknown[]) => void;
+}
diff --git a/e2e/wdio.bstack.conf.ts b/e2e/wdio.bstack.conf.ts
new file mode 100644
index 000000000..1ac8b2408
--- /dev/null
+++ b/e2e/wdio.bstack.conf.ts
@@ -0,0 +1,71 @@
+import { config as sharedConfig } from "./wdio.shared.conf.js";
+
+export const config: WebdriverIO.Config = {
+ ...sharedConfig,
+ ...{
+ user: process.env.BROWSERSTACK_USERNAME,
+ key: process.env.BROWSERSTACK_ACCESS_KEY,
+ hostname: "hub.browserstack.com",
+ services: [
+ [
+ "browserstack",
+ {
+ browserstackLocal: true,
+ },
+ ],
+ ],
+ capabilities: [
+ {
+ browserName: "Edge",
+ "bstack:options": {
+ os: "Windows",
+ osVersion: "11",
+ browserVersion: "81",
+ localIdentifier: process.env.BROWSERSTACK_LOCAL_IDENTIFIER,
+ },
+ },
+ {
+ browserName: "Firefox",
+ "bstack:options": {
+ os: "Windows",
+ osVersion: "7",
+ browserVersion: "80.0",
+ localIdentifier: process.env.BROWSERSTACK_LOCAL_IDENTIFIER,
+ },
+ },
+ {
+ browserName: "Safari",
+ "bstack:options": {
+ browserVersion: "latest",
+ os: "OS X",
+ osVersion: "Big Sur",
+ localIdentifier: process.env.BROWSERSTACK_LOCAL_IDENTIFIER,
+ },
+ },
+ // {
+ // browserName: 'Safari',
+ // 'bstack:options': {
+ // browserVersion: 'latest',
+ // os: 'OS X',
+ // osVersion: 'Monterey'
+ // }
+ // },
+ // {
+ // browserName: 'Chrome',
+ // 'bstack:options': {
+ // browserVersion: 'latest',
+ // os: 'Windows',
+ // osVersion: '11'
+ // }
+ // },
+ // {
+ // browserName: 'Firefox',
+ // 'bstack:options': {
+ // browserVersion: 'latest',
+ // os: 'OS X',
+ // osVersion: 'Ventura'
+ // }
+ // }
+ ],
+ },
+};
diff --git a/e2e/wdio.local.conf.ts b/e2e/wdio.local.conf.ts
new file mode 100644
index 000000000..b710a9531
--- /dev/null
+++ b/e2e/wdio.local.conf.ts
@@ -0,0 +1,23 @@
+import { config as sharedConfig } from "./wdio.shared.conf.js";
+
+export const config: WebdriverIO.Config = {
+ runner: "local",
+ ...sharedConfig,
+ services: ["geckodriver"],
+ ...{
+ capabilities: [
+ {
+ browserName: "chrome",
+ "wdio:devtoolsOptions": {
+ headless: true,
+ },
+ },
+ {
+ browserName: "firefox",
+ "moz:firefoxOptions": {
+ args: ["-headless"],
+ },
+ },
+ ],
+ },
+};
diff --git a/e2e/wdio.shared.conf.ts b/e2e/wdio.shared.conf.ts
new file mode 100644
index 000000000..b1c6e2418
--- /dev/null
+++ b/e2e/wdio.shared.conf.ts
@@ -0,0 +1,250 @@
+import url from "node:url";
+import path from "node:path";
+
+const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
+
+export const config: Omit = {
+ injectGlobals: false,
+ //
+ // ====================
+ // Runner Configuration
+ // ====================
+ //
+ // WebdriverIO allows it to run your tests in arbitrary locations (e.g. locally or
+ // on a remote machine).
+ // runner: 'local',
+ //
+ // ==================
+ // Specify Test Files
+ // ==================
+ // Define which test specs should run. The pattern is relative to the directory
+ // from which `wdio` was called. Notice that, if you are calling `wdio` from an
+ // NPM script (see https://docs.npmjs.com/cli/run-script) then the current working
+ // directory is where your package.json resides, so `wdio` will be called from there.
+ //
+ specs: ["./**/*.spec.ts"],
+ // Patterns to exclude.
+ exclude: [
+ // 'path/to/excluded/files'
+ ],
+ //
+ // ============
+ // Capabilities
+ // ============
+ // Define your capabilities here. WebdriverIO can run multiple capabilities at the same
+ // time. Depending on the number of capabilities, WebdriverIO launches several test
+ // sessions. Within your capabilities you can overwrite the spec and exclude options in
+ // order to group specific specs to a specific capability.
+ //
+ // First, you can define how many instances should be started at the same time. Let's
+ // say you have 3 different capabilities (Chrome, Firefox, and Safari) and you have
+ // set maxInstances to 1; wdio will spawn 3 processes. Therefore, if you have 10 spec
+ // files and you set maxInstances to 10, all spec files will get tested at the same time
+ // and 30 processes will get spawned. The property handles how many capabilities
+ // from the same test should run tests.
+ //
+ maxInstances: 5,
+ //
+ // ===================
+ // Test Configurations
+ // ===================
+ // Define all options that are relevant for the WebdriverIO instance here
+ //
+ // Level of logging verbosity: trace | debug | info | warn | error | silent
+ logLevel: "trace",
+ outputDir: path.resolve(__dirname, "logs"),
+ //
+ // Set specific log levels per logger
+ // loggers:
+ // - webdriver, webdriverio
+ // - @wdio/applitools-service, @wdio/browserstack-service, @wdio/devtools-service, @wdio/sauce-service
+ // - @wdio/mocha-framework, @wdio/jasmine-framework
+ // - @wdio/local-runner, @wdio/lambda-runner
+ // - @wdio/sumologic-reporter
+ // - @wdio/cli, @wdio/config, @wdio/sync, @wdio/utils
+ // Level of logging verbosity: trace | debug | info | warn | error | silent
+ // logLevels: {
+ // webdriver: 'info',
+ // '@wdio/applitools-service': 'info'
+ // },
+ //
+ // If you only want to run your tests until a specific amount of tests have failed use
+ // bail (default is 0 - don't bail, run all tests).
+ bail: 0,
+ //
+ // Set a base URL in order to shorten url command calls. If your `url` parameter starts
+ // with `/`, the base url gets prepended, not including the path portion of your baseUrl.
+ // If your `url` parameter starts without a scheme or `/` (like `some/path`), the base url
+ // gets prepended directly.
+ baseUrl: "http://localhost:3000",
+ //
+ // Default timeout for all waitFor* commands.
+ waitforTimeout: 10000,
+ //
+ // Default timeout in milliseconds for request
+ // if browser driver or grid doesn't send response
+ connectionRetryTimeout: 90000,
+ //
+ // Default request retries count
+ connectionRetryCount: 3,
+ //
+ // Framework you want to run your specs with.
+ // The following are supported: Mocha, Jasmine, and Cucumber
+ // see also: https://webdriver.io/docs/frameworks.html
+ //
+ // Make sure you have the wdio adapter package for the specific framework installed
+ // before running any tests.
+ framework: "jasmine",
+ //
+ // The number of times to retry the entire specfile when it fails as a whole
+ // specFileRetries: 1,
+ //
+ // Whether or not retried specfiles should be retried immediately or deferred to the end of the queue
+ // specFileRetriesDeferred: false,
+ //
+ // Test reporter for stdout.
+ // The only one supported by default is 'dot'
+ // see also: https://webdriver.io/docs/dot-reporter.html
+ reporters: ["spec"],
+ //
+ // Options to be passed to Jasmine.
+ jasmineOpts: {
+ // Jasmine default timeout
+ defaultTimeoutInterval: 60000,
+ //
+ // The Jasmine framework allows interception of each assertion in order to log the state of the application
+ // or website depending on the result. For example, it is pretty handy to take a screenshot every time
+ // an assertion fails.
+ // expectationResultHandler: function(passed, assertion) {
+ // do something
+ // }
+ },
+ //
+ // =====
+ // Hooks
+ // =====
+ // WebdriverIO provides several hooks you can use to interfere with the test process in order to enhance
+ // it and to build services around it. You can either apply a single function or an array of
+ // methods to it. If one of them returns with a promise, WebdriverIO will wait until that promise got
+ // resolved to continue.
+ /**
+ * Gets executed once before all workers get launched.
+ * @param {Object} config wdio configuration object
+ * @param {Array.