Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

PhantomJS fails to execute tests when using websockets, introduced in #768 #824

Closed
rokerkony opened this issue Jun 27, 2017 · 26 comments · Fixed by #826
Closed

PhantomJS fails to execute tests when using websockets, introduced in #768 #824

rokerkony opened this issue Jun 27, 2017 · 26 comments · Fixed by #826

Comments

@rokerkony
Copy link

Hi,
changes introduced in #768 (specifically changes on function patchProperty(...)) are causing us problem with running e2e tests in angular (4.2.2) and we cannot upgrade Zone.js from 0.8.10 to higher version.

When I drop changes manually on method patchProperty(...), it works as before.

Problem occurs when we run SendBird connect method which is connecting to WebSockets this.sendbird.connect(userId, accessToken, (user: User, connectError: any) => {

Call stack from running tests:

    at /Users/konradcerny/Sites/Erento/frontend-som/node_modules/selenium-webdriver/lib/promise.js:2107:17
    at ManagedPromise.invokeCallback_ (/Users/konradcerny/Sites/Erento/frontend-som/node_modules/selenium-webdriver/lib/promise.js:1366:14)
    at TaskQueue.execute_ (/Users/konradcerny/Sites/Erento/frontend-som/node_modules/selenium-webdriver/lib/promise.js:2970:14)
    at TaskQueue.executeNext_ (/Users/konradcerny/Sites/Erento/frontend-som/node_modules/selenium-webdriver/lib/promise.js:2953:27)
    at asyncRun (/Users/konradcerny/Sites/Erento/frontend-som/node_modules/selenium-webdriver/lib/promise.js:2813:27)
    at /Users/konradcerny/Sites/Erento/frontend-som/node_modules/selenium-webdriver/lib/promise.js:676:7
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:169:7)
From: Task: <anonymous wait>
    at scheduleWait (/Users/konradcerny/Sites/Erento/frontend-som/node_modules/selenium-webdriver/lib/promise.js:2094:20)
    at ControlFlow.wait (/Users/konradcerny/Sites/Erento/frontend-som/node_modules/selenium-webdriver/lib/promise.js:2408:12)
    at WebDriver.wait (/Users/konradcerny/Sites/Erento/frontend-som/node_modules/selenium-webdriver/lib/webdriver.js:943:29)
    at run (/Users/konradcerny/Sites/Erento/frontend-som/node_modules/protractor/lib/browser.ts:66:27)
    at ProtractorBrowser.to.(anonymous function) [as wait] (/Users/konradcerny/Sites/Erento/frontend-som/node_modules/protractor/lib/browser.ts:74:12)
    at Object.<anonymous> (/Users/konradcerny/Sites/Erento/frontend-som/e2e/pages/offer-modify-form.spec.ts:40:21)
    at /Users/konradcerny/Sites/Erento/frontend-som/node_modules/jasminewd2/index.js:112:25
    at new ManagedPromise (/Users/konradcerny/Sites/Erento/frontend-som/node_modules/selenium-webdriver/lib/promise.js:1067:7)
    at ControlFlow.promise (/Users/konradcerny/Sites/Erento/frontend-som/node_modules/selenium-webdriver/lib/promise.js:2396:12)
    at schedulerExecute (/Users/konradcerny/Sites/Erento/frontend-som/node_modules/jasminewd2/index.js:95:18)
    at TaskQueue.execute_ (/Users/konradcerny/Sites/Erento/frontend-som/node_modules/selenium-webdriver/lib/promise.js:2970:14)
    at TaskQueue.executeNext_ (/Users/konradcerny/Sites/Erento/frontend-som/node_modules/selenium-webdriver/lib/promise.js:2953:27)
    at asyncRun (/Users/konradcerny/Sites/Erento/frontend-som/node_modules/selenium-webdriver/lib/promise.js:2860:25)
    at /Users/konradcerny/Sites/Erento/frontend-som/node_modules/selenium-webdriver/lib/promise.js:676:7
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:169:7)
From: Task: Run fit("should show message has to be filled on non modified form") in control flow
    at Object.<anonymous> (/Users/konradcerny/Sites/Erento/frontend-som/node_modules/jasminewd2/index.js:94:19)
    at /Users/konradcerny/Sites/Erento/frontend-som/node_modules/jasminewd2/index.js:64:48
    at ControlFlow.emit (/Users/konradcerny/Sites/Erento/frontend-som/node_modules/selenium-webdriver/lib/events.js:62:21)
    at ControlFlow.shutdown_ (/Users/konradcerny/Sites/Erento/frontend-som/node_modules/selenium-webdriver/lib/promise.js:2565:10)
    at shutdownTask_.MicroTask (/Users/konradcerny/Sites/Erento/frontend-som/node_modules/selenium-webdriver/lib/promise.js:2490:53)
    at MicroTask.asyncRun (/Users/konradcerny/Sites/Erento/frontend-som/node_modules/selenium-webdriver/lib/promise.js:2619:9)
    at /Users/konradcerny/Sites/Erento/frontend-som/node_modules/selenium-webdriver/lib/promise.js:676:7
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:169:7)
From asynchronous test:
Error
    at Suite.<anonymous> (/Users/konradcerny/Sites/Erento/frontend-som/e2e/pages/offer-modify-form.spec.ts:39:9)
    at Suite.<anonymous> (/Users/konradcerny/Sites/Erento/frontend-som/e2e/pages/offer-modify-form.spec.ts:31:5)
    at Object.<anonymous> (/Users/konradcerny/Sites/Erento/frontend-som/e2e/pages/offer-modify-form.spec.ts:8:1)
    at Module._compile (module.js:569:30)
    at Module.m._compile (/Users/konradcerny/Sites/Erento/frontend-som/node_modules/ts-node/src/index.ts:382:23)
    at Module._extensions..js (module.js:580:10)
    at Object.require.extensions.(anonymous function) [as .ts] (/Users/konradcerny/Sites/Erento/frontend-som/node_modules/ts-node/src/index.ts:385:12)
    at Module.load (module.js:503:32)
    at tryModuleLoad (module.js:466:12)
@rokerkony
Copy link
Author

I have to add that it is working when tests are running in Chrome

@rokerkony
Copy link
Author

this:

var desc = Object.getOwnPropertyDescriptor(obj, prop) || { enumerable: true, configurable: true };

changed to:

var desc = Object.getOwnPropertyDescriptor(obj, prop);

and makes code not working. So it looks like in the end it doesn't patch the properties of websocket if I'm correct.

@JiaLiPassion
Copy link
Collaborator

@rokerkony, could you post the reproduce repo? or could you help to debug which object, which prop are not patched?

@rokerkony
Copy link
Author

I made my code working by changing it as:

if (prop === 'onopen') {
    var desc = Object.getOwnPropertyDescriptor(obj, prop) || { enumerable: true, configurable: true };
} else {
    var desc = Object.getOwnPropertyDescriptor(obj, prop);
}

and this is working to connect. But I guess it should be done for all the methods ['close', 'error', 'open', 'message'] because in other test which is checking incoming messages it seems that it is not receiving anything. With the code if (prop === 'onopen' || prop === 'onmessage') { it is receiving.

I don't see a way to make a reproduce repo without really connecting to Sendbird and for that I cannot share appId and tokens... I will try to be as helpful as possible to fix it 👍

To add all information I have in patchProperty, the obj is (taken from remote debugger for phantom):

__zone_symbol___onopen: function (event) {
addEventListener: function () {
close: function () {
get onopen: function () {
onclose: function (e) {DEBUG&&console.log("WSClient ws.onclose called - e, explicitDisconnect: ",e,explicitDisconnect),pinger&&pinger.stop(),explicitDisconnect?WSClientHandler.onClose(e):WSClientHandler.onError(e),explicitDisconnect=!1;}
onerror: function (e) {DEBUG&&console.log("WSClient ws.onerror called: ",e),pinger&&pinger.stop(),WSClientHandler.onError(e);}
onmessage: function (e) {active();var data=e.data.split("\n");for(var i in data){var item=data[i];if(item&&"string"==typeof item){try{if("PONG"==item.substring(0,4)){pinger&&pinger.ping();continue}}catch(e){DEBUG&&console.log("ws.onmessage-command check error: ",e)}WSClientHandler.onMessage(item)}}}
removeEventListener: function () {
send: function () {
set onopen: function (newValue) {

which looks like WebSocket from SendBird connect method, which after some prettify looks like this (spoiler alert: still not pretty):

this.connect = function (_user_id, _access_token, _WSHost) {
    DEBUG && console.log("WSClient connect called"), connectWSHost = _WSHost;
    var _WS = null;
    try {
        _WS = "undefined" == typeof WebSocket ? require("websocket").w3cwebsocket : WebSocket
    } catch (err) {
        _WS = WebSocket
    }
    try {
        var WS_URL_PARAM = "/?p=JS&pv=" + encodeURIComponent(OS_VERSION) + "&sv=" + encodeURIComponent("3.0.31") + "&ai=" + encodeURIComponent(appId);
        if (
            APIClient.getInstance().sessionKey ?
                WS_URL_PARAM += "&key=" + encodeURIComponent(APIClient.getInstance().sessionKey) :
                WS_URL_PARAM += "&user_id=" + encodeURIComponent(_user_id) + "&access_token=" + encodeURIComponent(_access_token),
                !(ws = new _WS(connectWSHost + WS_URL_PARAM))
        )
            return void WSClientHandler.onError(e)
    } catch (e) {
        return void WSClientHandler.onError(e)
    }
    if (DEBUG)try {
        window.ws = ws
    } catch (e) {
    }
    ws.onopen = function (e) {
        pinger && pinger.ping(), DEBUG && console.log("WSClient onopen called"), WSClientHandler.onOpen(e)
    },
    ws.onmessage = function (e) {
        active();
        var data = e.data.split("\n");
        for (var i in data) {
            var item = data[i];
            if (item && "string" == typeof item) {
                try {
                    if ("PONG" == item.substring(0, 4)) {
                        pinger && pinger.ping();
                        continue
                    }
                } catch (e) {
                    DEBUG && console.log("ws.onmessage-command check error: ", e)
                }
                WSClientHandler.onMessage(item)
            }
        }
    },
    ws.onclose = function (e) {
        DEBUG && console.log("WSClient ws.onclose called - e, explicitDisconnect: ", e, explicitDisconnect),
        pinger && pinger.stop(), 
        explicitDisconnect ? WSClientHandler.onClose(e) : WSClientHandler.onError(e), 
        explicitDisconnect = !1
    },
    ws.onerror = function (e) {
        DEBUG && console.log("WSClient ws.onerror called: ", e),
        pinger && pinger.stop(),
        WSClientHandler.onError(e)
    }
}

@JiaLiPassion
Copy link
Collaborator

JiaLiPassion commented Jun 27, 2017

@rokerkony , thank you for the information, in your code, could you check.

if (prop === 'onopen') {
    var desc = Object.getOwnPropertyDescriptor(obj, prop) || { enumerable: true, configurable: true };
} else {
    var desc = Object.getOwnPropertyDescriptor(obj, prop);
}

could you confirm that desc is undefined when prop is onopen, and could you print

console.log('target is ', obj, 'keys are:', Object.keys(obj), 'prototype is:', Object.getPrototypeOf(obj));

when prop is onopen?

@rokerkony
Copy link
Author

So, first of all, I created the repository with the generated app via angular-cli which is simulating the problem:
https://github.com/rokerkony/angular-zone-websocket-connection-problem

npm run e2e will work (chrome)
npm run e2e:phantom will NOT work (phantomjs)

but I cannot share my AppID (I put TODO in app.component.ts to find it) ... maybe it would be easy to create some trial on Sendbird and get ID plus create a channel...


@JiaLiPassion I checked also what you have asked me and here is a result:
onopen: Object.getOwnPropertyDescriptor(obj, prop) returns undefined so the result of

var desc = Object.getOwnPropertyDescriptor(obj, prop) || { enumerable: true, configurable: true };

is obviously { enumerable: true, configurable: true }

but this fallback to enumerable/configurable object was removed in 0.8.11 which could be a problem.

Hard to copy a result from the debugger but should be ok:
Target is:

Object
addEventListener: function () {
close: function () {
get onopen: function () {
onclose: function (e) {
onerror: function (e) {
onmessage: function (e) {
removeEventListener: function () {
send: function () {
set onopen: function (newValue) {
__proto__: WebSocket

keys are:

Array[4]
0: "addEventListener"
1: "removeEventListener"
2: "send"
3: "close"
length: 4
__proto__: Array[0]

prototype is:

WebSocket
URL: "ws://localhost:4200/sockjs-node/236/4zynjfdu/websocket"
binaryType: "blob"
bufferedAmount: 0
constructor: WebSocketConstructor
extensions: ""
onclose: null
onerror: null
onmessage: null
onopen: null
protocol: ""
readyState: 1
url: "ws://localhost:4200/sockjs-node/236/4zynjfdu/websocket"
__proto__: WebSocketPrototype

@JiaLiPassion
Copy link
Collaborator

@rokerkony , could you try the attached zone.js work or not?
zone.js.zip

@rokerkony
Copy link
Author

Unfortunately not.

prototype argument is now set to:

function (a, b) {
            var socket = arguments.length > 1 ? new WS(a, b) : new WS(a);
            var proxySocket;
            // Safari 7.0 has non-configurable own 'onmessage' and friends properties on the socket instance
            var onmessageDesc = Object.getOwnPropertyDescriptor(socket, 'onmessage');
            if (onmessageDesc && onmessageDesc.configurable === false) {
                proxySocket = Object.create(socket);
                ['addEventListener', 'removeEventListener', 'send', 'close'].forEach(function (propName) {
                    proxySocket[propName] = function () {
                        return socket[propName].apply(socket, arguments);
                    };
                });
            }
            else {
                // we can patch the real socket
                proxySocket = socket;
            }
            patchOnProperties(proxySocket, ['close', 'error', 'message', 'open'], _global.WebSocket);
            return proxySocket;
        } 

desc is still undefined before and after condition (if (!desc && prototype) {)

target is

Object {addEventListener: function, removeEventListener: function, send: function, close: function, readyState: 0}
addEventListener: function () {
close: function () {
onclose: function (e) {DEBUG&&console.log("WSClient ws.onclose called - e, explicitDisconnect: ",e,explicitDisconnect),pinger&&pinger.stop(),explicitDisconnect?WSClientHandler.onClose(e):WSClientHandler.onError(e),explicitDisconnect=!1;}
onerror: function (e) {DEBUG&&console.log("WSClient ws.onerror called: ",e),pinger&&pinger.stop(),WSClientHandler.onError(e);}
onmessage: function (e) {active();var data=e.data.split("\n");for(var i in data){var item=data[i];if(item&&"string"==typeof item){try{if("PONG"==item.substring(0,4)){pinger&&pinger.ping();continue}}catch(e){DEBUG&&console.log("ws.onmessage-command check error: ",e)}WSClientHandler.onMessage(item)}}}
onopen: function (e) {pinger&&pinger.ping(),DEBUG&&console.log("WSClient onopen called"),WSClientHandler.onOpen(e);}
removeEventListener: function () {
send: function () {
__proto__: WebSocket

keys are:

["addEventListener", "removeEventListener", "send", "close"]

prototype is:

WebSocket {readyState: 0, onclose: null, bufferedAmount: 0, extensions: "", onerror: null…}
URL: "wss://ws.sendbird.com/?p=JS&pv=Mozilla%2F5.0%20(Macintosh%3B%20Intel%20Mac%20OS%20X)%20AppleWebKit%2F538.1%20(KHTML.%20like%20Gecko)%20PhantomJS%2F2.1.1%20Safari%2F538.1&sv=3.0.31&ai=A85703AE-17FD-49A6-9298-89BCA43AD59C&user_id=95666b98-17d2-5a87-8062-7840f8d63599&access_token=4cc3001fbcd8d41e576813ef6a196781d453bd7f"
binaryType: "blob"
bufferedAmount: 0
constructor: WebSocketConstructor
extensions: ""
onclose: null
onerror: null
onmessage: null
onopen: null
protocol: ""
readyState: 1
url: "wss://ws.sendbird.com/?p=JS&pv=Mozilla%2F5.0%20(Macintosh%3B%20Intel%20Mac%20OS%20X)%20AppleWebKit%2F538.1%20(KHTML.%20like%20Gecko)%20PhantomJS%2F2.1.1%20Safari%2F538.1&sv=3.0.31&ai=A85703AE-17FD-49A6-9298-89BCA43AD59C&user_id=95666b98-17d2-5a87-8062-7840f8d63599&access_token=4cc3001fbcd8d41e576813ef6a196781d453bd7f"
__proto__: WebSocketPrototype

@JiaLiPassion
Copy link
Collaborator

@rokerkony , please try to modify

            patchOnProperties(proxySocket, ['close', 'error', 'message', 'open'], _global.WebSocket);

to

            patchOnProperties(proxySocket, ['close', 'error', 'message', 'open'], _global.WebSocket.prototype);

to try again.

@rokerkony
Copy link
Author

so no change... now the argument seems to be more correct, but I miss on* methods on it:

CLOSED: 3
CLOSING: 2
CONNECTING: 0
OPEN: 1
__zone_symbol__addEventListener: function addEventListener() {
__zone_symbol__removeEventListener: function removeEventListener() {
addEventListener: function (e, f, capture, secure) {
close: function close() {
dispatchEvent: function dispatchEvent() {
removeEventListener: function (e, f, capture, secure) {
send: function send() {

so it means that prototypeDesc is undefined

@JiaLiPassion
Copy link
Collaborator

@rokerkony , ok...,could you help me check where onopen is defined

  • WebSocket
  • WebSocketPrototype
  • WebSocketPrototype.prototype??

@rokerkony
Copy link
Author

@JiaLiPassion so after some time of investigation I can say that chrome has onopen on WebSocket.prototype and also on the instance new WebSocket(...)

but PhantomJS looks like to have it only on the instance:

WebSocket

CLOSED: 3
CLOSING: 2
CONNECTING: 0
OPEN: 1
length: 1
prototype: WebSocketPrototype
__proto__: Object

WebSocket.prototype

CLOSED: 3
CLOSING: 2
CONNECTING: 0
OPEN: 1
__zone_symbol__addEventListener: function addEventListener() {
__zone_symbol__removeEventListener: function removeEventListener() {
addEventListener: function (e, f, capture, secure) {
close: function close() {
dispatchEvent: function dispatchEvent() {
removeEventListener: function (e, f, capture, secure) {
send: function send() {
__proto__: Object

new WebSocket(...)

URL: "ws://localhost:4200/sockjs-node/493/qgagpfbx/websocket"
binaryType: "blob"
bufferedAmount: 0
constructor: WebSocketConstructor
extensions: ""
onclose: null
onerror: null
onmessage: null
onopen: null
protocol: ""
readyState: 1
url: "ws://localhost:4200/sockjs-node/493/qgagpfbx/websocket"
__proto__: WebSocketPrototype

@JiaLiPassion
Copy link
Collaborator

@rokerkony , I just tried Phantomjs 2.1.14, and the

Object.getOwnPropertyDescriptor(socket, 'onopen') 

return Object{value: null, writable: true, enumerable: true, configurable: false}

so the desc is not configurable. So which version of phantom you are using?

@rokerkony
Copy link
Author

rokerkony commented Jun 29, 2017

exactly, but socket is already an instance

console.log('1:', Object.getOwnPropertyDescriptor(WS, 'onopen'));
var socket = arguments.length > 1 ? new WS(a, b) : new WS(a);
console.log('2:', Object.getOwnPropertyDescriptor(socket, 'onopen'));
console.log('3:', Object.getOwnPropertyDescriptor(_global.WebSocket, 'onopen'));
console.log('4:', Object.getOwnPropertyDescriptor(_global.WebSocket.prototype, 'onopen'));

will output:

1: undefined
2: Object {value: null, writable: true, enumerable: true, configurable: false}
3: undefined
4: undefined 

Versions:
phantomjs-prebuilt@2.1.14
phantomjs@2.1.1

which should be latest version for both packages...
https://github.com/ariya/phantomjs/releases

@JiaLiPassion
Copy link
Collaborator

@rokerkony , yeah, that's why zone.js can't patch onopen, but I don't understand why your modified code would work.

var desc = Object.getOwnPropertyDescriptor(obj, prop) || { enumerable: true, configurable: true };

because try to set non-configurable property descriptor will cause error, I just tested it , it just throw error.

@rokerkony
Copy link
Author

Yeah I understand. But the modified code is not throwing an error for me (not in chrome nor phantom)...

I returned this fallback for now and this is a result of

var desc = Object.getOwnPropertyDescriptor(obj, prop) || { enumerable: true, configurable: true };
...
...
console.log('obj 1:', Object.assign({}, obj));
Object.defineProperty(obj, prop, desc);
console.log('obj 2:', Object.assign({}, obj));

Before patching:

addEventListener: function () {
close: function () {
removeEventListener: function () {
send: function () {
__proto__: Object

After patching:

addEventListener: function () {
close: function () {
onclose: null
onerror: null
onmessage: null
onopen: null
removeEventListener: function () {
send: function () {
__proto__: Object

but it is done in 4 steps for each method separately.

@JiaLiPassion
Copy link
Collaborator

could you print the obj and desc, I think if Object.defineProperty not throw error, that is because desc is undefined not non-configurable. So I would like to confirm that the obj is socket instance or WebSocket.prototype.

@rokerkony
Copy link
Author

actually it is not undefined...

prop: onclose 
desc: Object {enumerable: true, configurable: true, set: function, get: function}
obj1: Object {addEventListener: function, removeEventListener: function, send: function, close: function}
obj2: Object {addEventListener: function, removeEventListener: function, send: function, close: function, onclose: null}

prop: onerror 
desc: Object {enumerable: true, configurable: true, set: function, get: function}
obj1: Object {addEventListener: function, removeEventListener: function, send: function, close: function, onclose: null}
obj2: Object {addEventListener: function, removeEventListener: function, send: function, close: function, onclose: null…}

prop: onmessage 
desc: Object {enumerable: true, configurable: true, set: function, get: function}
obj1: Object {addEventListener: function, removeEventListener: function, send: function, close: function, onclose: null…}
obj2: Object {addEventListener: function, removeEventListener: function, send: function, close: function, onclose: null…}

prop: onopen 
desc: Object {enumerable: true, configurable: true, set: function, get: function}
obj1: Object {addEventListener: function, removeEventListener: function, send: function, close: function, onclose: null…}
obj2: Object {addEventListener: function, removeEventListener: function, send: function, close: function, onclose: null…}

if desc would be undefined it would not pass this condition:

        if (!desc || !desc.configurable) {
            return;
        }

@JiaLiPassion
Copy link
Collaborator

I think you print the information after this line

var desc = Object.getOwnPropertyDescriptor(obj, prop) || { enumerable: true, configurable: true };

is that right?

I think we should print the information before || { enumerable: true, configurable: true };

if (prop === 'onopen') {
  console.log('obj', obj');
console.log('desc', Object.getOwnPropertyDescriptor(obj, prop));
} 
var desc = Object.getOwnPropertyDescriptor(obj, prop) || { enumerable: true, configurable: true };

@rokerkony
Copy link
Author

Ok, so this:

function patchProperty(obj, prop, prototype) {
    var desc = Object.getOwnPropertyDescriptor(obj, prop);
    console.log('obj:', Object.assign({}, obj));
    console.log('desc:', Object.getOwnPropertyDescriptor(obj, prop));

outputs to:

obj: 
Object {addEventListener: function, removeEventListener: function, send: function, close: function}
addEventListener: function () {
close: function () {
removeEventListener: function () {
send: function () {
__proto__: Object

desc: undefined 

in case I will add

var desc = desc || { enumerable: true, configurable: true };

bellow console.log, it will add all on* properties because it will become configurable (not saying it is correct, just that only in this case it is fixing a situation)

@JiaLiPassion
Copy link
Collaborator

@rokerkony , yeah, desc is undefined, and I am still confusing that what the obj is, could you help me to find out that the obj is socket instance or not? And the logic is called from here https://github.com/angular/zone.js/blob/master/dist/zone.js#L2050 ?

@rokerkony
Copy link
Author

It looks like:
obj is an instance of WebSocket, exactly I would assume it is proxySocket variable which is constructed as Object.create(<<< var socket = new WS(...) >>>)
prototype is _global.WebSocket


I have an idea ... seems like Object.create does some magic here :-/

console.log('naaah1', Object.getOwnPropertyDescriptor(socket, 'onopen'));
proxySocket = Object.create(socket);
console.log('naaah2', Object.getOwnPropertyDescriptor(proxySocket, 'onopen'));

it outputs:

naaah1: Object {value: null, writable: true, enumerable: true, configurable: false} vendor.bundle.js:4618
naaah2: undefined 

@JiaLiPassion
Copy link
Collaborator

@rokerkony , I see.
desc become undefined, because proxySocket use socket as it's prototype, so it will not have onopen for it's own.

could you try the attached zone.js.zip?
zone.js.zip

@rokerkony
Copy link
Author

yes! that is working 👍

@JiaLiPassion
Copy link
Collaborator

@rokerkony , ok, thank you for confirm it, I will make a PR to fix this one.

@rokerkony
Copy link
Author

thx for helping

JiaLiPassion added a commit to JiaLiPassion/zone.js that referenced this issue Jun 29, 2017
JiaLiPassion added a commit to JiaLiPassion/zone.js that referenced this issue Jun 29, 2017
JiaLiPassion added a commit to JiaLiPassion/zone.js that referenced this issue Jul 7, 2017
mhevery pushed a commit that referenced this issue Jul 12, 2017
…hantomJS (#826)

* fix(websocket): fix #824, patch websocket onproperties correctly in phantomjs

* add phantomjs test for local and travis
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants