diff --git a/docs/api.md b/docs/api.md index 076138ffae..c8227dc4a8 100644 --- a/docs/api.md +++ b/docs/api.md @@ -19,7 +19,6 @@ - [class: Request](#class-request) - [class: Response](#class-response) - [class: Selectors](#class-selectors) -- [class: WebSocket](#class-websocket) - [class: TimeoutError](#class-timeouterror) - [class: Accessibility](#class-accessibility) - [class: Coverage](#class-coverage) @@ -445,7 +444,6 @@ page.removeListener('request', logRequest); - [event: 'requestfailed'](#event-requestfailed) - [event: 'requestfinished'](#event-requestfinished) - [event: 'response'](#event-response) -- [event: 'websocket'](#event-websocket) - [event: 'workercreated'](#event-workercreated) - [event: 'workerdestroyed'](#event-workerdestroyed) - [page.$(selector)](#pageselector) @@ -618,11 +616,6 @@ Emitted when a request finishes successfully. Emitted when a [response] is received. -#### event: 'websocket' -- <[WebSocket]> websocket - -Emitted when a <[WebSocket]> is opened. - #### event: 'workercreated' - <[Worker]> @@ -3171,67 +3164,6 @@ const { selectors, firefox } = require('playwright'); // Or 'chromium' or 'webk })(); ``` -### class: WebSocket - -The [WebSocket] class represents websocket connections in the page. - - -- [event: 'close'](#event-close-2) -- [event: 'error'](#event-error) -- [event: 'messagereceived'](#event-messagereceived) -- [event: 'messagesent'](#event-messagesent) -- [event: 'open'](#event-open) -- [webSocket.requestHeaders()](#websocketrequestheaders) -- [webSocket.responseHeaders()](#websocketresponseheaders) -- [webSocket.status()](#websocketstatus) -- [webSocket.statusText()](#websocketstatustext) -- [webSocket.url()](#websocketurl) - - -#### event: 'close' - -Fired when the websocket closes. - -#### event: 'error' -- <[String]> the error message - -Fired when the websocket has an error. - -#### event: 'messagereceived' -- <[Buffer]|[String]> data recieved - -Fired when the websocket recieves a message. - -#### event: 'messagesent' -- <[Buffer]|[String]> data recieved - -Fired when the websocket sends a message. - -#### event: 'open' - -Fired when the websocket opens. - -#### webSocket.requestHeaders() -- returns: <[Promise]<[Object]>> - -#### webSocket.responseHeaders() -- returns: <[Promise]<[Object]>> - -#### webSocket.status() -- returns: <[number]> - -Contains the status code of the WebSocket (e.g., 200 for a success). - -#### webSocket.statusText() -- returns: <[string]> - -Contains the status text of the WebSocket (e.g. usually an "OK" for a success). - -#### webSocket.url() -- returns: <[string]> - -Contains the URL of the WebSocket. - ### class: TimeoutError * extends: [Error] @@ -3431,7 +3363,7 @@ If the function passed to the `worker.evaluateHandle` returns a [Promise], then ### class: BrowserServer -- [event: 'close'](#event-close-3) +- [event: 'close'](#event-close-2) - [browserServer.close()](#browserserverclose) - [browserServer.kill()](#browserserverkill) - [browserServer.process()](#browserserverprocess) diff --git a/src/api.ts b/src/api.ts index 9c85edce7e..fab3403693 100644 --- a/src/api.ts +++ b/src/api.ts @@ -24,7 +24,7 @@ export { TimeoutError } from './errors'; export { Frame } from './frames'; export { Keyboard, Mouse } from './input'; export { JSHandle } from './javascript'; -export { Request, Response, WebSocket } from './network'; +export { Request, Response } from './network'; export { Coverage, FileChooser, Page, Worker } from './page'; export { Selectors } from './selectors'; diff --git a/src/chromium/crNetworkManager.ts b/src/chromium/crNetworkManager.ts index fad536e1ab..608ca460e7 100644 --- a/src/chromium/crNetworkManager.ts +++ b/src/chromium/crNetworkManager.ts @@ -52,13 +52,6 @@ export class CRNetworkManager { helper.addEventListener(session, 'Network.responseReceived', this._onResponseReceived.bind(this)), helper.addEventListener(session, 'Network.loadingFinished', this._onLoadingFinished.bind(this)), helper.addEventListener(session, 'Network.loadingFailed', this._onLoadingFailed.bind(this)), - helper.addEventListener(session, 'Network.webSocketCreated', e => this._page._frameManager.onWebSocketCreated(e.requestId, e.url)), - helper.addEventListener(session, 'Network.webSocketWillSendHandshakeRequest', e => this._page._frameManager.onWebSocketRequest(e.requestId, e.request.headers)), - helper.addEventListener(session, 'Network.webSocketHandshakeResponseReceived', e => this._page._frameManager.onWebSocketResponse(e.requestId, e.response.status, e.response.statusText, e.response.headers)), - helper.addEventListener(session, 'Network.webSocketFrameSent', e => e.response.payloadData && this._page._frameManager.onWebSocketFrameSent(e.requestId, e.response.opcode, e.response.payloadData)), - helper.addEventListener(session, 'Network.webSocketFrameReceived', e => e.response.payloadData && this._page._frameManager.webSocketFrameReceived(e.requestId, e.response.opcode, e.response.payloadData)), - helper.addEventListener(session, 'Network.webSocketClosed', e => this._page._frameManager.webSocketClosed(e.requestId)), - helper.addEventListener(session, 'Network.webSocketFrameError', e => this._page._frameManager.webSocketError(e.requestId, e.errorMessage)), ]; } diff --git a/src/events.ts b/src/events.ts index 6057f799d0..c3b2d353cd 100644 --- a/src/events.ts +++ b/src/events.ts @@ -46,16 +46,7 @@ export const Events = { FrameNavigated: 'framenavigated', Load: 'load', Popup: 'popup', - WebSocket: 'websocket', WorkerCreated: 'workercreated', WorkerDestroyed: 'workerdestroyed', }, - - WebSocket: { - Close: 'close', - Error: 'error', - MessageReceived: 'messagereceived', - MessageSent: 'messagesent', - Open: 'open', - } }; diff --git a/src/frames.ts b/src/frames.ts index eb5db37217..b0abddf51b 100644 --- a/src/frames.ts +++ b/src/frames.ts @@ -58,7 +58,6 @@ type ConsoleTagHandler = () => void; export class FrameManager { private _page: Page; private _frames = new Map(); - private _webSockets = new Map(); private _mainFrame: Frame; readonly _lifecycleWatchers = new Set<() => void>(); readonly _consoleMessageTags = new Map(); @@ -120,7 +119,6 @@ export class FrameManager { for (const watcher of frame._documentWatchers) watcher(documentId); this.clearFrameLifecycle(frame); - this.clearWebSockets(frame); if (!initial) this._page.emit(Events.Page.FrameNavigated, frame); } @@ -182,13 +180,6 @@ export class FrameManager { this._startNetworkIdleTimer(frame, 'networkidle2'); } - clearWebSockets(frame: Frame) { - // TODO: attributet sockets to frames. - if (frame.parentFrame()) - return; - this._webSockets.clear(); - } - requestStarted(request: network.Request) { this._inflightRequestStarted(request); const frame = request.frame(); @@ -228,50 +219,6 @@ export class FrameManager { this._page.emit(Events.Page.RequestFailed, request); } - onWebSocketCreated(requestId: string, url: string) { - const ws = new network.WebSocket(url); - this._webSockets.set(requestId, ws); - } - - onWebSocketRequest(requestId: string, headers: network.Headers) { - const ws = this._webSockets.get(requestId); - if (ws) { - ws._requestSent(headers); - this._page.emit(Events.Page.WebSocket, ws); - } - } - - onWebSocketResponse(requestId: string, status: number, statusText: string, headers: network.Headers) { - const ws = this._webSockets.get(requestId); - if (ws) - ws._responseReceived(status, statusText, headers); - } - - onWebSocketFrameSent(requestId: string, opcode: number, data: string) { - const ws = this._webSockets.get(requestId); - if (ws) - ws._frameSent(opcode, data); - } - - webSocketFrameReceived(requestId: string, opcode: number, data: string) { - const ws = this._webSockets.get(requestId); - if (ws) - ws._frameReceived(opcode, data); - } - - webSocketClosed(requestId: string) { - const ws = this._webSockets.get(requestId); - if (ws) - ws._closed(); - this._webSockets.delete(requestId); - } - - webSocketError(requestId: string, errorMessage: string): void { - const ws = this._webSockets.get(requestId); - if (ws) - ws._error(errorMessage); - } - provisionalLoadFailed(frame: Frame, documentId: string, error: string) { for (const watcher of frame._documentWatchers) watcher(documentId, new Error(error)); diff --git a/src/network.ts b/src/network.ts index b93dc007e8..1aa5518e04 100644 --- a/src/network.ts +++ b/src/network.ts @@ -17,7 +17,6 @@ import * as frames from './frames'; import { assert } from './helper'; import * as platform from './platform'; -import { Events } from './events'; export type NetworkCookie = { name: string, @@ -308,70 +307,6 @@ export interface RequestDelegate { continue(overrides: { method?: string; headers?: Headers; postData?: string; }): Promise; } -export class WebSocket extends platform.EventEmitter { - private _url: string; - _status: number | null = null; - _statusText: string | null = null; - _requestHeaders: Headers | null = null; - _responseHeaders: Headers | null = null; - - constructor(url: string) { - super(); - this._url = url; - } - - url(): string { - return this._url; - } - - status(): number | null { - return this._status; - } - - statusText(): string | null { - return this._statusText; - } - - requestHeaders(): Headers | null { - return this._requestHeaders; - } - - responseHeaders(): Headers | null { - return this._responseHeaders; - } - - _requestSent(headers: Headers) { - this._requestHeaders = {}; - for (const [name, value] of Object.entries(headers)) - this._requestHeaders[name.toLowerCase()] = value; - } - - _responseReceived(status: number, statusText: string, headers: Headers) { - this._status = status; - this._statusText = statusText; - this._responseHeaders = {}; - for (const [name, value] of Object.entries(headers)) - this._responseHeaders[name.toLowerCase()] = value; - this.emit(Events.WebSocket.Open); - } - - _frameSent(opcode: number, data: string) { - this.emit(Events.WebSocket.MessageSent, opcode === 2 ? Buffer.from(data, 'base64') : data); - } - - _frameReceived(opcode: number, data: string) { - this.emit(Events.WebSocket.MessageReceived, opcode === 2 ? Buffer.from(data, 'base64') : data); - } - - _error(errorMessage: string) { - this.emit(Events.WebSocket.Error, errorMessage); - } - - _closed() { - this.emit(Events.WebSocket.Close); - } -} - // List taken from https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml with extra 306 and 418 codes. export const STATUS_TEXTS: { [status: string]: string } = { '100': 'Continue', diff --git a/src/webkit/wkPage.ts b/src/webkit/wkPage.ts index dc11ae65b6..4ce2f353af 100644 --- a/src/webkit/wkPage.ts +++ b/src/webkit/wkPage.ts @@ -208,13 +208,6 @@ export class WKPage implements PageDelegate { helper.addEventListener(this._session, 'Network.responseReceived', e => this._onResponseReceived(e)), helper.addEventListener(this._session, 'Network.loadingFinished', e => this._onLoadingFinished(e)), helper.addEventListener(this._session, 'Network.loadingFailed', e => this._onLoadingFailed(e)), - helper.addEventListener(this._session, 'Network.webSocketCreated', e => this._page._frameManager.onWebSocketCreated(e.requestId, e.url)), - helper.addEventListener(this._session, 'Network.webSocketWillSendHandshakeRequest', e => this._page._frameManager.onWebSocketRequest(e.requestId, e.request.headers)), - helper.addEventListener(this._session, 'Network.webSocketHandshakeResponseReceived', e => this._page._frameManager.onWebSocketResponse(e.requestId, e.response.status, e.response.statusText, e.response.headers)), - helper.addEventListener(this._session, 'Network.webSocketFrameSent', e => e.response.payloadData && this._page._frameManager.onWebSocketFrameSent(e.requestId, e.response.opcode, e.response.payloadData)), - helper.addEventListener(this._session, 'Network.webSocketFrameReceived', e => e.response.payloadData && this._page._frameManager.webSocketFrameReceived(e.requestId, e.response.opcode, e.response.payloadData)), - helper.addEventListener(this._session, 'Network.webSocketClosed', e => this._page._frameManager.webSocketClosed(e.requestId)), - helper.addEventListener(this._session, 'Network.webSocketFrameError', e => this._page._frameManager.webSocketError(e.requestId, e.errorMessage)), ]; } diff --git a/test/network.spec.js b/test/network.spec.js index d5c915ae6c..93ec7d7b57 100644 --- a/test/network.spec.js +++ b/test/network.spec.js @@ -341,116 +341,4 @@ module.exports.describe = function({testRunner, expect, MAC, WIN, FFOX, CHROMIUM expect(error.message).toBe('Expected value of header "foo" to be String, but "number" is found.'); }); }); - - false && describe.skip(FFOX)('WebSocket', function() { - it('should work', async({page, server}) => { - const value = await page.evaluate((port) => { - let cb; - const result = new Promise(f => cb = f); - const ws = new WebSocket('ws://localhost:' + port + '/ws'); - ws.addEventListener('message', data => { ws.close(); cb(data.data); }); - return result; - }, server.PORT); - expect(value).toBe('incoming'); - }); - it('should emit open/close events', async({page, server}) => { - let socketClosed; - const socketClosePromise = new Promise(f => socketClosed = f); - const log = []; - page.on('websocket', ws => { - ws.on('open', () => log.push(`open<${ws.url()}>`)); - ws.on('close', () => { log.push('close'); socketClosed(); }); - }); - page.evaluate((port) => { - const ws = new WebSocket('ws://localhost:' + port + '/ws'); - ws.addEventListener('open', () => ws.close()); - }, server.PORT); - await socketClosePromise; - expect(log.join(':')).toBe(`open:close`); - }); - it('should expose status', async({page, server}) => { - let callback; - const result = new Promise(f => callback = f); - page.on('websocket', ws => ws.on('open', () => callback(ws))); - page.evaluate((port) => { - const ws = new WebSocket('ws://localhost:' + port + '/ws'); - ws.addEventListener('open', () => ws.close()); - }, server.PORT); - const ws = await result; - expect(ws.status()).toBe(101); - expect(ws.statusText()).toBe('Switching Protocols'); - }); - it('should emit error', async({page, server}) => { - let callback; - const result = new Promise(f => callback = f); - page.on('websocket', ws => ws.on('error', callback)); - page.evaluate((port) => { - new WebSocket('ws://localhost:' + port + '/bogus-ws'); - }, server.PORT); - const message = await result; - expect(message).toContain('Unexpected response code: 400'); - }); - it('should emit frame events', async({page, server}) => { - let socketClosed; - const socketClosePromise = new Promise(f => socketClosed = f); - const log = []; - page.on('websocket', ws => { - ws.on('open', () => log.push('open')); - ws.on('messageSent', d => log.push('sent<' + d + '>')); - ws.on('messageReceived', d => log.push('received<' + d + '>')); - ws.on('close', () => { log.push('close'); socketClosed(); }); - }); - page.evaluate((port) => { - const ws = new WebSocket('ws://localhost:' + port + '/ws'); - ws.addEventListener('open', () => ws.send('outgoing')); - ws.addEventListener('message', () => { ws.close(); }); - }, server.PORT); - await socketClosePromise; - expect(log.join(':')).toBe('open:sent:received:close'); - }); - it('should emit binary frame events', async({page, server}) => { - let doneCallback; - const donePromise = new Promise(f => doneCallback = f); - const sent = []; - page.on('websocket', ws => { - ws.on('close', doneCallback); - ws.on('messageSent', d => sent.push(d)); - }); - page.evaluate((port) => { - const ws = new WebSocket('ws://localhost:' + port + '/ws'); - ws.addEventListener('open', () => { - const binary = new Uint8Array(5); - for (let i = 0; i < 5; ++i) - binary[i] = i; - ws.send('text'); - ws.send(binary); - ws.close(); - }); - }, server.PORT); - await donePromise; - expect(sent[0]).toBe('text'); - for (let i = 0; i < 5; ++i) - expect(sent[1][i]).toBe(i); - }); - it('should report headers', async({page, server}) => { - let socketClosed; - let requestHeaders; - let responseHeaders; - const socketClosePromise = new Promise(f => socketClosed = f); - page.on('websocket', ws => { - requestHeaders = ws.requestHeaders(); - ws.on('open', () => { - responseHeaders = ws.responseHeaders(); - }); - ws.on('close', socketClosed); - }); - page.evaluate((port) => { - const ws = new WebSocket('ws://localhost:' + port + '/ws'); - ws.addEventListener('open', () => ws.close()); - }, server.PORT); - await socketClosePromise; - expect(requestHeaders['connection']).toBe('Upgrade'); - expect(responseHeaders['upgrade']).toBe('websocket'); - }); - }); };