Skip to content

Commit

Permalink
[js] Implement network request interceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
AutomatedTester committed Sep 17, 2021
1 parent a45202d commit 7e11db8
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 14 deletions.
89 changes: 89 additions & 0 deletions javascript/node/selenium-webdriver/devtools/networkinterceptor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

class HttpResponse {
/**
* Creates a HTTP Response that will be used to
* mock out network interceptions.
* @param {*} urlToIntercept
*/
constructor(urlToIntercept = "") {
this.returnBody = ""
this.returnHeaders = []
this.returnMethod = "GET"
this.returnStatus = 200
this.urlToIntercept = urlToIntercept
}

/**
* Add headers that will be returned when we intercept
* a HTTP Request
* @param {*} header
* @param {*} value
*/
addHeaders(header, value) {
this.returnHeaders.push({ name: header, value: value })
}

get headers() {
return this.returnHeaders
}

/**
* Set the STATUS value of the returned HTTP Request
* @param {*} value
*/
set status(value) {
// Add in check that his should be a number
this.returnStatus = value
}

get status() {
return this.returnStatus
}

/**
* Sets the value of the body of the HTTP Request that
* will be returned.
* @param {*} value
*/
set body(value) {
this.returnBody = value
}

get body() {
let buff = Buffer.from(this.returnBody, "utf-8")
return buff.toString("base64")
}

/**
* Sets the method of the HTTP Request
* @param {*} value the method of the request.
*/
set method(value) {
this.returnMethod = value
}

/**
* Returns the Method to be used in the intercept
*/
get method() {
return this.returnMethod
}

}
exports.HttpResponse = HttpResponse
82 changes: 68 additions & 14 deletions javascript/node/selenium-webdriver/lib/webdriver.js
Original file line number Diff line number Diff line change
Expand Up @@ -1246,14 +1246,6 @@ class WebDriver {
* @param connection CDP Connection
*/
async register(username, password, connection) {
await connection.execute(
'Network.setCacheDisabled',
this.getRandomNumber(1, 10),
{
cacheDisabled: true,
},
null
)

this._wsConnection.on('message', (message) => {
const params = JSON.parse(message)
Expand Down Expand Up @@ -1292,21 +1284,77 @@ class WebDriver {
},
null
)
await connection.execute(
'Network.setCacheDisabled',
this.getRandomNumber(1, 10),
{
cacheDisabled: true,
},
null
)
}

/**
* Handle Network interception requests
* @param connection WebSocket connection to the browser
* @param httpResponse Object representing what we are intercepting
* as well as what should be returned.
* @param callback callback called when we intercept requests.
*/
async onIntercept(connection, httpResponse, callback) {

this._wsConnection.on('message', (message) => {
const params = JSON.parse(message)
if (params.method === 'Fetch.requestPaused') {
const requestPausedParams = params['params']
if (requestPausedParams.request.url == httpResponse.urlToIntercept) {
connection.execute(
'Fetch.continueRequest',
this.getRandomNumber(1, 10),
{
requestId: requestPausedParams['requestId'],
url: httpResponse.urlToIntercept,
method: httpResponse.method,
headers: httpResponse.headers,
postData: httpResponse.body
}
)
callback()
} else {
connection.execute(
'Fetch.continueRequest',
this.getRandomNumber(1, 10),
{
requestId: requestPausedParams['requestId'],
}
)
}
}
})

await connection.execute(
'Fetch.enable',
1,
{},
null
)
await connection.execute(
'Network.setCacheDisabled',
this.getRandomNumber(1, 10),
{
cacheDisabled: true,
},
null
)
}
/**
*
* @param connection
* @param callback
* @returns {Promise<void>}
*/
async onLogEvent(connection, callback) {
await connection.execute(
'Runtime.enable',
this.getRandomNumber(1, 10),
{},
null
)


this._wsConnection.on('message', (message) => {
const params = JSON.parse(message)
Expand All @@ -1322,6 +1370,12 @@ class WebDriver {
callback(event)
}
})
await connection.execute(
'Runtime.enable',
this.getRandomNumber(1, 10),
{},
null
)
}

/**
Expand Down
17 changes: 17 additions & 0 deletions javascript/node/selenium-webdriver/test/devtools_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
const assert = require('assert')
const { Browser, until } = require('..')
const fileServer = require('../lib/test/fileserver')
const { HttpResponse } = require('../devtools/networkontor')
const { Pages, ignore, suite } = require('../lib/test')

suite(
Expand Down Expand Up @@ -123,6 +124,22 @@ suite(
assert.strictEqual(source.includes('Access granted!'), true)
})
})

describe("Network Interception", function () {
ignore(browsers(Browser.SAFARI, Browser.FIREFOX)).
it('Allows network requests to be captured and mocked', async function () {
const connection = await driver.createCDPConnection('page')
let url = fileServer.whereIs("/cheese")
let httpResponse = new HttpResponse(url)
httpResponse.addHeaders("Content-Type", "UTF-8")
httpResponse.body = "sausages"
await driver.onIntercept(connection, httpResponse, async function () {
let body = await driver.getPageSource()
assert.strictEqual(body.includes("sausages"), true, `Body contains: ${body}`)
})
driver.get(url)
})
})
},
{ browsers: ['chrome', 'firefox'] }
)

0 comments on commit 7e11db8

Please sign in to comment.