chore: http credentials send immeidately/unauthorized enum (#31076)

Reference https://github.com/microsoft/playwright-internal/issues/205
Reference https://github.com/microsoft/playwright/issues/30534
This commit is contained in:
Yury Semikhatsky 2024-05-30 10:19:56 -07:00 committed by GitHub
parent d6d373c459
commit 6067b78f88
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 85 additions and 46 deletions

View file

@ -571,7 +571,7 @@ Whether to emulate network being offline. Defaults to `false`. Learn more about
- `username` <[string]> - `username` <[string]>
- `password` <[string]> - `password` <[string]>
- `origin` ?<[string]> Restrain sending http credentials on specific origin (scheme://host:port). - `origin` ?<[string]> Restrain sending http credentials on specific origin (scheme://host:port).
- `sendImmediately` ?<[boolean]> Whether to send `Authorization` header with the first API request. By default, the credentials are sent only when 401 (Unauthorized) response with `WWW-Authenticate` header is received. This option does not affect requests sent from the browser. - `send` ?<[HttpCredentialsSend]<"unauthorized"|"always">> This option only applies to the requests sent from corresponding [APIRequestContext] and does not affect requests sent from the browser. `'always'` - `Authorization` header with basic authentication credentials will be sent with the each API request. `'unauthorized` - the credentials are only sent when 401 (Unauthorized) response with `WWW-Authenticate` header is received. Defaults to `'unauthorized'`.
Credentials for [HTTP authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication). Credentials for [HTTP authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication).
If no origin is specified, the username and password are sent to any servers upon unauthorized responses. If no origin is specified, the username and password are sent to any servers upon unauthorized responses.

View file

@ -334,7 +334,7 @@ scheme.PlaywrightNewRequestParams = tObject({
username: tString, username: tString,
password: tString, password: tString,
origin: tOptional(tString), origin: tOptional(tString),
sendImmediately: tOptional(tBoolean), send: tOptional(tEnum(['always', 'unauthorized'])),
})), })),
proxy: tOptional(tObject({ proxy: tOptional(tObject({
server: tString, server: tString,
@ -548,7 +548,7 @@ scheme.BrowserTypeLaunchPersistentContextParams = tObject({
username: tString, username: tString,
password: tString, password: tString,
origin: tOptional(tString), origin: tOptional(tString),
sendImmediately: tOptional(tBoolean), send: tOptional(tEnum(['always', 'unauthorized'])),
})), })),
deviceScaleFactor: tOptional(tNumber), deviceScaleFactor: tOptional(tNumber),
isMobile: tOptional(tBoolean), isMobile: tOptional(tBoolean),
@ -627,7 +627,7 @@ scheme.BrowserNewContextParams = tObject({
username: tString, username: tString,
password: tString, password: tString,
origin: tOptional(tString), origin: tOptional(tString),
sendImmediately: tOptional(tBoolean), send: tOptional(tEnum(['always', 'unauthorized'])),
})), })),
deviceScaleFactor: tOptional(tNumber), deviceScaleFactor: tOptional(tNumber),
isMobile: tOptional(tBoolean), isMobile: tOptional(tBoolean),
@ -689,7 +689,7 @@ scheme.BrowserNewContextForReuseParams = tObject({
username: tString, username: tString,
password: tString, password: tString,
origin: tOptional(tString), origin: tOptional(tString),
sendImmediately: tOptional(tBoolean), send: tOptional(tEnum(['always', 'unauthorized'])),
})), })),
deviceScaleFactor: tOptional(tNumber), deviceScaleFactor: tOptional(tNumber),
isMobile: tOptional(tBoolean), isMobile: tOptional(tBoolean),
@ -2506,7 +2506,7 @@ scheme.AndroidDeviceLaunchBrowserParams = tObject({
username: tString, username: tString,
password: tString, password: tString,
origin: tOptional(tString), origin: tOptional(tString),
sendImmediately: tOptional(tBoolean), send: tOptional(tEnum(['always', 'unauthorized'])),
})), })),
deviceScaleFactor: tOptional(tNumber), deviceScaleFactor: tOptional(tNumber),
isMobile: tOptional(tBoolean), isMobile: tOptional(tBoolean),

View file

@ -159,7 +159,7 @@ export abstract class APIRequestContext extends SdkObject {
} }
const credentials = this._getHttpCredentials(requestUrl); const credentials = this._getHttpCredentials(requestUrl);
if (credentials?.sendImmediately) if (credentials?.send === 'always')
setBasicAuthorizationHeader(headers, credentials); setBasicAuthorizationHeader(headers, credentials);
const method = params.method?.toUpperCase() || 'GET'; const method = params.method?.toUpperCase() || 'GET';

View file

@ -13393,11 +13393,12 @@ export interface BrowserType<Unused = {}> {
origin?: string; origin?: string;
/** /**
* Whether to send `Authorization` header with the first API request. By default, the credentials are sent only when * This option only applies to the requests sent from corresponding {@link APIRequestContext} and does not affect
* 401 (Unauthorized) response with `WWW-Authenticate` header is received. This option does not affect requests sent * requests sent from the browser. `'always'` - `Authorization` header with basic authentication credentials will be
* from the browser. * sent with the each API request. `'unauthorized` - the credentials are only sent when 401 (Unauthorized) response
* with `WWW-Authenticate` header is received. Defaults to `'unauthorized'`.
*/ */
sendImmediately?: boolean; send?: "unauthorized"|"always";
}; };
/** /**
@ -14930,11 +14931,12 @@ export interface AndroidDevice {
origin?: string; origin?: string;
/** /**
* Whether to send `Authorization` header with the first API request. By default, the credentials are sent only when * This option only applies to the requests sent from corresponding {@link APIRequestContext} and does not affect
* 401 (Unauthorized) response with `WWW-Authenticate` header is received. This option does not affect requests sent * requests sent from the browser. `'always'` - `Authorization` header with basic authentication credentials will be
* from the browser. * sent with the each API request. `'unauthorized` - the credentials are only sent when 401 (Unauthorized) response
* with `WWW-Authenticate` header is received. Defaults to `'unauthorized'`.
*/ */
sendImmediately?: boolean; send?: "unauthorized"|"always";
}; };
/** /**
@ -15661,11 +15663,12 @@ export interface APIRequest {
origin?: string; origin?: string;
/** /**
* Whether to send `Authorization` header with the first API request. By default, the credentials are sent only when * This option only applies to the requests sent from corresponding {@link APIRequestContext} and does not affect
* 401 (Unauthorized) response with `WWW-Authenticate` header is received. This option does not affect requests sent * requests sent from the browser. `'always'` - `Authorization` header with basic authentication credentials will be
* from the browser. * sent with the each API request. `'unauthorized` - the credentials are only sent when 401 (Unauthorized) response
* with `WWW-Authenticate` header is received. Defaults to `'unauthorized'`.
*/ */
sendImmediately?: boolean; send?: "unauthorized"|"always";
}; };
/** /**
@ -16818,11 +16821,12 @@ export interface Browser extends EventEmitter {
origin?: string; origin?: string;
/** /**
* Whether to send `Authorization` header with the first API request. By default, the credentials are sent only when * This option only applies to the requests sent from corresponding {@link APIRequestContext} and does not affect
* 401 (Unauthorized) response with `WWW-Authenticate` header is received. This option does not affect requests sent * requests sent from the browser. `'always'` - `Authorization` header with basic authentication credentials will be
* from the browser. * sent with the each API request. `'unauthorized` - the credentials are only sent when 401 (Unauthorized) response
* with `WWW-Authenticate` header is received. Defaults to `'unauthorized'`.
*/ */
sendImmediately?: boolean; send?: "unauthorized"|"always";
}; };
/** /**
@ -17790,11 +17794,12 @@ export interface Electron {
origin?: string; origin?: string;
/** /**
* Whether to send `Authorization` header with the first API request. By default, the credentials are sent only when * This option only applies to the requests sent from corresponding {@link APIRequestContext} and does not affect
* 401 (Unauthorized) response with `WWW-Authenticate` header is received. This option does not affect requests sent * requests sent from the browser. `'always'` - `Authorization` header with basic authentication credentials will be
* from the browser. * sent with the each API request. `'unauthorized` - the credentials are only sent when 401 (Unauthorized) response
* with `WWW-Authenticate` header is received. Defaults to `'unauthorized'`.
*/ */
sendImmediately?: boolean; send?: "unauthorized"|"always";
}; };
/** /**
@ -20458,11 +20463,12 @@ export interface HTTPCredentials {
origin?: string; origin?: string;
/** /**
* Whether to send `Authorization` header with the first API request. By default, the credentials are sent only when * This option only applies to the requests sent from corresponding {@link APIRequestContext} and does not affect
* 401 (Unauthorized) response with `WWW-Authenticate` header is received. This option does not affect requests sent * requests sent from the browser. `'always'` - `Authorization` header with basic authentication credentials will be
* from the browser. * sent with the each API request. `'unauthorized` - the credentials are only sent when 401 (Unauthorized) response
* with `WWW-Authenticate` header is received. Defaults to `'unauthorized'`.
*/ */
sendImmediately?: boolean; send?: "unauthorized"|"always";
} }
export interface Geolocation { export interface Geolocation {

View file

@ -578,7 +578,7 @@ export type PlaywrightNewRequestParams = {
username: string, username: string,
password: string, password: string,
origin?: string, origin?: string,
sendImmediately?: boolean, send?: 'always' | 'unauthorized',
}, },
proxy?: { proxy?: {
server: string, server: string,
@ -602,7 +602,7 @@ export type PlaywrightNewRequestOptions = {
username: string, username: string,
password: string, password: string,
origin?: string, origin?: string,
sendImmediately?: boolean, send?: 'always' | 'unauthorized',
}, },
proxy?: { proxy?: {
server: string, server: string,
@ -959,7 +959,7 @@ export type BrowserTypeLaunchPersistentContextParams = {
username: string, username: string,
password: string, password: string,
origin?: string, origin?: string,
sendImmediately?: boolean, send?: 'always' | 'unauthorized',
}, },
deviceScaleFactor?: number, deviceScaleFactor?: number,
isMobile?: boolean, isMobile?: boolean,
@ -1032,7 +1032,7 @@ export type BrowserTypeLaunchPersistentContextOptions = {
username: string, username: string,
password: string, password: string,
origin?: string, origin?: string,
sendImmediately?: boolean, send?: 'always' | 'unauthorized',
}, },
deviceScaleFactor?: number, deviceScaleFactor?: number,
isMobile?: boolean, isMobile?: boolean,
@ -1140,7 +1140,7 @@ export type BrowserNewContextParams = {
username: string, username: string,
password: string, password: string,
origin?: string, origin?: string,
sendImmediately?: boolean, send?: 'always' | 'unauthorized',
}, },
deviceScaleFactor?: number, deviceScaleFactor?: number,
isMobile?: boolean, isMobile?: boolean,
@ -1199,7 +1199,7 @@ export type BrowserNewContextOptions = {
username: string, username: string,
password: string, password: string,
origin?: string, origin?: string,
sendImmediately?: boolean, send?: 'always' | 'unauthorized',
}, },
deviceScaleFactor?: number, deviceScaleFactor?: number,
isMobile?: boolean, isMobile?: boolean,
@ -1261,7 +1261,7 @@ export type BrowserNewContextForReuseParams = {
username: string, username: string,
password: string, password: string,
origin?: string, origin?: string,
sendImmediately?: boolean, send?: 'always' | 'unauthorized',
}, },
deviceScaleFactor?: number, deviceScaleFactor?: number,
isMobile?: boolean, isMobile?: boolean,
@ -1320,7 +1320,7 @@ export type BrowserNewContextForReuseOptions = {
username: string, username: string,
password: string, password: string,
origin?: string, origin?: string,
sendImmediately?: boolean, send?: 'always' | 'unauthorized',
}, },
deviceScaleFactor?: number, deviceScaleFactor?: number,
isMobile?: boolean, isMobile?: boolean,
@ -4529,7 +4529,7 @@ export type AndroidDeviceLaunchBrowserParams = {
username: string, username: string,
password: string, password: string,
origin?: string, origin?: string,
sendImmediately?: boolean, send?: 'always' | 'unauthorized',
}, },
deviceScaleFactor?: number, deviceScaleFactor?: number,
isMobile?: boolean, isMobile?: boolean,
@ -4586,7 +4586,7 @@ export type AndroidDeviceLaunchBrowserOptions = {
username: string, username: string,
password: string, password: string,
origin?: string, origin?: string,
sendImmediately?: boolean, send?: 'always' | 'unauthorized',
}, },
deviceScaleFactor?: number, deviceScaleFactor?: number,
isMobile?: boolean, isMobile?: boolean,

View file

@ -456,7 +456,11 @@ ContextOptions:
username: string username: string
password: string password: string
origin: string? origin: string?
sendImmediately: boolean? send:
type: enum?
literals:
- always
- unauthorized
deviceScaleFactor: number? deviceScaleFactor: number?
isMobile: boolean? isMobile: boolean?
hasTouch: boolean? hasTouch: boolean?
@ -674,7 +678,11 @@ Playwright:
username: string username: string
password: string password: string
origin: string? origin: string?
sendImmediately: boolean? send:
type: enum?
literals:
- always
- unauthorized
proxy: proxy:
type: object? type: object?
properties: properties:

View file

@ -435,10 +435,10 @@ it('should return error with wrong credentials', async ({ context, server }) =>
expect(response2.status()).toBe(401); expect(response2.status()).toBe(401);
}); });
it('should support HTTPCredentials.sendImmediately', async ({ contextFactory, server }) => { it('should support HTTPCredentials.sendImmediately for newContext', async ({ contextFactory, server }) => {
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/30534' }); it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/30534' });
const context = await contextFactory({ const context = await contextFactory({
httpCredentials: { username: 'user', password: 'pass', origin: server.PREFIX.toUpperCase(), sendImmediately: true } httpCredentials: { username: 'user', password: 'pass', origin: server.PREFIX.toUpperCase(), send: 'always' }
}); });
{ {
const [serverRequest, response] = await Promise.all([ const [serverRequest, response] = await Promise.all([
@ -459,6 +459,31 @@ it('should support HTTPCredentials.sendImmediately', async ({ contextFactory, se
} }
}); });
it('should support HTTPCredentials.sendImmediately for browser.newPage', async ({ contextFactory, server, browser }) => {
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/30534' });
const page = await browser.newPage({
httpCredentials: { username: 'user', password: 'pass', origin: server.PREFIX.toUpperCase(), send: 'always' }
});
{
const [serverRequest, response] = await Promise.all([
server.waitForRequest('/empty.html'),
page.request.get(server.EMPTY_PAGE)
]);
expect(serverRequest.headers.authorization).toBe('Basic ' + Buffer.from('user:pass').toString('base64'));
expect(response.status()).toBe(200);
}
{
const [serverRequest, response] = await Promise.all([
server.waitForRequest('/empty.html'),
page.request.get(server.CROSS_PROCESS_PREFIX + '/empty.html')
]);
// Not sent to another origin.
expect(serverRequest.headers.authorization).toBe(undefined);
expect(response.status()).toBe(200);
}
await page.close();
});
it('delete should support post data', async ({ context, server }) => { it('delete should support post data', async ({ context, server }) => {
const [request, response] = await Promise.all([ const [request, response] = await Promise.all([
server.waitForRequest('/simple.json'), server.waitForRequest('/simple.json'),

View file

@ -157,7 +157,7 @@ it('should support WWW-Authenticate: Basic', async ({ playwright, server }) => {
it('should support HTTPCredentials.sendImmediately', async ({ playwright, server }) => { it('should support HTTPCredentials.sendImmediately', async ({ playwright, server }) => {
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/30534' }); it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/30534' });
const request = await playwright.request.newContext({ const request = await playwright.request.newContext({
httpCredentials: { username: 'user', password: 'pass', origin: server.PREFIX.toUpperCase(), sendImmediately: true } httpCredentials: { username: 'user', password: 'pass', origin: server.PREFIX.toUpperCase(), send: 'always' }
}); });
{ {
const [serverRequest, response] = await Promise.all([ const [serverRequest, response] = await Promise.all([