chore: add python aliases (#4949)

This commit is contained in:
Pavel Feldman 2021-01-08 15:00:14 -08:00 committed by GitHub
parent f0a8729137
commit 114d586f07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 125 additions and 34 deletions

View File

@ -481,6 +481,7 @@ await context.grantPermissions(['geolocation']);
Event name, same one would pass into `browserContext.on(event)`.
### param: BrowserContext.waitForEvent.optionsOrPredicate
* langs: js
- `optionsOrPredicate` <[Function]|[Object]>
- `predicate` <[Function]> receives the event data and resolves to truthy value when the waiting should resolve.
- `timeout` <[float]> maximum time to wait for in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can be changed by using the [`method: BrowserContext.setDefaultTimeout`].

View File

@ -22,6 +22,8 @@ JSHandle.dispose`]. ElementHandles are auto-disposed when their origin frame get
ElementHandle instances can be used as an argument in [`method: Page.$eval`] and [`method: Page.evaluate`] methods.
## async method: ElementHandle.$
* langs:
- alias-python: query_selector
- returns: <[null]|[ElementHandle]>
The method finds an element matching the specified selector in the `ElementHandle`'s subtree. See [Working with
@ -30,6 +32,8 @@ selectors](./selectors.md#working-with-selectors) for more details. If no elemen
### param: ElementHandle.$.selector = %%-query-selector-%%
## async method: ElementHandle.$$
* langs:
- alias-python: query_selector_all
- returns: <[Array]<[ElementHandle]>>
The method finds all elements matching the specified selector in the `ElementHandle`s subtree. See [Working with
@ -38,6 +42,8 @@ selectors](./selectors.md#working-with-selectors) for more details. If no elemen
### param: ElementHandle.$$.selector = %%-query-selector-%%
## async method: ElementHandle.$eval
* langs:
- alias-python: eval_on_selector
- returns: <[Serializable]>
Returns the return value of [`param: pageFunction`]
@ -70,6 +76,8 @@ Function to be evaluated in browser context
Optional argument to pass to [`param: pageFunction`]
## async method: ElementHandle.$$eval
* langs:
- alias-python: eval_on_selector_all
- returns: <[Serializable]>
Returns the return value of [`param: pageFunction`]

View File

@ -38,6 +38,8 @@ console.log(text);
```
## async method: Frame.$
* langs:
- alias-python: query_selector
- returns: <[null]|[ElementHandle]>
Returns the ElementHandle pointing to the frame element.
@ -48,6 +50,8 @@ selectors](./selectors.md#working-with-selectors) for more details. If no elemen
### param: Frame.$.selector = %%-query-selector-%%
## async method: Frame.$$
* langs:
- alias-python: query_selector_all
- returns: <[Array]<[ElementHandle]>>
Returns the ElementHandles pointing to the frame elements.
@ -58,6 +62,8 @@ selectors](./selectors.md#working-with-selectors) for more details. If no elemen
### param: Frame.$$.selector = %%-query-selector-%%
## async method: Frame.$eval
* langs:
- alias-python: eval_on_selector
- returns: <[Serializable]>
Returns the return value of [`param: pageFunction`]
@ -90,6 +96,8 @@ Function to be evaluated in browser context
Optional argument to pass to [`param: pageFunction`]
## async method: Frame.$$eval
* langs:
- alias-python: eval_on_selector_all
- returns: <[Serializable]>
Returns the return value of [`param: pageFunction`]

View File

@ -210,6 +210,8 @@ Emitted when a dedicated [WebWorker](https://developer.mozilla.org/en-US/docs/We
page.
## async method: Page.$
* langs:
- alias-python: query_selector
- returns: <[null]|[ElementHandle]>
The method finds an element matching the specified selector within the page. If no elements match the selector, the
@ -220,6 +222,8 @@ Shortcut for main frame's [`method: Frame.$`].
### param: Page.$.selector = %%-query-selector-%%
## async method: Page.$$
* langs:
- alias-python: query_selector_all
- returns: <[Array]<[ElementHandle]>>
The method finds all elements matching the specified selector within the page. If no elements match the selector, the
@ -230,6 +234,8 @@ Shortcut for main frame's [`method: Frame.$$`].
### param: Page.$$.selector = %%-query-selector-%%
## async method: Page.$eval
* langs:
- alias-python: eval_on_selector
- returns: <[Serializable]>
The method finds an element matching the specified selector within the page and passes it as a first argument to
@ -262,6 +268,8 @@ Function to be evaluated in browser context
Optional argument to pass to [`param: pageFunction`]
## async method: Page.$$eval
* langs:
- alias-python: eval_on_selector_all
- returns: <[Serializable]>
The method finds all elements matching the specified selector within the page and passes an array of matched elements as
@ -560,6 +568,7 @@ await page.evaluate(() => matchMedia('(prefers-color-scheme: no-preference)').ma
```
### param: Page.emulateMedia.params
* langs: js
- `params` <[Object]>
- `media` <[null]|"screen"|"print"> Changes the CSS media type of the page. The only allowed values are `'screen'`, `'print'` and `null`. Passing `null` disables CSS media emulation. Omitting `media` or passing `undefined` does not change the emulated value. Optional.
- `colorScheme` <[null]|"light"|"dark"|"no-preference"> Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'`, `'dark'`, `'no-preference'`. Passing `null` disables color scheme emulation. Omitting `colorScheme` or passing `undefined` does not change the emulated value. Optional.
@ -1569,6 +1578,7 @@ value. Will throw an error if the page is closed before the event is fired.
Event name, same one would pass into `page.on(event)`.
### param: Page.waitForEvent.optionsOrPredicate
* langs: js
- `optionsOrPredicate` <[Function]|[Object]>
- `predicate` <[Function]> receives the event data and resolves to truthy value when the waiting should resolve.
- `timeout` <[float]> maximum time to wait for in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can be changed by using the [`method: BrowserContext.setDefaultTimeout`].

View File

@ -27,6 +27,8 @@ Optional error code. Defaults to `failed`, could be one of the following:
* `'failed'` - A generic failure occurred.
## async method: Route.continue
* langs:
- alias-python: continue_
Continues route's request with optional overrides.

View File

@ -47,6 +47,7 @@ value. Will throw an error if the webSocket is closed before the event is fired.
Event name, same one would pass into `webSocket.on(event)`.
### param: WebSocket.waitForEvent.optionsOrPredicate
* langs: js
- `optionsOrPredicate` <[Function]|[Object]>
- `predicate` <[Function]> receives the event data and resolves to truthy value when the waiting should resolve.
- `timeout` <[float]> maximum time to wait for in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can be changed by using the [`method: BrowserContext.setDefaultTimeout`].

View File

@ -303,6 +303,19 @@ only the first option matching one of the passed options is selected. Optional.
Options to select by label. If the `<select>` has the `multiple` attribute, all given options are selected, otherwise
only the first option matching one of the passed options is selected. Optional.
## python-wait-for-event-predicate
* langs: python
- `predicate` <[Function]>
Receives the event data and resolves to truthy value when the waiting should resolve.
## python-wait-for-event-timeout
* langs: python
- `timeout` <[float]>
Maximum time to wait for in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout.
The default value can be changed by using the [`method: BrowserContext.setDefaultTimeout`].
## shared-context-params-list
- %%-context-option-acceptdownloads-%%

View File

@ -79,3 +79,26 @@ Longitude between -180 and 180. **required**
- `accuracy` <[float]>
Non-negative accuracy value. Defaults to `0`. Optional.
### param: Page.emulateMedia.params
* langs: python
- `media` <[null]|"screen"|"print">
Changes the CSS media type of the page. The only allowed values are `'screen'`, `'print'` and `null`.
Passing `null` disables CSS media emulation. Omitting `media` or passing `undefined` does not change the emulated value.
Optional.
### param: Page.emulateMedia.params
* langs: python
- `colorScheme` <[null]|"light"|"dark"|"no-preference">
Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'`, `'dark'`, `'no-preference'`. Passing
`null` disables color scheme emulation. Omitting `colorScheme` or passing `undefined` does not change the emulated
value. Optional.
### option: BrowserContext.waitForEvent.predicate = %%-python-wait-for-event-predicate-%%
### option: BrowserContext.waitForEvent.timeout = %%-python-wait-for-event-timeout-%%
### option: Page.waitForEvent.predicate = %%-python-wait-for-event-predicate-%%
### option: Page.waitForEvent.timeout = %%-python-wait-for-event-timeout-%%
### option: WebSocket.waitForEvent.predicate = %%-python-wait-for-event-predicate-%%
### option: WebSocket.waitForEvent.timeout = %%-python-wait-for-event-timeout-%%

View File

@ -207,15 +207,17 @@ Consider a page with two buttons, first invisible and second visible.
<button>Visible</button>
```
* ```js
* This will find the first button, because it is the first one in DOM order. Then it will wait for the button to become visible before clicking, or timeout while waiting:
```js
await page.click('button');
```
This will find the first button, because it is the first one in DOM order. Then it will wait for the button to become visible before clicking, or timeout while waiting.
* ```js
* This will find a second button, because it is visible, and then click it.
```js
await page.click('button:visible');
```
This will find a second button, because it is visible, and then click it.
```
Use `:visible` with caution, because it has two major drawbacks:
* When elements change their visibility dynamically, `:visible` will give upredictable results based on the timing.

View File

@ -113,7 +113,7 @@ class ApiParser {
let options = method.argsArray.find(o => o.name === 'options');
if (!options) {
const type = new Documentation.Type('Object', []);
options = Documentation.Member.createProperty(null, 'options', type, undefined, false);
options = Documentation.Member.createProperty({}, 'options', type, undefined, false);
method.argsArray.push(options);
}
const p = this.parseProperty(spec);
@ -143,7 +143,7 @@ class ApiParser {
for (const child of spec.children || []) {
const { name, text } = parseVariable(child.text);
const comments = /** @type {MarkdownNode[]} */ ([{ type: 'text', text }]);
properties.push(Documentation.Member.createProperty(null, name, this.parseType(child), comments, guessRequired(text)));
properties.push(Documentation.Member.createProperty({}, name, this.parseType(child), comments, guessRequired(text)));
}
return Documentation.Type.parse(arg.type, properties);
}
@ -272,13 +272,27 @@ function parseApi(apiDir) {
/**
* @param {MarkdownNode} spec
* @returns {?Set<string>}
* @returns {import('./documentation').Langs}
*/
function extractLangs(spec) {
for (const child of spec.children)
if (child.type === 'li' && child.liType === 'bullet' && child.text.startsWith('langs: '))
return new Set(child.text.substring('langs: '.length).split(',').map(l => l.trim()));
return null;
for (const child of spec.children) {
if (child.type !== 'li' || child.liType !== 'bullet' || !child.text.startsWith('langs:'))
continue;
const only = child.text.substring('langs:'.length).trim();
/** @type {Object<string, string>} */
const aliases = {};
for (const p of child.children || []) {
const match = p.text.match(/alias-(\w+)[\s]*:(.*)/);
if (match)
aliases[match[1].trim()] = match[2].trim();
}
return {
only: only ? only.split(',') : undefined,
aliases
};
}
return {};
}
/**

View File

@ -31,6 +31,13 @@ const md = require('../markdown');
* }} ParsedType
*/
/**
* @typedef {{
* only?: string[],
* aliases?: Object<string, string>
* }} Langs
*/
/**
* @typedef {function({
* clazz?: Documentation.Class,
@ -81,7 +88,7 @@ class Documentation {
filterForLanguage(lang) {
const classesArray = [];
for (const clazz of this.classesArray) {
if (clazz.langs && !clazz.langs.has(lang))
if (clazz.langs.only && !clazz.langs.only.includes(lang))
continue;
clazz.filterForLanguage(lang);
classesArray.push(clazz);
@ -131,7 +138,7 @@ class Documentation {
Documentation.Class = class {
/**
* @param {?Set<string>} langs
* @param {Langs} langs
* @param {string} name
* @param {!Array<!Documentation.Member>} membersArray
* @param {?string=} extendsName
@ -188,8 +195,10 @@ Documentation.Class = class {
filterForLanguage(lang) {
const membersArray = [];
for (const member of this.membersArray) {
if (member.langs && !member.langs.has(lang))
if (member.langs.only && !member.langs.only.includes(lang))
continue;
if (member.langs.aliases && member.langs.aliases[lang])
member.alias = member.langs.aliases[lang];
member.filterForLanguage(lang);
membersArray.push(member);
}
@ -257,7 +266,7 @@ Documentation.Class = class {
Documentation.Member = class {
/**
* @param {string} kind
* @param {?Set<string>} langs
* @param {Langs} langs
* @param {string} name
* @param {?Documentation.Type} type
* @param {!Array<!Documentation.Member>} argsArray
@ -287,6 +296,7 @@ Documentation.Member = class {
});
};
this.async = false;
this.alias = name;
}
index() {
@ -304,8 +314,10 @@ Documentation.Member = class {
filterForLanguage(lang) {
const argsArray = [];
for (const arg of this.argsArray) {
if (arg.langs && !arg.langs.has(lang))
if (arg.langs.only && !arg.langs.only.includes(lang))
continue;
if (arg.langs.aliases && arg.langs.aliases[lang])
arg.alias = arg.langs.aliases[lang];
arg.filterForLanguage(lang);
argsArray.push(arg);
}
@ -319,7 +331,7 @@ Documentation.Member = class {
}
/**
* @param {?Set<string>} langs
* @param {Langs} langs
* @param {string} name
* @param {!Array<!Documentation.Member>} argsArray
* @param {?Documentation.Type} returnType
@ -331,10 +343,10 @@ Documentation.Member = class {
}
/**
* @param {?Set<string>} langs
* @param {string} name
* @param {!Langs} langs
* @param {!string} name
* @param {!Documentation.Type} type
* @param {MarkdownNode[]=} spec
* @param {!MarkdownNode[]=} spec
* @param {boolean=} required
* @return {!Documentation.Member}
*/
@ -343,7 +355,7 @@ Documentation.Member = class {
}
/**
* @param {?Set<string>} langs
* @param {Langs} langs
* @param {string} name
* @param {?Documentation.Type=} type
* @param {MarkdownNode[]=} spec

View File

@ -52,8 +52,7 @@ function serializeClass(clazz) {
const result = { name: clazz.name };
if (clazz.extends)
result.extends = clazz.extends;
if (clazz.langs)
result.langs = [...clazz.langs];
result.langs = clazz.langs;
if (clazz.comment)
result.comment = clazz.comment;
result.members = clazz.membersArray.map(serializeMember);
@ -66,8 +65,6 @@ function serializeClass(clazz) {
function serializeMember(member) {
const result = /** @type {any} */ ({ ...member });
sanitize(result);
if (member.langs)
result.langs = [...member.langs];
result.args = member.argsArray.map(serializeProperty);
if (member.type)
result.type = serializeType(member.type)
@ -77,8 +74,6 @@ function serializeMember(member) {
function serializeProperty(arg) {
const result = { ...arg };
sanitize(result);
if (arg.langs)
result.langs = [...arg.langs];
if (arg.type)
result.type = serializeType(arg.type)
return result;
@ -88,7 +83,6 @@ function sanitize(result) {
delete result.args;
delete result.argsArray;
delete result.clazz;
delete result.langs;
delete result.spec;
}

View File

@ -60,7 +60,7 @@ module.exports = function lint(documentation, jsSources, apiFileName) {
}
const memberParams = paramsForMember(member);
for (const paramName of memberParams) {
if (!params.has(paramName))
if (!params.has(paramName) && paramName !== 'options')
errors.push(`Documented "${cls.name}.${member.name}.${paramName}" not found is sources`);
}
}

View File

@ -38,6 +38,5 @@ test('missing docs', async ({}) => {
'Documented "DoesNotExist" not found in sources',
'Documented "Exists.doesNotExist" not found is sources',
'Documented "Exists.exists.doesNotExist" not found is sources',
'Documented "Exists.exists.options" not found is sources',
]);
});

View File

@ -26,7 +26,7 @@
* }} MarkdownNode */
function flattenWrappedLines(content) {
const inLines = content.split('\n');
const inLines = content.replace(/\r\n/g, '\n').split('\n');
let inCodeBlock = false;
const outLines = [];
let outLineTokens = [];
@ -124,8 +124,12 @@ function buildTree(lines) {
};
line = lines[++i];
while (!line.trim().startsWith('```')) {
if (!line.startsWith(indent))
throw new Error('Bad code block ' + line);
if (!line.startsWith(indent)) {
const from = Math.max(0, i - 5)
const to = Math.min(lines.length, from + 10);
const snippet = lines.slice(from, to);
throw new Error(`Bad code block: ${snippet.join('\n')}`);
}
node.lines.push(line.substring(indent.length));
line = lines[++i];
}