2020-10-29 16:12:30 -07:00
/ * *
* Copyright ( c ) Microsoft Corporation .
*
* Licensed 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 .
* /
2022-03-25 15:05:50 -08:00
import { browserTest as it , expect } from '../config/browserTest' ;
2021-04-05 18:48:46 -07:00
2023-07-25 16:47:04 -07:00
it . skip ( ( { mode } ) = > mode . startsWith ( 'service' ) ) ;
2021-08-19 13:34:32 -07:00
it . beforeEach ( ( { server } ) = > {
server . setRoute ( '/target.html' , async ( req , res ) = > {
res . end ( '<html><title>Served by the proxy</title></html>' ) ;
} ) ;
} ) ;
2021-10-28 07:31:30 -08:00
it ( 'should work when passing the proxy only on the context level' , async ( { browserName , platform , browserType , server , proxyServer } ) = > {
2021-08-19 13:34:32 -07:00
proxyServer . forwardTo ( server . PORT ) ;
2021-07-19 17:50:14 +02:00
let browser ;
try {
browser = await browserType . launch ( {
proxy : undefined ,
} ) ;
const context = await browser . newContext ( {
2021-08-19 13:34:32 -07:00
proxy : { server : ` localhost: ${ proxyServer . PORT } ` }
2021-07-19 17:50:14 +02:00
} ) ;
2021-04-30 00:02:48 +02:00
2021-07-19 17:50:14 +02:00
const page = await context . newPage ( ) ;
await page . goto ( 'http://non-existent.com/target.html' ) ;
2021-08-19 13:34:32 -07:00
expect ( proxyServer . requestUrls ) . toContain ( 'http://non-existent.com/target.html' ) ;
2021-07-19 17:50:14 +02:00
expect ( await page . title ( ) ) . toBe ( 'Served by the proxy' ) ;
} finally {
await browser . close ( ) ;
}
2021-04-30 00:02:48 +02:00
} ) ;
2021-05-09 17:47:20 -07:00
it ( 'should throw for bad server value' , async ( { contextFactory } ) = > {
const error = await contextFactory ( {
2020-10-29 16:12:30 -07:00
// @ts-expect-error server must be a string
proxy : { server : 123 }
} ) . catch ( e = > e ) ;
expect ( error . message ) . toContain ( 'proxy.server: expected string, got number' ) ;
} ) ;
2021-08-19 13:34:32 -07:00
it ( 'should use proxy' , async ( { contextFactory , server , proxyServer } ) = > {
proxyServer . forwardTo ( server . PORT ) ;
2021-05-09 17:47:20 -07:00
const context = await contextFactory ( {
2021-08-19 13:34:32 -07:00
proxy : { server : ` localhost: ${ proxyServer . PORT } ` }
2020-10-29 16:12:30 -07:00
} ) ;
2021-04-05 18:48:46 -07:00
const page = await context . newPage ( ) ;
2020-10-29 16:12:30 -07:00
await page . goto ( 'http://non-existent.com/target.html' ) ;
2021-08-19 13:34:32 -07:00
expect ( proxyServer . requestUrls ) . toContain ( 'http://non-existent.com/target.html' ) ;
2020-10-29 16:12:30 -07:00
expect ( await page . title ( ) ) . toBe ( 'Served by the proxy' ) ;
2021-04-05 18:48:46 -07:00
await context . close ( ) ;
2020-10-29 16:12:30 -07:00
} ) ;
2025-06-19 11:06:48 -07:00
it ( 'should send secure cookies to subdomain.localhost' , async ( { contextFactory , browserName , server , isWindows , proxyServer } ) = > {
2025-06-11 10:07:45 -07:00
proxyServer . forwardTo ( server . PORT ) ;
const context = await contextFactory ( {
proxy : { server : ` localhost: ${ proxyServer . PORT } ` } ,
} ) ;
server . setRoute ( '/set-cookie.html' , async ( req , res ) = > {
res . setHeader ( 'Set-Cookie' , [ ` non-secure=1; HttpOnly ` , ` secure=1; HttpOnly; Secure ` ] ) ;
res . end ( ) ;
} ) ;
server . setRoute ( '/read-cookie.html' , async ( req , res ) = > {
res . setHeader ( 'Content-Type' , ` text/html ` ) ;
res . end ( ` <div>Cookie: ${ req . headers . cookie . split ( ';' ) . map ( c = > c . trim ( ) ) . sort ( ) . join ( '; ' ) } </div> ` ) ;
} ) ;
const page = await context . newPage ( ) ;
await page . goto ( ` http://subdomain.localhost/set-cookie.html ` ) ;
const cookies = await context . cookies ( 'http://subdomain.localhost' ) ;
expect ( cookies . map ( ( { name , domain } ) = > ( { name , domain } ) ) ) . toEqual ( [
{
name : 'non-secure' ,
domain : 'subdomain.localhost' ,
} ,
2025-06-19 11:06:48 -07:00
. . . ( ( browserName === 'webkit' ) && ! isWindows ? [ ] : [ {
2025-06-11 10:07:45 -07:00
name : 'secure' ,
domain : 'subdomain.localhost' ,
} ] ) ,
] ) ;
await page . goto ( ` http://subdomain.localhost/read-cookie.html ` ) ;
await expect ( page . locator ( 'div' ) ) . toHaveText ( browserName === 'webkit' ? 'Cookie: non-secure=1' : 'Cookie: non-secure=1; secure=1' ) ;
await context . close ( ) ;
} ) ;
2022-11-23 09:22:49 -08:00
2024-10-04 08:22:27 -07:00
it ( 'should set cookie for top-level domain' , {
annotation : { type : 'issue' , description : 'https://github.com/microsoft/playwright/issues/18362' }
} , async ( { contextFactory , server , proxyServer , browserName , isLinux } ) = > {
2022-11-23 09:22:49 -08:00
it . fixme ( browserName === 'webkit' && isLinux ) ;
2023-01-27 21:52:34 -08:00
2023-10-17 13:41:23 -07:00
proxyServer . forwardTo ( server . PORT , { allowConnectRequests : true } ) ;
2022-11-23 09:22:49 -08:00
const context = await contextFactory ( {
proxy : { server : ` localhost: ${ proxyServer . PORT } ` }
} ) ;
server . setRoute ( '/empty.html' , ( req , res ) = > {
res . setHeader ( 'Set-Cookie' , ` name=val; Domain=codes; Path=/; ` ) ;
res . end ( ) ;
} ) ;
await context . request . get ( 'http://codes/empty.html' ) ;
const [ cookie ] = await context . cookies ( ) ;
expect ( cookie ) . toBeTruthy ( ) ;
expect ( cookie . name ) . toBe ( 'name' ) ;
expect ( cookie . value ) . toBe ( 'val' ) ;
await context . close ( ) ;
} ) ;
2021-12-10 14:01:56 -08:00
it . describe ( 'should proxy local network requests' , ( ) = > {
for ( const additionalBypass of [ false , true ] ) {
it . describe ( additionalBypass ? 'with other bypasses' : 'by default' , ( ) = > {
for ( const params of [
{
target : 'localhost' ,
description : 'localhost' ,
} ,
{
target : '127.0.0.1' ,
description : 'loopback address' ,
} ,
{
target : '169.254.3.4' ,
description : 'link-local'
}
] ) {
it ( ` ${ params . description } ` , async ( { platform , browserName , contextFactory , server , proxyServer } ) = > {
2024-02-23 14:27:30 -08:00
it . skip ( browserName === 'webkit' && platform === 'darwin' && [ 'localhost' , '127.0.0.1' ] . includes ( params . target ) && additionalBypass , 'Mac webkit does not proxy localhost when bypass rules are set' ) ;
2021-12-10 14:01:56 -08:00
const path = ` /target- ${ additionalBypass } - ${ params . target } .html ` ;
server . setRoute ( path , async ( req , res ) = > {
res . end ( '<html><title>Served by the proxy</title></html>' ) ;
} ) ;
2024-02-23 14:27:30 -08:00
const url = ` http:// ${ params . target } :55555 ${ path } ` ;
2021-12-10 14:01:56 -08:00
proxyServer . forwardTo ( server . PORT ) ;
const context = await contextFactory ( {
proxy : { server : ` localhost: ${ proxyServer . PORT } ` , bypass : additionalBypass ? '1.non.existent.domain.for.the.test' : undefined }
} ) ;
const page = await context . newPage ( ) ;
await page . goto ( url ) ;
expect ( proxyServer . requestUrls ) . toContain ( url ) ;
expect ( await page . title ( ) ) . toBe ( 'Served by the proxy' ) ;
await page . goto ( 'http://1.non.existent.domain.for.the.test/foo.html' ) . catch ( ( ) = > { } ) ;
if ( additionalBypass )
expect ( proxyServer . requestUrls ) . not . toContain ( 'http://1.non.existent.domain.for.the.test/foo.html' ) ;
else
expect ( proxyServer . requestUrls ) . toContain ( 'http://1.non.existent.domain.for.the.test/foo.html' ) ;
await context . close ( ) ;
} ) ;
}
} ) ;
}
} ) ;
2021-10-13 12:10:09 -07:00
it ( 'should use ipv6 proxy' , async ( { contextFactory , server , proxyServer , browserName } ) = > {
it . fail ( browserName === 'firefox' , 'page.goto: NS_ERROR_UNKNOWN_HOST' ) ;
proxyServer . forwardTo ( server . PORT ) ;
const context = await contextFactory ( {
proxy : { server : ` [0:0:0:0:0:0:0:1]: ${ proxyServer . PORT } ` }
} ) ;
const page = await context . newPage ( ) ;
await page . goto ( 'http://non-existent.com/target.html' ) ;
expect ( proxyServer . requestUrls ) . toContain ( 'http://non-existent.com/target.html' ) ;
expect ( await page . title ( ) ) . toBe ( 'Served by the proxy' ) ;
await context . close ( ) ;
} ) ;
2021-08-19 13:34:32 -07:00
it ( 'should use proxy twice' , async ( { contextFactory , server , proxyServer } ) = > {
proxyServer . forwardTo ( server . PORT ) ;
2021-05-09 17:47:20 -07:00
const context = await contextFactory ( {
2021-08-19 13:34:32 -07:00
proxy : { server : ` localhost: ${ proxyServer . PORT } ` }
2020-10-29 16:12:30 -07:00
} ) ;
2021-04-05 18:48:46 -07:00
const page = await context . newPage ( ) ;
2020-10-29 16:12:30 -07:00
await page . goto ( 'http://non-existent.com/target.html' ) ;
2021-08-19 13:34:32 -07:00
expect ( proxyServer . requestUrls ) . toContain ( 'http://non-existent.com/target.html' ) ;
2020-10-29 16:12:30 -07:00
await page . goto ( 'http://non-existent-2.com/target.html' ) ;
2021-08-19 13:34:32 -07:00
expect ( proxyServer . requestUrls ) . toContain ( 'http://non-existent-2.com/target.html' ) ;
2020-10-29 16:12:30 -07:00
expect ( await page . title ( ) ) . toBe ( 'Served by the proxy' ) ;
2021-04-05 18:48:46 -07:00
await context . close ( ) ;
2020-10-29 16:12:30 -07:00
} ) ;
2021-09-27 18:58:08 +02:00
it ( 'should use proxy for second page' , async ( { contextFactory , server , proxyServer } ) = > {
2021-08-19 13:34:32 -07:00
proxyServer . forwardTo ( server . PORT ) ;
2021-05-09 17:47:20 -07:00
const context = await contextFactory ( {
2021-08-19 13:34:32 -07:00
proxy : { server : ` localhost: ${ proxyServer . PORT } ` }
2020-10-29 16:12:30 -07:00
} ) ;
2021-04-05 18:48:46 -07:00
const page = await context . newPage ( ) ;
2020-10-29 16:12:30 -07:00
await page . goto ( 'http://non-existent.com/target.html' ) ;
2021-08-19 13:34:32 -07:00
expect ( proxyServer . requestUrls ) . toContain ( 'http://non-existent.com/target.html' ) ;
2020-10-29 16:12:30 -07:00
expect ( await page . title ( ) ) . toBe ( 'Served by the proxy' ) ;
2021-04-05 18:48:46 -07:00
const page2 = await context . newPage ( ) ;
2021-08-19 13:34:32 -07:00
proxyServer . requestUrls = [ ] ;
2020-10-29 16:12:30 -07:00
await page2 . goto ( 'http://non-existent.com/target.html' ) ;
2021-08-19 13:34:32 -07:00
expect ( proxyServer . requestUrls ) . toContain ( 'http://non-existent.com/target.html' ) ;
2020-10-29 16:12:30 -07:00
expect ( await page2 . title ( ) ) . toBe ( 'Served by the proxy' ) ;
2021-04-05 18:48:46 -07:00
await context . close ( ) ;
2020-10-29 16:12:30 -07:00
} ) ;
2023-02-24 06:34:37 -08:00
it ( 'should use proxy for https urls' , async ( { contextFactory , httpsServer , proxyServer } ) = > {
2021-08-19 07:36:03 -07:00
httpsServer . setRoute ( '/target.html' , async ( req , res ) = > {
2021-08-19 13:34:32 -07:00
res . end ( '<html><title>Served by https server via proxy</title></html>' ) ;
2021-08-19 07:36:03 -07:00
} ) ;
2023-10-17 13:41:23 -07:00
proxyServer . forwardTo ( httpsServer . PORT , { allowConnectRequests : true } ) ;
2021-08-19 07:36:03 -07:00
const context = await contextFactory ( {
ignoreHTTPSErrors : true ,
proxy : { server : ` localhost: ${ proxyServer . PORT } ` }
} ) ;
const page = await context . newPage ( ) ;
await page . goto ( 'https://non-existent.com/target.html' ) ;
2021-08-19 13:34:32 -07:00
expect ( proxyServer . connectHosts ) . toContain ( 'non-existent.com:443' ) ;
expect ( await page . title ( ) ) . toBe ( 'Served by https server via proxy' ) ;
2021-08-19 07:36:03 -07:00
await context . close ( ) ;
} ) ;
2021-09-27 18:58:08 +02:00
it ( 'should work with IP:PORT notion' , async ( { contextFactory , server , proxyServer } ) = > {
2021-08-19 13:34:32 -07:00
proxyServer . forwardTo ( server . PORT ) ;
2021-05-09 17:47:20 -07:00
const context = await contextFactory ( {
2021-08-19 13:34:32 -07:00
proxy : { server : ` 127.0.0.1: ${ proxyServer . PORT } ` }
2020-10-29 16:12:30 -07:00
} ) ;
2021-04-05 18:48:46 -07:00
const page = await context . newPage ( ) ;
2020-10-29 16:12:30 -07:00
await page . goto ( 'http://non-existent.com/target.html' ) ;
2021-08-19 13:34:32 -07:00
expect ( proxyServer . requestUrls ) . toContain ( 'http://non-existent.com/target.html' ) ;
2020-10-29 16:12:30 -07:00
expect ( await page . title ( ) ) . toBe ( 'Served by the proxy' ) ;
2021-04-05 18:48:46 -07:00
await context . close ( ) ;
2020-10-29 16:12:30 -07:00
} ) ;
2021-09-27 18:58:08 +02:00
it ( 'should throw for socks5 authentication' , async ( { contextFactory } ) = > {
2021-05-09 17:47:20 -07:00
const error = await contextFactory ( {
2021-02-08 12:07:45 -08:00
proxy : { server : ` socks5://localhost:1234 ` , username : 'user' , password : 'secret' }
} ) . catch ( e = > e ) ;
expect ( error . message ) . toContain ( 'Browser does not support socks5 proxy authentication' ) ;
} ) ;
2021-09-27 18:58:08 +02:00
it ( 'should throw for socks4 authentication' , async ( { contextFactory } ) = > {
2021-05-09 17:47:20 -07:00
const error = await contextFactory ( {
2021-02-08 12:07:45 -08:00
proxy : { server : ` socks4://localhost:1234 ` , username : 'user' , password : 'secret' }
} ) . catch ( e = > e ) ;
expect ( error . message ) . toContain ( 'Socks4 proxy protocol does not support authentication' ) ;
} ) ;
2021-09-27 18:58:08 +02:00
it ( 'should authenticate' , async ( { contextFactory , server , proxyServer } ) = > {
2021-08-19 13:34:32 -07:00
proxyServer . forwardTo ( server . PORT ) ;
let auth ;
proxyServer . setAuthHandler ( req = > {
auth = req . headers [ 'proxy-authorization' ] ;
return ! ! auth ;
2020-10-29 16:12:30 -07:00
} ) ;
2021-05-09 17:47:20 -07:00
const context = await contextFactory ( {
2021-08-19 13:34:32 -07:00
proxy : { server : ` localhost: ${ proxyServer . PORT } ` , username : 'user' , password : 'secret' }
2020-10-29 16:12:30 -07:00
} ) ;
2021-04-05 18:48:46 -07:00
const page = await context . newPage ( ) ;
2020-10-29 16:12:30 -07:00
await page . goto ( 'http://non-existent.com/target.html' ) ;
2021-08-19 13:34:32 -07:00
expect ( proxyServer . requestUrls ) . toContain ( 'http://non-existent.com/target.html' ) ;
expect ( auth ) . toBe ( 'Basic ' + Buffer . from ( 'user:secret' ) . toString ( 'base64' ) ) ;
expect ( await page . title ( ) ) . toBe ( 'Served by the proxy' ) ;
2021-04-05 18:48:46 -07:00
await context . close ( ) ;
2020-10-29 16:12:30 -07:00
} ) ;
2021-09-27 18:58:08 +02:00
it ( 'should authenticate with empty password' , async ( { contextFactory , server , proxyServer } ) = > {
2021-08-19 13:34:32 -07:00
proxyServer . forwardTo ( server . PORT ) ;
let auth ;
proxyServer . setAuthHandler ( req = > {
auth = req . headers [ 'proxy-authorization' ] ;
return ! ! auth ;
2020-12-21 11:47:13 -08:00
} ) ;
2021-05-09 17:47:20 -07:00
const context = await contextFactory ( {
2021-08-19 13:34:32 -07:00
proxy : { server : ` localhost: ${ proxyServer . PORT } ` , username : 'user' , password : '' }
2020-12-21 11:47:13 -08:00
} ) ;
2021-04-05 18:48:46 -07:00
const page = await context . newPage ( ) ;
2020-12-21 11:47:13 -08:00
await page . goto ( 'http://non-existent.com/target.html' ) ;
2021-08-19 13:34:32 -07:00
expect ( auth ) . toBe ( 'Basic ' + Buffer . from ( 'user:' ) . toString ( 'base64' ) ) ;
expect ( await page . title ( ) ) . toBe ( 'Served by the proxy' ) ;
2021-04-05 18:48:46 -07:00
await context . close ( ) ;
2020-12-21 11:47:13 -08:00
} ) ;
2021-09-27 18:58:08 +02:00
it ( 'should isolate proxy credentials between contexts' , async ( { contextFactory , server , browserName , proxyServer } ) = > {
2021-08-19 13:34:32 -07:00
proxyServer . forwardTo ( server . PORT ) ;
let auth ;
proxyServer . setAuthHandler ( req = > {
auth = req . headers [ 'proxy-authorization' ] ;
return ! ! auth ;
2020-12-21 14:39:11 -08:00
} ) ;
{
2021-05-09 17:47:20 -07:00
const context = await contextFactory ( {
2021-08-19 13:34:32 -07:00
proxy : { server : ` localhost: ${ proxyServer . PORT } ` , username : 'user1' , password : 'secret1' }
2020-12-21 14:39:11 -08:00
} ) ;
const page = await context . newPage ( ) ;
await page . goto ( 'http://non-existent.com/target.html' ) ;
2021-08-19 13:34:32 -07:00
expect ( auth ) . toBe ( 'Basic ' + Buffer . from ( 'user1:secret1' ) . toString ( 'base64' ) ) ;
expect ( await page . title ( ) ) . toBe ( 'Served by the proxy' ) ;
2020-12-21 14:39:11 -08:00
await context . close ( ) ;
}
2021-08-19 13:34:32 -07:00
auth = undefined ;
2020-12-21 14:39:11 -08:00
{
2021-05-09 17:47:20 -07:00
const context = await contextFactory ( {
2021-08-19 13:34:32 -07:00
proxy : { server : ` localhost: ${ proxyServer . PORT } ` , username : 'user2' , password : 'secret2' }
2020-12-21 14:39:11 -08:00
} ) ;
const page = await context . newPage ( ) ;
await page . goto ( 'http://non-existent.com/target.html' ) ;
2021-08-19 13:34:32 -07:00
expect ( await page . title ( ) ) . toBe ( 'Served by the proxy' ) ;
expect ( auth ) . toBe ( 'Basic ' + Buffer . from ( 'user2:secret2' ) . toString ( 'base64' ) ) ;
2020-12-21 14:39:11 -08:00
await context . close ( ) ;
}
} ) ;
2023-09-29 10:45:31 -07:00
it ( 'should exclude patterns' , async ( { contextFactory , server , proxyServer } ) = > {
2021-08-19 13:34:32 -07:00
proxyServer . forwardTo ( server . PORT ) ;
2020-10-29 16:12:30 -07:00
// FYI: using long and weird domain names to avoid ATT DNS hijacking
// that resolves everything to some weird search results page.
//
// @see https://gist.github.com/CollinChaffin/24f6c9652efb3d6d5ef2f5502720ef00
2021-05-09 17:47:20 -07:00
const context = await contextFactory ( {
2021-08-19 13:34:32 -07:00
proxy : { server : ` localhost: ${ proxyServer . PORT } ` , bypass : '1.non.existent.domain.for.the.test, 2.non.existent.domain.for.the.test, .another.test' }
2020-10-29 16:12:30 -07:00
} ) ;
2023-06-30 13:08:18 -07:00
const nonFaviconUrls = ( ) = > {
return proxyServer . requestUrls . filter ( u = > ! u . includes ( 'favicon' ) ) ;
} ;
2020-10-29 16:12:30 -07:00
{
2023-09-29 10:45:31 -07:00
proxyServer . requestUrls = [ ] ;
const page = await context . newPage ( ) ;
await page . goto ( 'http://0.non.existent.domain.for.the.test/target.html' ) ;
expect ( proxyServer . requestUrls ) . toContain ( 'http://0.non.existent.domain.for.the.test/target.html' ) ;
expect ( await page . title ( ) ) . toBe ( 'Served by the proxy' ) ;
await page . close ( ) ;
}
{
proxyServer . requestUrls = [ ] ;
const page = await context . newPage ( ) ;
2020-10-29 16:12:30 -07:00
const error = await page . goto ( 'http://1.non.existent.domain.for.the.test/target.html' ) . catch ( e = > e ) ;
2023-06-30 13:08:18 -07:00
expect ( nonFaviconUrls ( ) ) . toEqual ( [ ] ) ;
2020-10-29 16:12:30 -07:00
expect ( error . message ) . toBeTruthy ( ) ;
2023-09-29 10:45:31 -07:00
await page . close ( ) ;
2020-10-29 16:12:30 -07:00
}
{
2023-09-29 10:45:31 -07:00
proxyServer . requestUrls = [ ] ;
const page = await context . newPage ( ) ;
2020-10-29 16:12:30 -07:00
const error = await page . goto ( 'http://2.non.existent.domain.for.the.test/target.html' ) . catch ( e = > e ) ;
2023-06-30 13:08:18 -07:00
expect ( nonFaviconUrls ( ) ) . toEqual ( [ ] ) ;
2020-10-29 16:12:30 -07:00
expect ( error . message ) . toBeTruthy ( ) ;
2023-09-29 10:45:31 -07:00
await page . close ( ) ;
2020-10-29 16:12:30 -07:00
}
{
2023-09-29 10:45:31 -07:00
proxyServer . requestUrls = [ ] ;
const page = await context . newPage ( ) ;
2020-10-29 16:12:30 -07:00
const error = await page . goto ( 'http://foo.is.the.another.test/target.html' ) . catch ( e = > e ) ;
2023-06-30 13:08:18 -07:00
expect ( nonFaviconUrls ( ) ) . toEqual ( [ ] ) ;
2020-10-29 16:12:30 -07:00
expect ( error . message ) . toBeTruthy ( ) ;
2023-09-29 10:45:31 -07:00
await page . close ( ) ;
2023-06-30 13:08:18 -07:00
}
2023-01-05 10:04:20 -08:00
2020-10-29 16:12:30 -07:00
{
2023-09-29 10:45:31 -07:00
proxyServer . requestUrls = [ ] ;
const page = await context . newPage ( ) ;
2020-10-29 16:12:30 -07:00
await page . goto ( 'http://3.non.existent.domain.for.the.test/target.html' ) ;
2023-06-30 13:08:18 -07:00
expect ( nonFaviconUrls ( ) ) . toContain ( 'http://3.non.existent.domain.for.the.test/target.html' ) ;
2020-10-29 16:12:30 -07:00
expect ( await page . title ( ) ) . toBe ( 'Served by the proxy' ) ;
2023-09-29 10:45:31 -07:00
await page . close ( ) ;
2020-10-29 16:12:30 -07:00
}
2021-04-05 18:48:46 -07:00
await context . close ( ) ;
2020-10-29 16:12:30 -07:00
} ) ;
2021-05-09 17:47:20 -07:00
it ( 'should use socks proxy' , async ( { contextFactory , socksPort } ) = > {
const context = await contextFactory ( {
2020-10-29 16:12:30 -07:00
proxy : { server : ` socks5://localhost: ${ socksPort } ` }
} ) ;
2021-04-05 18:48:46 -07:00
const page = await context . newPage ( ) ;
2020-10-29 16:12:30 -07:00
await page . goto ( 'http://non-existent.com' ) ;
expect ( await page . title ( ) ) . toBe ( 'Served by the SOCKS proxy' ) ;
2021-04-05 18:48:46 -07:00
await context . close ( ) ;
2020-10-29 16:12:30 -07:00
} ) ;
2021-05-09 17:47:20 -07:00
it ( 'should use socks proxy in second page' , async ( { contextFactory , socksPort } ) = > {
const context = await contextFactory ( {
2020-10-29 16:12:30 -07:00
proxy : { server : ` socks5://localhost: ${ socksPort } ` }
} ) ;
2021-04-05 18:48:46 -07:00
const page = await context . newPage ( ) ;
2020-10-29 16:12:30 -07:00
await page . goto ( 'http://non-existent.com' ) ;
expect ( await page . title ( ) ) . toBe ( 'Served by the SOCKS proxy' ) ;
2021-04-05 18:48:46 -07:00
const page2 = await context . newPage ( ) ;
2020-10-29 16:12:30 -07:00
await page2 . goto ( 'http://non-existent.com' ) ;
expect ( await page2 . title ( ) ) . toBe ( 'Served by the SOCKS proxy' ) ;
2021-04-05 18:48:46 -07:00
await context . close ( ) ;
2020-10-29 16:12:30 -07:00
} ) ;
2021-05-09 17:47:20 -07:00
it ( 'does launch without a port' , async ( { contextFactory } ) = > {
const context = await contextFactory ( {
2020-10-29 16:12:30 -07:00
proxy : { server : 'http://localhost' }
} ) ;
2021-04-05 18:48:46 -07:00
await context . close ( ) ;
2020-10-29 16:12:30 -07:00
} ) ;
2024-07-05 13:24:06 +02:00
2024-07-23 09:37:00 +01:00
it ( 'should isolate proxy credentials between contexts on navigation' , async ( { contextFactory , server } ) = > {
2024-07-05 13:24:06 +02:00
it . info ( ) . annotations . push ( { type : 'issue' , description : 'https://github.com/microsoft/playwright/issues/31525' } ) ;
server . setRoute ( '/target.html' , async ( req , res ) = > {
const authHeader = req . headers [ 'proxy-authorization' ] ;
if ( ! authHeader ) {
res . writeHead ( 407 , { 'Proxy-Authenticate' : 'Basic realm="proxy"' } ) ;
res . end ( 'Proxy authorization required' ) ;
return ;
}
const [ username , ] = Buffer . from ( authHeader . split ( ' ' ) [ 1 ] , 'base64' ) . toString ( ) . split ( ':' ) ;
res . writeHead ( 200 , { 'Content-Type' : 'text/html' } ) ;
res . end ( ` Hello <div data-testid=user> ${ username } </div>! \ n ` ) ;
} ) ;
const context1 = await contextFactory ( {
proxy : { server : server.PREFIX , username : 'user1' , password : 'secret1' }
} ) ;
const page1 = await context1 . newPage ( ) ;
await page1 . goto ( 'http://non-existent.com/target.html' ) ;
await expect ( page1 . getByTestId ( 'user' ) ) . toHaveText ( 'user1' ) ;
const context2 = await contextFactory ( {
proxy : { server : server.PREFIX , username : 'user2' , password : 'secret2' }
} ) ;
const page2 = await context2 . newPage ( ) ;
await page2 . goto ( 'http://non-existent.com/target.html' ) ;
await expect ( page2 . getByTestId ( 'user' ) ) . toHaveText ( 'user2' ) ;
await page1 . goto ( 'http://non-existent.com/target.html' ) ;
await expect ( page1 . getByTestId ( 'user' ) ) . toHaveText ( 'user1' ) ;
} ) ;