Path: blob/trunk/javascript/selenium-webdriver/test/bidi/generated/network_test.js
11822 views
// Licensed to the Software Freedom Conservancy (SFC) under one1// or more contributor license agreements. See the NOTICE file2// distributed with this work for additional information3// regarding copyright ownership. The SFC licenses this file4// to you under the Apache License, Version 2.0 (the5// "License"); you may not use this file except in compliance6// with the License. You may obtain a copy of the License at7//8// http://www.apache.org/licenses/LICENSE-2.09//10// Unless required by applicable law or agreed to in writing,11// software distributed under the License is distributed on an12// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY13// KIND, either express or implied. See the License for the14// specific language governing permissions and limitations15// under the License.1617'use strict'1819const assert = require('node:assert')20const { suite, ignore, Pages } = require('../../../lib/test')21const { Browser } = require('selenium-webdriver')22const { Network } = require('selenium-webdriver/bidi/generated/network')23const { BrowsingContext } = require('selenium-webdriver/bidi/generated/browsing_context')2425suite(26function (env) {27let driver28let network29let browsingContext30let contextId3132beforeEach(async function () {33driver = await env.builder().build()34network = await Network.create(driver)35browsingContext = await BrowsingContext.create(driver)36contextId = await driver.getWindowHandle()37})3839afterEach(function () {40return driver.quit()41})4243describe('onBeforeRequestSent', function () {44it('receives event when a page is loaded', async function () {45let event = null4647await network.onBeforeRequestSent((params) => {48if (params.request.url.includes('emptyPage') || params.request.url.includes('empty')) {49event = params50}51})5253await browsingContext.navigate({ context: contextId, url: Pages.emptyPage, wait: 'complete' })5455assert.ok(event, 'beforeRequestSent should have fired')56assert.strictEqual(event.request.method, 'GET')57assert.ok(event.request.url)58assert.ok(event.request.headers.length > 0, 'request should have at least one header')59})6061it('receives cookies in beforeRequestSent', async function () {62let cookieEvent = null6364await network.onBeforeRequestSent((params) => {65// Capture the first event that carries our test cookie66if (params.request.cookies && params.request.cookies.some((c) => c.name === 'bidi-test')) {67cookieEvent = params68}69})7071await browsingContext.navigate({ context: contextId, url: Pages.emptyText, wait: 'complete' })72await driver.manage().addCookie({ name: 'bidi-test', value: 'works' })73await browsingContext.navigate({ context: contextId, url: Pages.emptyText, wait: 'complete' })74await driver.wait(() => cookieEvent !== null, 5000)7576assert.ok(cookieEvent, 'beforeRequestSent with bidi-test cookie should have fired')77const cookie = cookieEvent.request.cookies.find((c) => c.name === 'bidi-test')78assert.ok(cookie, 'cookie should appear in request')79assert.strictEqual(cookie.value.value, 'works')80})81})8283describe('onResponseCompleted', function () {84it('receives event when a response completes', async function () {85let event = null8687await network.onResponseCompleted((params) => {88// Capture the first responseCompleted event — no URL filter needed.89if (!event) {90event = params91}92})9394await browsingContext.navigate({ context: contextId, url: Pages.emptyPage, wait: 'complete' })95await driver.wait(() => event !== null, 5000)9697assert.ok(event, 'responseCompleted should have fired')98assert.ok(event.response)99assert.ok(event.response.status >= 200)100assert.ok(event.response.url)101})102})103104describe('onFetchError', function () {105it('receives event on network fetch error', async function () {106let errorEvent = null107108await network.onFetchError((params) => {109errorEvent = params110})111112// Navigate to a non-existent host to trigger a fetch error.113// Use wait: 'none' so the call returns immediately — waiting for114// 'complete' on a non-existent host blocks for the full TCP/DNS115// timeout before the fetchError event can be observed.116await browsingContext117.navigate({ context: contextId, url: 'http://doesnotexist.invalid/', wait: 'none' })118.catch(() => {})119await driver.wait(() => errorEvent !== null, 5000)120121assert.ok(errorEvent, 'fetchError should have fired')122assert.ok(errorEvent.request)123})124})125126describe('addIntercept and continueRequest', function () {127it('can add and remove an intercept', async function () {128const result = await network.addIntercept({129phases: ['beforeRequestSent'],130})131132assert.ok(result.intercept, 'intercept id should be returned')133assert.strictEqual(typeof result.intercept, 'string')134135await network.removeIntercept({ intercept: result.intercept })136})137138it('throws when removing a non-existent intercept', async function () {139await assert.rejects(() => network.removeIntercept({ intercept: 'no-such-intercept-id' }), /no such intercept/)140})141142it('can intercept and continue a request', async function () {143const intercept = await network.addIntercept({144phases: ['beforeRequestSent'],145})146147let counter = 0148await network.onBeforeRequestSent(async (params) => {149if (params.isBlocked) {150counter++151try {152await network.continueRequest({ request: params.request.request })153} catch (_err) {154// ignore — request may already be resolved155}156}157})158159await browsingContext.navigate({ context: contextId, url: Pages.logEntryAdded, wait: 'complete' })160161assert.ok(counter >= 1, 'at least one request should have been intercepted and continued')162await network.removeIntercept({ intercept: intercept.intercept })163})164165it('can intercept by url pattern', async function () {166const result = await network.addIntercept({167phases: ['beforeRequestSent'],168urlPatterns: [{ type: 'string', pattern: Pages.emptyPage }],169})170171assert.ok(result.intercept)172173await network.removeIntercept({ intercept: result.intercept })174})175})176177describe('failRequest', function () {178it('can fail an intercepted request', async function () {179const intercept = await network.addIntercept({180phases: ['beforeRequestSent'],181urlPatterns: [{ type: 'string', pattern: Pages.emptyText }],182})183184let interceptHandled = false185await network.onBeforeRequestSent(async (params) => {186if (params.isBlocked && params.request.url.includes('emptyText') && !interceptHandled) {187interceptHandled = true188try {189await network.failRequest({ request: params.request.request })190} catch (_err) {191// ignore — request may already be gone192}193}194})195196// Navigation will fail because we're blocking it — that's expected197await browsingContext.navigate({ context: contextId, url: Pages.emptyText, wait: 'complete' }).catch(() => {})198199await network.removeIntercept({ intercept: intercept.intercept })200})201})202203describe('setCacheBehavior', function () {204it('can set cache behavior to bypass', async function () {205const contextId = await driver.getWindowHandle()206207const result = await network.setCacheBehavior({208cacheBehavior: 'bypass',209contexts: [contextId],210})211})212213it('can set cache behavior back to default', async function () {214const contextId = await driver.getWindowHandle()215216await network.setCacheBehavior({ cacheBehavior: 'bypass', contexts: [contextId] })217await network.setCacheBehavior({ cacheBehavior: 'default', contexts: [contextId] })218})219220it('can set global cache behavior', async function () {221await network.setCacheBehavior({ cacheBehavior: 'bypass' })222await network.setCacheBehavior({ cacheBehavior: 'default' })223})224})225226describe('setExtraHeaders', function () {227it('can set extra headers for a context', async function () {228const contextId = await driver.getWindowHandle()229230const result = await network.setExtraHeaders({231headers: [{ name: 'x-custom-header', value: { type: 'string', value: 'test-value' } }],232contexts: [contextId],233})234})235236it('can clear extra headers', async function () {237const contextId = await driver.getWindowHandle()238239await network.setExtraHeaders({240headers: [{ name: 'x-custom-header', value: { type: 'string', value: 'test' } }],241contexts: [contextId],242})243await network.setExtraHeaders({244headers: [],245contexts: [contextId],246})247})248})249250describe('onResponseStarted', function () {251it('receives event when a response starts', async function () {252let event = null253254await network.onResponseStarted((params) => {255if (!event) {256event = params257}258})259260await browsingContext.navigate({ context: contextId, url: Pages.emptyPage, wait: 'complete' })261await driver.wait(() => event !== null, 5000)262263assert.ok(event, 'responseStarted should have fired')264assert.ok(event.response)265})266})267},268{ browsers: [Browser.CHROME, Browser.FIREFOX] },269)270271272