Skip to content

Commit 671cfa0

Browse files
fix(types): support objects with typed keys and values (microsoft#1752)
There are a few places in the API where we use objects as maps. This patch adds them to docs and the types. For `env`, we accept booleans and numbers as well because they are often used for their string values.
1 parent 793586e commit 671cfa0

File tree

6 files changed

+36
-18
lines changed

6 files changed

+36
-18
lines changed

docs/api.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ Indicates that the browser is connected.
211211
- `accuracy` <[number]> Non-negative accuracy value. Defaults to `0`.
212212
- `locale` <[string]> Specify user locale, for example `en-GB`, `de-DE`, etc. Locale will affect `navigator.language` value, `Accept-Language` request header value as well as number and date formatting rules.
213213
- `permissions` <[Array]<[string]>> A list of permissions to grant to all pages in this context. See [browserContext.grantPermissions](#browsercontextgrantpermissionspermissions-options) for more details.
214-
- `extraHTTPHeaders` <[Object]> An object containing additional HTTP headers to be sent with every request. All header values must be strings.
214+
- `extraHTTPHeaders` <[Object]<[string], [string]>> An object containing additional HTTP headers to be sent with every request. All header values must be strings.
215215
- `offline` <[boolean]> Whether to emulate network being offline. Defaults to `false`.
216216
- `httpCredentials` <[Object]> Credentials for [HTTP authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication).
217217
- `username` <[string]>
@@ -253,7 +253,7 @@ Creates a new browser context. It won't share cookies/cache with other browser c
253253
- `accuracy` <[number]> Non-negative accuracy value. Defaults to `0`.
254254
- `locale` <[string]> Specify user locale, for example `en-GB`, `de-DE`, etc. Locale will affect `navigator.language` value, `Accept-Language` request header value as well as number and date formatting rules.
255255
- `permissions` <[Array]<[string]>> A list of permissions to grant to all pages in this context. See [browserContext.grantPermissions](#browsercontextgrantpermissionspermissions-options) for more details.
256-
- `extraHTTPHeaders` <[Object]> An object containing additional HTTP headers to be sent with every request. All header values must be strings.
256+
- `extraHTTPHeaders` <[Object]<[string], [string]>> An object containing additional HTTP headers to be sent with every request. All header values must be strings.
257257
- `offline` <[boolean]> Whether to emulate network being offline. Defaults to `false`.
258258
- `httpCredentials` <[Object]> Credentials for [HTTP authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication).
259259
- `username` <[string]>
@@ -544,7 +544,7 @@ This setting will change the default maximum time for all the methods accepting
544544
> **NOTE** [`page.setDefaultNavigationTimeout`](#pagesetdefaultnavigationtimeouttimeout), [`page.setDefaultTimeout`](#pagesetdefaulttimeouttimeout) and [`browserContext.setDefaultNavigationTimeout`](#browsercontextsetdefaultnavigationtimeouttimeout) take priority over [`browserContext.setDefaultTimeout`](#browsercontextsetdefaulttimeouttimeout).
545545
546546
#### browserContext.setExtraHTTPHeaders(headers)
547-
- `headers` <[Object]> An object containing additional HTTP headers to be sent with every request. All header values must be strings.
547+
- `headers` <[Object]<[string], [string]>> An object containing additional HTTP headers to be sent with every request. All header values must be strings.
548548
- returns: <[Promise]>
549549

550550
The extra HTTP headers will be sent with every request initiated by any page in the context. These headers are merged with page-specific extra HTTP headers set with [page.setExtraHTTPHeaders()](#pagesetextrahttpheadersheaders). If page overrides a particular header, page-specific header value will be used instead of the browser context header value.
@@ -1552,7 +1552,7 @@ This setting will change the default maximum time for all the methods accepting
15521552
> **NOTE** [`page.setDefaultNavigationTimeout`](#pagesetdefaultnavigationtimeouttimeout) takes priority over [`page.setDefaultTimeout`](#pagesetdefaulttimeouttimeout).
15531553
15541554
#### page.setExtraHTTPHeaders(headers)
1555-
- `headers` <[Object]> An object containing additional HTTP headers to be sent with every request. All header values must be strings.
1555+
- `headers` <[Object]<[string], [string]>> An object containing additional HTTP headers to be sent with every request. All header values must be strings.
15561556
- returns: <[Promise]>
15571557

15581558
The extra HTTP headers will be sent with every request the page initiates.
@@ -3308,7 +3308,7 @@ page.on('requestfailed', request => {
33083308
- returns: <[Frame]> A [Frame] that initiated this request.
33093309

33103310
#### request.headers()
3311-
- returns: <[Object]> An object with HTTP headers associated with the request. All header names are lower-case.
3311+
- returns: <[Object]<[string], [string]>> An object with HTTP headers associated with the request. All header names are lower-case.
33123312

33133313
#### request.isNavigationRequest()
33143314
- returns: <[boolean]>
@@ -3516,7 +3516,7 @@ Aborts the route's request.
35163516
- `overrides` <[Object]> Optional request overrides, which can be one of the following:
35173517
- `method` <[string]> If set changes the request method (e.g. GET or POST)
35183518
- `postData` <[string]> If set changes the post data of request
3519-
- `headers` <[Object]> If set changes the request HTTP headers. Header values will be converted to a string.
3519+
- `headers` <[Object]<[string], [string]>> If set changes the request HTTP headers. Header values will be converted to a string.
35203520
- returns: <[Promise]>
35213521

35223522
Continues route's request with optional overrides.
@@ -3535,7 +3535,7 @@ await page.route('**/*', (route, request) => {
35353535
#### route.fulfill(response)
35363536
- `response` <[Object]> Response that will fulfill this route's request.
35373537
- `status` <[number]> Response status code, defaults to `200`.
3538-
- `headers` <[Object]> Optional response headers. Header values will be converted to a string.
3538+
- `headers` <[Object]<[string], [string]>> Optional response headers. Header values will be converted to a string.
35393539
- `contentType` <[string]> If set, equals to setting `Content-Type` response header.
35403540
- `body` <[string]|[Buffer]> Optional response body.
35413541
- `path` <[string]> Optional file path to respond with. The content type will be inferred from file extension. If `path` is a relative path, then it is resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd).
@@ -3777,7 +3777,7 @@ This methods attaches Playwright to an existing browser instance.
37773777
- `handleSIGHUP` <[boolean]> Close the browser process on SIGHUP. Defaults to `true`.
37783778
- `logger` <[Logger]> Logger sink for Playwright logging.
37793779
- `timeout` <[number]> Maximum time in milliseconds to wait for the browser instance to start. Defaults to `30000` (30 seconds). Pass `0` to disable timeout.
3780-
- `env` <[Object]> Specify environment variables that will be visible to the browser. Defaults to `process.env`.
3780+
- `env` <[Object]<[string], [string]|[number]|[boolean]>> Specify environment variables that will be visible to the browser. Defaults to `process.env`.
37813781
- `devtools` <[boolean]> **Chromium-only** Whether to auto-open a Developer Tools panel for each tab. If this option is `true`, the `headless` option will be set `false`.
37823782
- `slowMo` <[number]> Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on.
37833783
- returns: <[Promise]<[Browser]>> Promise which resolves to browser instance.
@@ -3810,7 +3810,7 @@ const browser = await chromium.launch({ // Or 'firefox' or 'webkit'.
38103810
- `handleSIGHUP` <[boolean]> Close the browser process on SIGHUP. Defaults to `true`.
38113811
- `logger` <[Logger]> Logger sink for Playwright logging.
38123812
- `timeout` <[number]> Maximum time in milliseconds to wait for the browser instance to start. Defaults to `30000` (30 seconds). Pass `0` to disable timeout.
3813-
- `env` <[Object]> Specify environment variables that will be visible to the browser. Defaults to `process.env`.
3813+
- `env` <[Object]<[string], [string]|[number]|[boolean]>> Specify environment variables that will be visible to the browser. Defaults to `process.env`.
38143814
- `devtools` <[boolean]> **Chromium-only** Whether to auto-open a Developer Tools panel for each tab. If this option is `true`, the `headless` option will be set `false`.
38153815
- `slowMo` <[number]> Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on. Defaults to 0.
38163816
- returns: <[Promise]<[BrowserContext]>> Promise which resolves to the browser app instance.
@@ -3829,7 +3829,7 @@ Launches browser instance that uses persistent storage located at `userDataDir`.
38293829
- `handleSIGHUP` <[boolean]> Close the browser process on SIGHUP. Defaults to `true`.
38303830
- `logger` <[Logger]> Logger sink for Playwright logging.
38313831
- `timeout` <[number]> Maximum time in milliseconds to wait for the browser instance to start. Defaults to `30000` (30 seconds). Pass `0` to disable timeout.
3832-
- `env` <[Object]> Specify environment variables that will be visible to the browser. Defaults to `process.env`.
3832+
- `env` <[Object]<[string], [string]|[number]|[boolean]>> Specify environment variables that will be visible to the browser. Defaults to `process.env`.
38333833
- `devtools` <[boolean]> **Chromium-only** Whether to auto-open a Developer Tools panel for each tab. If this option is `true`, the `headless` option will be set `false`.
38343834
- returns: <[Promise]<[BrowserServer]>> Promise which resolves to the browser app instance.
38353835

src/server/browserType.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ type LaunchOptionsBase = BrowserArgOptions & {
3232
handleSIGHUP?: boolean,
3333
timeout?: number,
3434
logger?: Logger,
35-
env?: {[key: string]: string} | undefined
35+
env?: {[key: string]: string|number|boolean}
3636
};
3737

3838
export type ConnectOptions = {

src/server/processLauncher.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ const browserStdErrLog: Log = {
4848
export type LaunchProcessOptions = {
4949
executablePath: string,
5050
args: string[],
51-
env?: {[key: string]: string | undefined},
51+
env?: {[key: string]: string | number | boolean | undefined},
5252

5353
handleSIGINT?: boolean,
5454
handleSIGTERM?: boolean,
@@ -80,7 +80,7 @@ export async function launchProcess(options: LaunchProcessOptions): Promise<Laun
8080
// process group, making it possible to kill child process tree with `.kill(-pid)` command.
8181
// @see https://nodejs.org/api/child_process.html#child_process_options_detached
8282
detached: process.platform !== 'win32',
83-
env: options.env,
83+
env: (options.env as {[key: string]: string}),
8484
stdio
8585
}
8686
);

utils/doclint/check_public_api/JSBuilder.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ function checkSources(sources) {
184184
*/
185185
function serializeType(type, circular = []) {
186186
let typeName = checker.typeToString(type).replace(/SmartHandle/g, 'Handle');
187-
if (typeName === 'any' || typeName === '{ [x: string]: string; }')
187+
if (typeName === 'any')
188188
typeName = 'Object';
189189
const nextCircular = [typeName].concat(circular);
190190

@@ -196,8 +196,10 @@ function checkSources(sources) {
196196
}
197197
return new Documentation.Type(typeName, []);
198198
}
199-
200-
if (isRegularObject(type)) {
199+
const stringIndexType = type.getStringIndexType();
200+
if (stringIndexType) {
201+
return new Documentation.Type(`Object<string, ${serializeType(stringIndexType, circular).name}>`);
202+
} else if (isRegularObject(type)) {
201203
let properties = undefined;
202204
if (!circular.includes(typeName))
203205
properties = type.getProperties().map(property => serializeSymbol(property, nextCircular));

utils/generate_types/index.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,14 @@ function parseType(type) {
307307
function stringifyType(parsedType) {
308308
if (!parsedType)
309309
return 'void';
310+
if (parsedType.name === 'Object' && parsedType.template) {
311+
const keyType = stringifyType({
312+
...parsedType.template,
313+
next: null
314+
});
315+
const valueType = stringifyType(parsedType.template.next);
316+
return `{ [key: ${keyType}]: ${valueType}; }`;
317+
}
310318
let out = parsedType.name;
311319
if (parsedType.args) {
312320
let args = parsedType.args;

utils/generate_types/test/test.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,14 @@ playwright.chromium.launch().then(async browser => {
135135
await page.route(str => {
136136
const assertion: AssertType<string, typeof str> = true;
137137
return true;
138-
}, interceptedRequest => {
139-
interceptedRequest.continue();
138+
}, (route, request) => {
139+
const {referer} = request.headers();
140+
const isString: AssertType<string, typeof referer> = true;
141+
route.continue({
142+
headers: {
143+
'Access-Control-Allow-Origin': '*'
144+
}
145+
});
140146
return 'something random for no reason';
141147
});
142148

@@ -207,6 +213,8 @@ playwright.chromium.launch().then(async browser => {
207213
const launchOptions: playwright.LaunchOptions = {
208214
devtools: true,
209215
env: {
216+
TIMEOUT: 52,
217+
SOMETHING: '/some/path',
210218
JEST_TEST: true
211219
}
212220
};

0 commit comments

Comments
 (0)