Skip to content

Commit

Permalink
[bidi] Add provide response command (#13708)
Browse files Browse the repository at this point in the history
  • Loading branch information
pujagani authored Mar 19, 2024
1 parent 30fbca1 commit 3c783f7
Show file tree
Hide file tree
Showing 6 changed files with 248 additions and 0 deletions.
5 changes: 5 additions & 0 deletions java/src/org/openqa/selenium/bidi/module/Network.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.openqa.selenium.bidi.network.ContinueRequestParameters;
import org.openqa.selenium.bidi.network.ContinueResponseParameters;
import org.openqa.selenium.bidi.network.FetchError;
import org.openqa.selenium.bidi.network.ProvideResponseParameters;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.internal.Require;

Expand Down Expand Up @@ -132,6 +133,10 @@ public void continueResponse(ContinueResponseParameters parameters) {
this.bidi.send(new Command<>("network.continueResponse", parameters.toMap()));
}

public void provideResponse(ProvideResponseParameters parameters) {
this.bidi.send(new Command<>("network.provideResponse", parameters.toMap()));
}

public void onBeforeRequestSent(Consumer<BeforeRequestSent> consumer) {
if (browsingContextIds.isEmpty()) {
this.bidi.addListener(beforeRequestSentEvent, consumer);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// 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.

package org.openqa.selenium.bidi.network;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class ProvideResponseParameters {
private final Map<String, Object> map = new HashMap<>();

public ProvideResponseParameters(String request) {
map.put("request", request);
}

public ProvideResponseParameters body(BytesValue value) {
map.put("body", value.toMap());
return this;
}

public ProvideResponseParameters cookies(List<SetCookieHeader> cookieHeaders) {
List<Map<String, Object>> cookies =
cookieHeaders.stream().map(SetCookieHeader::toMap).collect(Collectors.toList());
map.put("cookies", cookies);
return this;
}

public ProvideResponseParameters headers(List<Header> headers) {
List<Map<String, Object>> headerList =
headers.stream().map(Header::toMap).collect(Collectors.toList());
map.put("headers", headerList);
return this;
}

public ProvideResponseParameters reasonPhrase(String reasonPhrase) {
map.put("reasonPhrase", reasonPhrase);
return this;
}

public ProvideResponseParameters statusCode(int statusCode) {
map.put("statusCode", statusCode);
return this;
}

public Map<String, Object> toMap() {
return map;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
Expand Down Expand Up @@ -132,6 +133,71 @@ void canContinueResponse() throws InterruptedException {
}
}

@Test
@NotYetImplemented(SAFARI)
@NotYetImplemented(IE)
@NotYetImplemented(EDGE)
@NotYetImplemented(FIREFOX)
void canProvideResponse() throws InterruptedException {
try (Network network = new Network(driver)) {
String intercept =
network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));

CountDownLatch latch = new CountDownLatch(1);

network.onBeforeRequestSent(
beforeRequestSent -> {
network.provideResponse(
new ProvideResponseParameters(beforeRequestSent.getRequest().getRequestId()));

latch.countDown();
});

assertThat(intercept).isNotNull();

driver.get(server.whereIs("/bidi/logEntryAdded.html"));

boolean countdown = latch.await(5, TimeUnit.SECONDS);
assertThat(countdown).isTrue();
}
}

@Disabled
@NotYetImplemented(SAFARI)
@NotYetImplemented(IE)
@NotYetImplemented(EDGE)
@NotYetImplemented(FIREFOX)
// TODO: Browsers are yet to implement all parameters. Once implemented, add exhaustive tests.
void canProvideResponseWithAllParameters() throws InterruptedException {
try (Network network = new Network(driver)) {
String intercept =
network.addIntercept(new AddInterceptParameters(InterceptPhase.RESPONSE_STARTED));

CountDownLatch latch = new CountDownLatch(1);

network.onResponseStarted(
responseDetails -> {
network.provideResponse(
new ProvideResponseParameters(responseDetails.getRequest().getRequestId())
.body(
new BytesValue(
BytesValue.Type.STRING,
"<html><head><title>Hello," + " World!</title></head><body/></html>")));

latch.countDown();
});

assertThat(intercept).isNotNull();

driver.get(server.whereIs("/bidi/logEntryAdded.html"));

boolean countdown = latch.await(5, TimeUnit.SECONDS);
assertThat(countdown).isTrue();

assertThat(driver.getPageSource()).contains("Hello");
}
}

@Test
@NotYetImplemented(SAFARI)
@NotYetImplemented(IE)
Expand Down
14 changes: 14 additions & 0 deletions javascript/node/selenium-webdriver/bidi/network.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const { BeforeRequestSent, ResponseStarted, FetchError } = require('./networkTyp
const { AddInterceptParameters } = require('./addInterceptParameters')
const { ContinueResponseParameters } = require('./continueResponseParameters')
const { ContinueRequestParameters } = require('./continueRequestParameters')
const { ProvideResponseParameters } = require('./provideResponseParameters')

class Network {
constructor(driver, browsingContextIds) {
Expand Down Expand Up @@ -196,6 +197,19 @@ class Network {
await this.bidi.send(command)
}

async provideResponse(params) {
if (!(params instanceof ProvideResponseParameters)) {
throw new Error(`Params must be an instance of ProvideResponseParameters. Received:'${params}'`)
}

const command = {
method: 'network.provideResponse',
params: Object.fromEntries(params.asMap()),
}

await this.bidi.send(command)
}

async close() {
await this.bidi.unsubscribe(
'network.beforeRequestSent',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// 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.

const { BytesValue, Header } = require('./networkTypes')

class ProvideResponseParameters {
#map = new Map()

constructor(request) {
this.#map.set('request', request)
}

body(value) {
if (!(value instanceof BytesValue)) {
throw new Error(`Value must be an instance of BytesValue. Received: ${typeof value} with value: ${value}`)
}
this.#map.set('body', Object.fromEntries(value.asMap()))
return this
}

cookies(cookieHeaders) {
const cookies = []
cookieHeaders.forEach((header) => {
if (!(header instanceof Header)) {
throw new Error(`CookieHeader must be an instance of Header. Received:'${header}'`)
}
cookies.push(Object.fromEntries(header.asMap()))
})

this.#map.set('cookies', cookies)
return this
}

headers(headers) {
const headerList = []
headers.forEach((header) => {
if (!(header instanceof Header)) {
throw new Error(`Header must be an instance of Header. Received:'${header}'`)
}
headerList.push(Object.fromEntries(header.asMap()))
})

this.#map.set('headers', headerList)
return this
}

reasonPhrase(reasonPhrase) {
if (typeof reasonPhrase !== 'string') {
throw new Error(`Reason phrase must be a string. Received: '${reasonPhrase})'`)
}
this.#map.set('reasonPhrase', reasonPhrase)
return this
}

statusCode(statusCode) {
if (!Number.isInteger(statusCode)) {
throw new Error(`Status must be an integer. Received:'${statusCode}'`)
}

this.#map.set('statusCode', statusCode)
return this
}

asMap() {
return this.#map
}
}

module.exports = { ProvideResponseParameters }
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const { InterceptPhase } = require('../../bidi/interceptPhase')
const { until } = require('../../index')
const { ContinueRequestParameters } = require('../../bidi/continueRequestParameters')
const { ContinueResponseParameters } = require('../../bidi/continueResponseParameters')
const { ProvideResponseParameters } = require('../../bidi/provideResponseParameters')

suite(
function (env) {
Expand Down Expand Up @@ -147,6 +148,21 @@ suite(

assert.strictEqual(counter, 1)
})

xit('can provide response', async function () {
await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))

let counter = 0

await network.beforeRequestSent(async (event) => {
await network.provideResponse(new ProvideResponseParameters(event.request.request))
counter = counter + 1
})

await driver.get(Pages.logEntryAdded)

assert.strictEqual(counter, 1)
})
})
},
{ browsers: [Browser.FIREFOX] },
Expand Down

0 comments on commit 3c783f7

Please sign in to comment.