diff --git a/README.md b/README.md
index c9770e4af3e4c3c764ff92dac0856998f8f911a9..3ab395e620591deb943acdec6909890cc9c5e130 100644
--- a/README.md
+++ b/README.md
@@ -103,8 +103,6 @@ authors of both. In particular, I made sure to go through the issue tracker of g
 to ensure I implemented details correctly and understood how people were using WebSockets in
 production.
 
-Another comparison between Go WebSocket libraries is available at [gorilla/websocket](https://github.com/gorilla/websocket#gorilla-websocket-compared-with-other-packages).
-
 ### gorilla/websocket
 
 https://github.com/gorilla/websocket
diff --git a/ci/test.sh b/ci/test.sh
index 1f5b5102bda6001d322a9bbfc6b819ccfa84e72e..d7abcd1e10eceb890b8fa2cdf26ea676915c773d 100755
--- a/ci/test.sh
+++ b/ci/test.sh
@@ -27,8 +27,12 @@ fi
 mkdir -p ci/out/websocket
 "${argv[@]}"
 
-# Removes coverage of generated files.
-grep -v _string.go < ci/out/coverage.prof > ci/out/coverage2.prof
+# Removes coverage of generated/test related files.
+grep -v _stringer.go < ci/out/coverage.prof > ci/out/coverage2.prof
+mv ci/out/coverage2.prof ci/out/coverage.prof
+grep -v wsjstest < ci/out/coverage.prof > ci/out/coverage2.prof
+mv ci/out/coverage2.prof ci/out/coverage.prof
+grep -v wsecho < ci/out/coverage.prof > ci/out/coverage2.prof
 mv ci/out/coverage2.prof ci/out/coverage.prof
 
 go tool cover -html=ci/out/coverage.prof -o=ci/out/coverage.html
diff --git a/ci/wasm.sh b/ci/wasm.sh
index a780b63f25d2e4f0116e68a00f8dd37cf7404d59..134b60b51e9247965d071187bb51d61396447716 100755
--- a/ci/wasm.sh
+++ b/ci/wasm.sh
@@ -22,7 +22,8 @@ if [[ -z $WS_ECHO_SERVER_URL ]]; then
 fi
 
 go install github.com/agnivade/wasmbrowsertest
-GOOS=js GOARCH=wasm go test -exec=wasmbrowsertest ./... -args "$WS_ECHO_SERVER_URL"
+export WS_ECHO_SERVER_URL
+GOOS=js GOARCH=wasm go test -exec=wasmbrowsertest ./...
 
 kill "$wsjstestPID"
 if ! wait "$wsjstestPID"; then
diff --git a/go.mod b/go.mod
index 86a9403b244132a9b0291031e1588bdcd40a869d..8bd3b8872c63281ca7bd0cfb4dcfaa8d5936ef32 100644
--- a/go.mod
+++ b/go.mod
@@ -3,12 +3,17 @@ module nhooyr.io/websocket
 go 1.13
 
 require (
-	github.com/agnivade/wasmbrowsertest v0.3.0
+	github.com/agnivade/wasmbrowsertest v0.3.1
+	github.com/chromedp/cdproto v0.0.0-20190926234355-1b4886c6fad6 // indirect
+	github.com/chromedp/chromedp v0.4.0 // indirect
 	github.com/fatih/color v1.7.0 // indirect
+	github.com/go-interpreter/wagon v0.6.0 // indirect
 	github.com/golang/protobuf v1.3.2
 	github.com/google/go-cmp v0.3.1
+	github.com/google/pprof v0.0.0-20190908185732-236ed259b199 // indirect
 	github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
 	github.com/kr/pretty v0.1.0 // indirect
+	github.com/mailru/easyjson v0.7.0 // indirect
 	github.com/mattn/go-colorable v0.1.2 // indirect
 	github.com/mattn/go-isatty v0.0.9 // indirect
 	github.com/pkg/errors v0.8.1 // indirect
@@ -20,7 +25,7 @@ require (
 	go.uber.org/multierr v1.1.0
 	golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac
 	golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e // indirect
-	golang.org/x/sys v0.0.0-20190919044723-0c1ff786ef13 // indirect
+	golang.org/x/sys v0.0.0-20190927073244-c990c680b611 // indirect
 	golang.org/x/time v0.0.0-20190308202827-9d24e82272b4
 	golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72
 	gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
diff --git a/go.sum b/go.sum
index 4af0094612a0141082b8b901d1c8e38396e3510e..0bcfc0b42c0b0e0700e3fcb632380f6235f48ab2 100644
--- a/go.sum
+++ b/go.sum
@@ -1,10 +1,15 @@
-github.com/agnivade/wasmbrowsertest v0.3.0 h1:5pAabhWzTVCLoVWqYejEbmWyzNGFR7K/Nu5lsmD1fVc=
-github.com/agnivade/wasmbrowsertest v0.3.0/go.mod h1:zQt6ZTdl338xxRaMW395qccVE2eQm0SjC/SDz0mPWQI=
+github.com/agnivade/wasmbrowsertest v0.3.1 h1:bA9aA+bcp7KuqGvmCuBdnMqy6PXxFjYP7FxsaT+JSqc=
+github.com/agnivade/wasmbrowsertest v0.3.1/go.mod h1:zQt6ZTdl338xxRaMW395qccVE2eQm0SjC/SDz0mPWQI=
 github.com/chromedp/cdproto v0.0.0-20190614062957-d6d2f92b486d/go.mod h1:S8mB5wY3vV+vRIzf39xDXsw3XKYewW9X6rW2aEmkrSw=
 github.com/chromedp/cdproto v0.0.0-20190621002710-8cbd498dd7a0 h1:4Wocv9f+KWF4GtZudyrn8JSBTgHQbGp86mcsoH7j1iQ=
 github.com/chromedp/cdproto v0.0.0-20190621002710-8cbd498dd7a0/go.mod h1:S8mB5wY3vV+vRIzf39xDXsw3XKYewW9X6rW2aEmkrSw=
+github.com/chromedp/cdproto v0.0.0-20190812224334-39ef923dcb8d/go.mod h1:0YChpVzuLJC5CPr+x3xkHN6Z8KOSXjNbL7qV8Wc4GW0=
+github.com/chromedp/cdproto v0.0.0-20190926234355-1b4886c6fad6 h1:C/dvU7FH/BUbkgKS/eYDrja/D5idxH+FxaVmFRWW3E8=
+github.com/chromedp/cdproto v0.0.0-20190926234355-1b4886c6fad6/go.mod h1:0YChpVzuLJC5CPr+x3xkHN6Z8KOSXjNbL7qV8Wc4GW0=
 github.com/chromedp/chromedp v0.3.1-0.20190619195644-fd957a4d2901 h1:tg66ykM8VYqP9k4DFQwSMnYv84HNTruF+GR6kefFNg4=
 github.com/chromedp/chromedp v0.3.1-0.20190619195644-fd957a4d2901/go.mod h1:mJdvfrVn594N9tfiPecUidF6W5jPRKHymqHfzbobPsM=
+github.com/chromedp/chromedp v0.4.0 h1:0AJC5ejETuh/6n7Tcsw4u4G0eKZkI9aVRwckWaImLUE=
+github.com/chromedp/chromedp v0.4.0/go.mod h1:DC3QUn4mJ24dwjcaGQLoZrhm4X/uPHZ6spDbS2uFhm4=
 github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -19,6 +24,8 @@ github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/go-interpreter/wagon v0.5.1-0.20190713202023-55a163980b6c h1:DLLAPVFrk9iNzljMKF512CUmrFImQ6WU3sDiUS4IRqk=
 github.com/go-interpreter/wagon v0.5.1-0.20190713202023-55a163980b6c/go.mod h1:5+b/MBYkclRZngKF5s6qrgWxSLgE9F5dFdO1hAueZLc=
+github.com/go-interpreter/wagon v0.6.0 h1:BBxDxjiJiHgw9EdkYXAWs8NHhwnazZ5P2EWBW5hFNWw=
+github.com/go-interpreter/wagon v0.6.0/go.mod h1:5+b/MBYkclRZngKF5s6qrgWxSLgE9F5dFdO1hAueZLc=
 github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0=
 github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
 github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8=
@@ -33,6 +40,8 @@ github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
 github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/pprof v0.0.0-20190515194954-54271f7e092f h1:Jnx61latede7zDD3DiiP4gmNz33uK0U5HDUaF0a/HVQ=
 github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/google/pprof v0.0.0-20190908185732-236ed259b199 h1:sEyCq3pOT7tNC+3gcLI7sZkBDgntZ6wQJNmr9lmIjIc=
+github.com/google/pprof v0.0.0-20190908185732-236ed259b199/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
 github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
@@ -52,6 +61,9 @@ github.com/mailru/easyjson v0.0.0-20190403194419-1ea4449da983/go.mod h1:C1wdFJiN
 github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
 github.com/mailru/easyjson v0.0.0-20190620125010-da37f6c1e481 h1:IaSjLMT6WvkoZZjspGxy3rdaTEmWLoRm49WbtVUi9sA=
 github.com/mailru/easyjson v0.0.0-20190620125010-da37f6c1e481/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
+github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
 github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
 github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
 github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
@@ -118,8 +130,8 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20190618155005-516e3c20635f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190919044723-0c1ff786ef13 h1:/zi0zzlPHWXYXrO1LjNRByFu8sdGgCkj2JLDdBIB84k=
-golang.org/x/sys v0.0.0-20190919044723-0c1ff786ef13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190927073244-c990c680b611 h1:q9u40nxWT5zRClI/uU9dHCiYGottAg6Nzz4YUQyHxdA=
+golang.org/x/sys v0.0.0-20190927073244-c990c680b611/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
diff --git a/internal/wsjs/wsjs_js.go b/internal/wsjs/wsjs_js.go
index 68078cf2e74c6fd9614d2d8f3f9a8de91930e200..d48691d45081edfbe6590f767da81fe818e13ab0 100644
--- a/internal/wsjs/wsjs_js.go
+++ b/internal/wsjs/wsjs_js.go
@@ -43,19 +43,11 @@ func New(url string, protocols []string) (c WebSocket, err error) {
 
 	c.setBinaryType("arraybuffer")
 
-	c.Extensions = c.v.Get("extensions").String()
-	c.Protocol = c.v.Get("protocol").String()
-	c.URL = c.v.Get("url").String()
-
 	return c, nil
 }
 
 // WebSocket is a wrapper around a javascript WebSocket object.
 type WebSocket struct {
-	Extensions string
-	Protocol   string
-	URL        string
-
 	v js.Value
 }
 
@@ -131,6 +123,11 @@ func (c WebSocket) OnMessage(fn func(m MessageEvent)) (remove func()) {
 	})
 }
 
+// Subprotocol returns the WebSocket subprotocol in use.
+func (c WebSocket) Subprotocol() string {
+	return c.v.Get("protocol").String()
+}
+
 // OnOpen registers a function to be called when the websocket is opened.
 func (c WebSocket) OnOpen(fn func(e js.Value)) (remove func()) {
 	return c.addEventListener("open", fn)
diff --git a/websocket_js.go b/websocket_js.go
index 05fafe2a20cdedc58f5b24fffc33a681f1793a06..4563a1bc437d88e9dd2cd661d5ea24457345f885 100644
--- a/websocket_js.go
+++ b/websocket_js.go
@@ -219,7 +219,7 @@ func (c *Conn) Close(code StatusCode, reason string) error {
 // Subprotocol returns the negotiated subprotocol.
 // An empty string means the default protocol.
 func (c *Conn) Subprotocol() string {
-	return c.ws.Protocol
+	return c.ws.Subprotocol()
 }
 
 // DialOptions represents the options available to pass to Dial.
diff --git a/websocket_js_test.go b/websocket_js_test.go
index 8e4299692a9a10a04d8a0a0db03c532aac91f401..a3bb7639362edead3bc0dbf18e1fcec07147deb8 100644
--- a/websocket_js_test.go
+++ b/websocket_js_test.go
@@ -2,8 +2,8 @@ package websocket_test
 
 import (
 	"context"
-	"flag"
 	"net/http"
+	"os"
 	"testing"
 	"time"
 
@@ -13,12 +13,10 @@ import (
 func TestConn(t *testing.T) {
 	t.Parallel()
 
-	wsEchoServerURL := flag.Arg(0)
-
 	ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
 	defer cancel()
 
-	c, resp, err := websocket.Dial(ctx, wsEchoServerURL, &websocket.DialOptions{
+	c, resp, err := websocket.Dial(ctx, os.Getenv("WS_ECHO_SERVER_URL"), &websocket.DialOptions{
 		Subprotocols: []string{"echo"},
 	})
 	if err != nil {
@@ -26,7 +24,7 @@ func TestConn(t *testing.T) {
 	}
 	defer c.Close(websocket.StatusInternalError, "")
 
-	assertSubprotocol(c, "echo")
+	err = assertSubprotocol(c, "echo")
 	if err != nil {
 		t.Fatal(err)
 	}