Skip to content

Commit

Permalink
Allow multiple network mocks at the same time. (#3621)
Browse files Browse the repository at this point in the history
  • Loading branch information
garg3133 authored Feb 28, 2023
1 parent f1411c1 commit 1756240
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 21 deletions.
13 changes: 13 additions & 0 deletions lib/transport/selenium-webdriver/cdp.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,19 @@ class Cdp {

resetConnection() {
this._connection = undefined;
this._networkMocks = undefined;
}

get networkMocks() {
if (this._networkMocks) {
return this._networkMocks;
}

return this._networkMocks = {};
}

addNetworkMock(url, response) {
this.networkMocks[url] = response;
}
}

Expand Down
49 changes: 28 additions & 21 deletions lib/transport/selenium-webdriver/method-mappings.js
Original file line number Diff line number Diff line change
Expand Up @@ -1105,36 +1105,43 @@ module.exports = class MethodMappings {
const cdpConnection = await cdp.getConnection(this.driver);

const {status=200, headers: headersObject, body: bodyPlain=''} = response;

const headers = [];
if (headersObject) {
for (const [name, value] of Object.entries(headersObject)) {
headers.push({name, value});
}
}

// Convert body to base64
const bodyBase64 = Buffer.from(bodyPlain, 'utf-8').toString('base64');

cdpConnection._wsConnection.on('message', (message) => {
const params = JSON.parse(message);
if (params.method === 'Fetch.requestPaused') {
const requestPausedParams = params['params'];
if (requestPausedParams.request.url === urlToIntercept) {
cdpConnection.execute('Fetch.fulfillRequest', {
requestId: requestPausedParams['requestId'],
responseCode: status,
responseHeaders: headers,
body: bodyBase64
});
} else {
cdpConnection.execute('Fetch.continueRequest', {
requestId: requestPausedParams['requestId']
});

cdp.addNetworkMock(urlToIntercept, {status, headers, body: bodyBase64});

// Add event listener only the first time.
if (Object.keys(cdp.networkMocks).length === 1) {
cdpConnection._wsConnection.on('message', (message) => {
const params = JSON.parse(message);
if (params.method === 'Fetch.requestPaused') {
const requestPausedParams = params['params'];
const requestUrl = requestPausedParams.request.url;

const networkMocks = cdp.networkMocks;
if (Object.keys(networkMocks).includes(requestUrl)) {
const mockResponse = networkMocks[requestUrl];
cdpConnection.execute('Fetch.fulfillRequest', {
requestId: requestPausedParams['requestId'],
responseCode: mockResponse.status,
responseHeaders: mockResponse.headers,
body: mockResponse.body
});
} else {
cdpConnection.execute('Fetch.continueRequest', {
requestId: requestPausedParams['requestId']
});
}
}
}
});
});
}

await cdpConnection.execute(
'Fetch.enable',
{}
Expand Down
75 changes: 75 additions & 0 deletions test/src/api/commands/client/testMockNetworkResponse.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,81 @@ describe('.mockNetworkResponse()', function () {
});
});

it('browser.mockNetworkResponse(urlToIntercept, {status, headers, body}) with multiple mocks', function (done) {
MockServer.addMock({
url: '/session',
response: {
value: {
sessionId: '13521-10219-202',
capabilities: {
browserName: 'chrome',
browserVersion: '92.0'
}
}
},
method: 'POST',
statusCode: 201
}, true);

Nightwatch.initW3CClient({
desiredCapabilities: {
browserName: 'chrome',
'goog:chromeOptions': {}
},
output: process.env.VERBOSE === '1',
silent: false
}).then(client => {
const cdpCommandsExecuted = [];
let timesEventListenerAdded = 0;

cdp.resetConnection();
client.transport.driver.createCDPConnection = function() {
return Promise.resolve({
_wsConnection: {
on: () => {
timesEventListenerAdded++;
}
},
execute: function(command) {
cdpCommandsExecuted.push(command);
}
});
};

client.api.mockNetworkResponse('https://www.google.com/', {
status: 200,
headers: {'Content-Type': 'UTF-8'},
body: 'Hey there!'
});
client.api.mockNetworkResponse('https://www.duckduckgo.com/', {
status: 200,
headers: {'Content-Type': 'UTF-8'},
body: 'Good bye!'
});

client.start(function (err) {
if (err) {
done(err);

return;
}

try {
const mocks = cdp.networkMocks;
assert.deepStrictEqual(Object.keys(mocks), ['https://www.google.com/', 'https://www.duckduckgo.com/']);
assert.strictEqual(mocks['https://www.google.com/'].body, Buffer.from('Hey there!').toString('base64'));
assert.strictEqual(mocks['https://www.duckduckgo.com/'].body, Buffer.from('Good bye!').toString('base64'));

assert.strictEqual(timesEventListenerAdded, 1);
assert.deepStrictEqual(cdpCommandsExecuted, ['Fetch.enable', 'Network.setCacheDisabled', 'Fetch.enable', 'Network.setCacheDisabled']);
done();
} catch (err) {
done(err);
}
});
});
});

it('browser.mockNetworkResponse() with relative url to launch_url', function (done) {
MockServer.addMock({
url: '/session',
Expand Down

0 comments on commit 1756240

Please sign in to comment.