[doclint] introduce preprocessor's gen:copy and gen:paste tasks
The two tasks allow to copy text from one part of document to another. This comes handy in organizing the documentation for our shortcut methods, which should be exactly the same as the original methods. The tasks work like this: - the gen:copy(id) task saves a part of document under the name 'ID'. - the gen:paste(id) task pastes text saved with id 'ID' This patch also fixes a bunch of links in documentation, as well as migrating `api.md` to use the two tasks.
This commit is contained in:
parent
3ada7e1adb
commit
4ee8eb8afc
183
docs/api.md
183
docs/api.md
@ -310,76 +310,60 @@ Emitted when a request is successfully finished.
|
||||
Emitted when a [response] is received.
|
||||
|
||||
#### page.$(selector, pageFunction, ...args)
|
||||
|
||||
<!-- gen:paste('frame.$') -->
|
||||
<!-- Text below is automatically copied from "gen:copy('frame.$')" -->
|
||||
- `selector` <[string]> A [selector] to be matched in the page
|
||||
- `pageFunction` <[function]\([Element]\)> Function to be evaluated in-page with first element matching `selector`
|
||||
- `pageFunction` <[function]\([Element]\)> Function to be evaluated with first element matching `selector`
|
||||
- `...args` <...[string]> Arguments to pass to `pageFunction`
|
||||
- returns: <[Promise]<[Object]>> Promise which resolves to function return value.
|
||||
|
||||
Example:
|
||||
```js
|
||||
const outerhtml = await page.$('#box', e => e.outerHTML);
|
||||
```
|
||||
|
||||
<!-- gen:stop -->
|
||||
Shortcut for [page.mainFrame().$(selector, pageFunction, ...args)](#pageselector-fun-args).
|
||||
|
||||
#### page.$$(selector, pageFunction, ...args)
|
||||
|
||||
<!-- gen:paste('frame.$$') -->
|
||||
<!-- Text below is automatically copied from "gen:copy('frame.$$')" -->
|
||||
- `selector` <[string]> A [selector] to be matched in the page
|
||||
- `pageFunction` <[function]\([Element]\)> Function to be evaluated in-page for every matching element.
|
||||
- `pageFunction` <[function]\([Element]\)> Function to be evaluted for every element matching `selector`.
|
||||
- `...args` <...[string]> Arguments to pass to `pageFunction`
|
||||
- returns: <[Promise]<[Array]<[Object]>>> Promise which resolves to array of function return values.
|
||||
|
||||
Example:
|
||||
```js
|
||||
const headings = await page.$$('h1,h2,h3,h4', el => el.textContent);
|
||||
for (const heading of headings) console.log(heading);
|
||||
```
|
||||
<!-- gen:stop -->
|
||||
|
||||
Shortcut for [page.mainFrame().$$(selector, pageFunction, ...args)](#pageselector-fun-args).
|
||||
|
||||
#### page.addScriptTag(url)
|
||||
<!-- gen:paste('frame.addScriptTag') -->
|
||||
<!-- Text below is automatically copied from "gen:copy('frame.addScriptTag')" -->
|
||||
- `url` <[string]> Url of a script to be added
|
||||
- returns: <[Promise]> Promise which resolves as the script gets added and loads.
|
||||
<!-- gen:stop -->
|
||||
|
||||
Shortcut for [page.mainFrame().addScriptTag(url)](#frameaddscripttagurl).
|
||||
|
||||
Adds a `<script>` tag to the page with the desired url. Alternatively, JavaScript could be injected to the page via [`page.injectFile`](#pageinjectfilefilepath) method.
|
||||
|
||||
#### page.click(selector[, options])
|
||||
<!-- gen:paste('frame.click') -->
|
||||
<!-- Text below is automatically copied from "gen:copy('frame.click')" -->
|
||||
- `selector` <[string]> A query [selector] to search for element to click. If there are multiple elements satisfying the selector, the first will be clicked.
|
||||
- `options` <[Object]>
|
||||
- `button` <[string]> `left`, `right`, or `middle`, defaults to `left`.
|
||||
- `clickCount` <[number]> defaults to 1
|
||||
- returns: <[Promise]> Promise which resolves when the element matching `selector` is successfully clicked. Promise gets rejected if there's no element matching `selector`.
|
||||
<!-- gen:stop -->
|
||||
|
||||
Shortcut for [page.mainFrame().click(selector[, options])](#frameclickselector-options).
|
||||
|
||||
#### page.close()
|
||||
- returns: <[Promise]> Returns promise which resolves when page gets closed.
|
||||
|
||||
#### page.evaluate(pageFunction, ...args)
|
||||
<!-- gen:paste('frame.evaluate') -->
|
||||
<!-- Text below is automatically copied from "gen:copy('frame.evaluate')" -->
|
||||
- `pageFunction` <[function]|[string]> Function to be evaluated in browser context
|
||||
- `...args` <...[string]> Arguments to pass to `pageFunction`
|
||||
- returns: <[Promise]<[Object]>> Promise which resolves to function return value
|
||||
<!-- gen:stop -->
|
||||
|
||||
If the function, passed to the `page.evaluate`, returns a [Promise], then `page.evaluate` would wait for the promise to resolve and return it's value.
|
||||
|
||||
```js
|
||||
const {Browser} = require('puppeteer');
|
||||
const browser = new Browser();
|
||||
browser.newPage().then(async page =>
|
||||
const result = await page.evaluate(() => {
|
||||
return Promise.resolve(8 * 7);
|
||||
});
|
||||
console.log(result); // prints "56"
|
||||
browser.close();
|
||||
});
|
||||
```
|
||||
|
||||
A string can also be passed in instead of a function.
|
||||
|
||||
```js
|
||||
console.log(await page.evaluate('1 + 2')); // prints "3"
|
||||
```
|
||||
|
||||
This is a shortcut for [page.mainFrame().evaluate()](#frameevaluatefun-args) method.
|
||||
Shortcut for [page.mainFrame().evaluate(pageFunction, ...args)](#frameevaluatepagefunction-args) method.
|
||||
|
||||
#### page.evaluateOnNewDocument(pageFunction, ...args)
|
||||
- `pageFunction` <[function]|[string]> Function to be evaluated in browser context
|
||||
@ -393,8 +377,13 @@ Adds a function which would be invoked in one of the following scenarios:
|
||||
The function is invoked after the document was created but before any of its scripts were run. This is useful to amend JavaScript environment, e.g. to seed [Math.random](https://github.com/GoogleChrome/puppeteer/blob/master/examples/unrandomize.js)
|
||||
|
||||
#### page.focus(selector)
|
||||
<!-- gen:paste('frame.focus') -->
|
||||
<!-- Text below is automatically copied from "gen:copy('frame.focus')" -->
|
||||
- `selector` <[string]> A query [selector] of element to focus. If there are multiple elements satisfying the selector, the first will be focused.
|
||||
- returns: <[Promise]> Promise which resolves when the element matching `selector` is successfully focused. Promise gets rejected if there's no element matching `selector`.
|
||||
<!-- gen:stop -->
|
||||
|
||||
Shortcut for [page.mainFrame().focus(selector)](#framefocusselector).
|
||||
|
||||
#### page.frames()
|
||||
- returns: <[Array]<[Frame]>> An array of all frames attached to the page.
|
||||
@ -426,12 +415,22 @@ can not go back, resolves to null.
|
||||
Navigate to the next page in history.
|
||||
|
||||
#### page.hover(selector)
|
||||
<!-- gen:paste('frame.hover') -->
|
||||
<!-- Text below is automatically copied from "gen:copy('frame.hover')" -->
|
||||
- `selector` <[string]> A query [selector] to search for element to hover. If there are multiple elements satisfying the selector, the first will be hovered.
|
||||
- returns: <[Promise]> Promise which resolves when the element matching `selector` is successfully hovered. Promise gets rejected if there's no element matching `selector`.
|
||||
<!-- gen:stop -->
|
||||
|
||||
Shortcut for [page.mainFrame().hover(selector)](#framehoverselector).
|
||||
|
||||
#### page.injectFile(filePath)
|
||||
- `filePath` <[string]> Path to the JavaScript file to be injected into page. If `filePath` is a relative path, then it is resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd).
|
||||
- returns: <[Promise]> Promise which resolves when file gets successfully evaluated in page.
|
||||
<!-- gen:paste('frame.injectFile') -->
|
||||
<!-- Text below is automatically copied from "gen:copy('frame.injectFile')" -->
|
||||
- `filePath` <[string]> Path to the JavaScript file to be injected into frame. If `filePath` is a relative path, then it is resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd).
|
||||
- returns: <[Promise]> Promise which resolves when file gets successfully evaluated in frame.
|
||||
<!-- gen:stop -->
|
||||
|
||||
Shortcut for [page.mainFrame().injectFile(filePath)](#frameinjectfilefilepath).
|
||||
|
||||
#### page.keyboard
|
||||
|
||||
@ -622,7 +621,12 @@ screenshot (unless a `fullPage` option is given).
|
||||
In case of multiple pages in one browser, each page can have its own viewport size.
|
||||
|
||||
#### page.title()
|
||||
<!-- gen:paste('frame.title') -->
|
||||
<!-- Text below is automatically copied from "gen:copy('frame.title')" -->
|
||||
- returns: <[Promise]<[string]>> Returns page's title.
|
||||
<!-- gen:stop -->
|
||||
|
||||
Shortcut for [page.mainFrame().title()](#frametitle).
|
||||
|
||||
#### page.type(text)
|
||||
- `text` <[string]> A text to type into a focused element.
|
||||
@ -633,12 +637,20 @@ Sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in t
|
||||
To press a special key, use [`page.press`](#pagepresskey-options).
|
||||
|
||||
#### page.uploadFile(selector, ...filePaths)
|
||||
<!-- gen:paste('frame.uploadFile') -->
|
||||
<!-- Text below is automatically copied from "gen:copy('frame.uploadFile')" -->
|
||||
- `selector` <[string]> A query [selector] to a file input
|
||||
- `...filePaths` <[string]> Sets the value of the file input these paths. If some of the `filePaths` are relative paths, then they are resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd).
|
||||
- returns: <[Promise]> Promise which resolves when the value is set.
|
||||
<!-- gen:stop -->
|
||||
|
||||
Shortcut for [page.mainFrame().uploadFile(selector, ...filePaths)](#frameuploadfileselector-filepaths).
|
||||
|
||||
#### page.url()
|
||||
- returns: <[string]> Current page url.
|
||||
<!-- gen:paste('frame.url') -->
|
||||
<!-- Text below is automatically copied from "gen:copy('frame.url')" -->
|
||||
- returns: <[string]>
|
||||
<!-- gen:stop -->
|
||||
|
||||
This is a shortcut for [page.mainFrame().url()](#frameurl)
|
||||
|
||||
@ -646,21 +658,18 @@ This is a shortcut for [page.mainFrame().url()](#frameurl)
|
||||
- returns: <[Object]> An object with the save fields as described in [page.setViewport](#pagesetviewportviewport)
|
||||
|
||||
#### page.waitFor(selectorOrFunctionOrTimeout[, options])
|
||||
<!-- gen:paste('frame.waitFor') -->
|
||||
<!-- Text below is automatically copied from "gen:copy('frame.waitFor')" -->
|
||||
- `selectorOrFunctionOrTimeout` <[string]|[number]|[function]> A [selector], predicate or timeout to wait for
|
||||
- `options` <[Object]> Optional waiting parameters
|
||||
- returns: <[Promise]>
|
||||
<!-- gen:stop -->
|
||||
|
||||
This is a shortcut method for [frame.waitForSelector](#framewaitforselectorselector-options) or [page.mainFrame().waitForFunction()](#framewaitforfunctionpagefunction-options-args).
|
||||
|
||||
This method behaves differently with respect to the type of the first parameter:
|
||||
- if `selectorOrFunctionOrTimeout` is a `string`, than the first argument is treated as a [selector] to wait for and the method is a shortcut for [frame.waitForSelector](#framewaitforselectorselector-options)
|
||||
- if `selectorOrFunctionOrTimeout` is a `function`, than the first argument is treated as a predicate to wait for and the method is a shortcut for [frame.waitForFunction()](#framewaitforfunctionpagefunction-options-args).
|
||||
- if `selectorOrFunctionOrTimeout` is a `number`, than the first argument is treated as a timeout in milliseconds and the method returns a promise which resolves after the timeout
|
||||
- otherwise, an exception is thrown
|
||||
|
||||
The method is a shortcut for [page.mainFrame().waitFor()](#framewaitforselectorortimeout-options).
|
||||
Shortcut for [page.mainFrame().waitFor(selectorOrFunctionOrTimeout[, options])](#framewaitforselectororfunctionortimeout-options).
|
||||
|
||||
#### page.waitForFunction(pageFunction[, options, ...args])
|
||||
<!-- gen:paste('frame.waitForFunction') -->
|
||||
<!-- Text below is automatically copied from "gen:copy('frame.waitForFunction')" -->
|
||||
- `pageFunction` <[function]|[string]> Function to be evaluated in browser context
|
||||
- `options` <[Object]> Optional waiting parameters
|
||||
- `polling` <[string]|[number]> An interval at which the `pageFunction` is executed, defaults to `raf`. If `polling` is a number, then it is treated as an interval in milliseconds at which the function would be executed. If `polling` is a string, then it could be one of the following values:
|
||||
@ -669,8 +678,8 @@ The method is a shortcut for [page.mainFrame().waitFor()](#framewaitforselectoro
|
||||
- `timeout` <[number]> maximum time to wait for in milliseconds. Defaults to `30000` (30 seconds).
|
||||
- `...args` <...[Object]> Arguments to pass to `pageFunction`
|
||||
- returns: <[Promise]> Promise which resolves when element specified by selector string is added to DOM.
|
||||
|
||||
Shortcut for [page.mainFrame().waitForFunction()](#framewaitforfunctionpagefunction-options-args).
|
||||
<!-- gen:stop -->
|
||||
Shortcut for [page.mainFrame().waitForFunction(pageFunction[, options, ...args])](#framewaitforfunctionpagefunction-options-args).
|
||||
|
||||
#### page.waitForNavigation(options)
|
||||
- `options` <[Object]> Navigation parameters which might have the following properties:
|
||||
@ -683,13 +692,15 @@ Shortcut for [page.mainFrame().waitForFunction()](#framewaitforfunctionpagefunct
|
||||
- returns: <[Promise]<[Response]>> Promise which resolves to the main resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect.
|
||||
|
||||
#### page.waitForSelector(selector[, options])
|
||||
- `selector` <[string]> A query [selector] to wait for on the page.
|
||||
<!-- gen:paste('frame.waitForSelector') -->
|
||||
<!-- Text below is automatically copied from "gen:copy('frame.waitForSelector')" -->
|
||||
- `selector` <[string]> CSS selector of awaited element,
|
||||
- `options` <[Object]> Optional waiting parameters
|
||||
- `visible` <[boolean]> wait for element to be present in DOM and to be visible, i.e. to not have `display: none` or `visibility: hidden` CSS properties. Defaults to `false`.
|
||||
- `timeout` <[number]> maximum time to wait for in milliseconds. Defaults to `30000` (30 seconds).
|
||||
- returns: <[Promise]> Promise which resolves when the element matching `selector` appears in the page.
|
||||
|
||||
Shortcut for [page.mainFrame().waitForSelector()](#framewaitforselectorselectoroptions).
|
||||
- returns: <[Promise]> Promise which resolves when element specified by selector string is added to DOM.
|
||||
<!-- gen:stop -->
|
||||
Shortcut for [page.mainFrame().waitForSelector(selector[, options])](#framewaitforselectorselector-options).
|
||||
|
||||
### class: Keyboard
|
||||
|
||||
@ -838,51 +849,94 @@ browser.newPage().then(async page => {
|
||||
```
|
||||
|
||||
#### frame.$(selector, pageFunction, ...args)
|
||||
<!-- gen:copy('frame.$') -->
|
||||
- `selector` <[string]> A [selector] to be matched in the page
|
||||
- `pageFunction` <[function]\([Element]\)> Function to be evaluated with first element matching `selector`
|
||||
- `...args` <...[string]> Arguments to pass to `pageFunction`
|
||||
- returns: <[Promise]<[Object]>> Promise which resolves to function return value.
|
||||
<!-- gen:stop -->
|
||||
Example:
|
||||
```js
|
||||
const outerhtml = await page.$('#box', e => e.outerHTML);
|
||||
```
|
||||
|
||||
|
||||
#### frame.$$(selector, pageFunction, ...args)
|
||||
<!-- gen:copy('frame.$$') -->
|
||||
- `selector` <[string]> A [selector] to be matched in the page
|
||||
- `pageFunction` <[function]\([Element]\)> Function to be evaluted for every element matching `selector`.
|
||||
- `...args` <...[string]> Arguments to pass to `pageFunction`
|
||||
- returns: <[Promise]<[Array]<[Object]>>> Promise which resolves to array of function return values.
|
||||
<!-- gen:stop -->
|
||||
Example:
|
||||
```js
|
||||
const headings = await page.$$('h1,h2,h3,h4', el => el.textContent);
|
||||
for (const heading of headings) console.log(heading);
|
||||
```
|
||||
|
||||
|
||||
#### frame.addScriptTag(url)
|
||||
<!-- gen:copy('frame.addScriptTag') -->
|
||||
- `url` <[string]> Url of a script to be added
|
||||
- returns: <[Promise]> Promise which resolves as the script gets added and loads.
|
||||
|
||||
<!-- gen:stop -->
|
||||
Adds a `<script>` tag to the frame with the desired url. Alternatively, JavaScript could be injected to the frame via [`frame.injectFile`](#frameinjectfilefilepath) method.
|
||||
|
||||
#### frame.childFrames()
|
||||
- returns: <[Array]<[Frame]>>
|
||||
|
||||
#### frame.click(selector[, options])
|
||||
<!-- gen:copy('frame.click') -->
|
||||
- `selector` <[string]> A query [selector] to search for element to click. If there are multiple elements satisfying the selector, the first will be clicked.
|
||||
- `options` <[Object]>
|
||||
- `button` <[string]> `left`, `right`, or `middle`, defaults to `left`.
|
||||
- `clickCount` <[number]> defaults to 1
|
||||
- returns: <[Promise]> Promise which resolves when the element matching `selector` is successfully clicked. Promise gets rejected if there's no element matching `selector`.
|
||||
<!-- gen:stop -->
|
||||
|
||||
#### frame.evaluate(pageFunction, ...args)
|
||||
<!-- gen:copy('frame.evaluate') -->
|
||||
- `pageFunction` <[function]|[string]> Function to be evaluated in browser context
|
||||
- `...args` <...[string]> Arguments to pass to `pageFunction`
|
||||
- returns: <[Promise]<[Object]>> Promise which resolves to function return value
|
||||
<!-- gen:stop -->
|
||||
If the function, passed to the `page.evaluate`, returns a [Promise], then `page.evaluate` would wait for the promise to resolve and return it's value.
|
||||
|
||||
If the function, passed to the `frame.evaluate`, returns a [Promise], then `frame.evaluate` would wait for the promise to resolve and return it's value.
|
||||
```js
|
||||
const {Browser} = require('puppeteer');
|
||||
const browser = new Browser();
|
||||
browser.newPage().then(async page =>
|
||||
const result = await page.evaluate(() => {
|
||||
return Promise.resolve(8 * 7);
|
||||
});
|
||||
console.log(result); // prints "56"
|
||||
browser.close();
|
||||
});
|
||||
```
|
||||
|
||||
A string can also be passed in instead of a function.
|
||||
|
||||
```js
|
||||
console.log(await page.evaluate('1 + 2')); // prints "3"
|
||||
```
|
||||
|
||||
#### frame.focus(selector)
|
||||
<!-- gen:copy('frame.focus') -->
|
||||
- `selector` <[string]> A query [selector] of element to focus. If there are multiple elements satisfying the selector, the first will be focused.
|
||||
- returns: <[Promise]> Promise which resolves when the element matching `selector` is successfully focused. Promise gets rejected if there's no element matching `selector`.
|
||||
<!-- gen:stop -->
|
||||
|
||||
#### frame.hover(selector)
|
||||
<!-- gen:copy('frame.hover') -->
|
||||
- `selector` <[string]> A query [selector] to search for element to hover. If there are multiple elements satisfying the selector, the first will be hovered.
|
||||
- returns: <[Promise]> Promise which resolves when the element matching `selector` is successfully hovered. Promise gets rejected if there's no element matching `selector`.
|
||||
<!-- gen:stop -->
|
||||
|
||||
#### frame.injectFile(filePath)
|
||||
<!-- gen:copy('frame.injectFile') -->
|
||||
- `filePath` <[string]> Path to the JavaScript file to be injected into frame. If `filePath` is a relative path, then it is resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd).
|
||||
- returns: <[Promise]> Promise which resolves when file gets successfully evaluated in frame.
|
||||
<!-- gen:stop -->
|
||||
|
||||
#### frame.isDetached()
|
||||
- returns: <[boolean]>
|
||||
@ -902,22 +956,30 @@ Note: This value is calculated once when the frame is created, and will not upda
|
||||
- returns: <[Frame]> Returns parent frame, if any. Detached frames and main frames return `null`.
|
||||
|
||||
#### frame.title()
|
||||
<!-- gen:copy('frame.title') -->
|
||||
- returns: <[Promise]<[string]>> Returns page's title.
|
||||
<!-- gen:stop -->
|
||||
|
||||
#### frame.uploadFile(selector, ...filePaths)
|
||||
<!-- gen:copy('frame.uploadFile') -->
|
||||
- `selector` <[string]> A query [selector] to a file input
|
||||
- `...filePaths` <[string]> Sets the value of the file input these paths. If some of the `filePaths` are relative paths, then they are resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd).
|
||||
- returns: <[Promise]> Promise which resolves when the value is set.
|
||||
<!-- gen:stop -->
|
||||
|
||||
#### frame.url()
|
||||
<!-- gen:copy('frame.url') -->
|
||||
- returns: <[string]>
|
||||
<!-- gen:stop -->
|
||||
|
||||
Returns frame's url.
|
||||
|
||||
#### frame.waitFor(selectorOrFunctionOrTimeout[, options])
|
||||
<!-- gen:copy('frame.waitFor') -->
|
||||
- `selectorOrFunctionOrTimeout` <[string]|[number]|[function]> A [selector], predicate or timeout to wait for
|
||||
- `options` <[Object]> Optional waiting parameters
|
||||
- returns: <[Promise]>
|
||||
<!-- gen:stop -->
|
||||
|
||||
This is a shortcut method for [frame.waitForSelector](#framewaitforselectorselector-options) or [page.mainFrame().waitForFunction()](#framewaitforfunctionpagefunction-options-args).
|
||||
|
||||
@ -928,6 +990,7 @@ This method behaves differently with respect to the type of the first parameter:
|
||||
- otherwise, an exception is thrown
|
||||
|
||||
#### frame.waitForFunction(pageFunction[, options, ...args])
|
||||
<!-- gen:copy('frame.waitForFunction') -->
|
||||
- `pageFunction` <[function]|[string]> Function to be evaluated in browser context
|
||||
- `options` <[Object]> Optional waiting parameters
|
||||
- `polling` <[string]|[number]> An interval at which the `pageFunction` is executed, defaults to `raf`. If `polling` is a number, then it is treated as an interval in milliseconds at which the function would be executed. If `polling` is a string, then it could be one of the following values:
|
||||
@ -936,6 +999,7 @@ This method behaves differently with respect to the type of the first parameter:
|
||||
- `timeout` <[number]> maximum time to wait for in milliseconds. Defaults to `30000` (30 seconds).
|
||||
- `...args` <...[Object]> Arguments to pass to `pageFunction`
|
||||
- returns: <[Promise]> Promise which resolves when element specified by selector string is added to DOM.
|
||||
<!-- gen:stop -->
|
||||
|
||||
The `waitForFunction` could be used to observe viewport size change:
|
||||
```js
|
||||
@ -951,11 +1015,13 @@ browser.newPage().then(async page => {
|
||||
```
|
||||
|
||||
#### frame.waitForSelector(selector[, options])
|
||||
<!-- gen:copy('frame.waitForSelector') -->
|
||||
- `selector` <[string]> CSS selector of awaited element,
|
||||
- `options` <[Object]> Optional waiting parameters
|
||||
- `visible` <[boolean]> wait for element to be present in DOM and to be visible, i.e. to not have `display: none` or `visibility: hidden` CSS properties. Defaults to `false`.
|
||||
- `timeout` <[number]> maximum time to wait for in milliseconds. Defaults to `30000` (30 seconds).
|
||||
- returns: <[Promise]> Promise which resolves when element specified by selector string is added to DOM.
|
||||
<!-- gen:stop -->
|
||||
|
||||
Wait for the `selector` to appear in page. If at the moment of calling
|
||||
the method the `selector` already exists, the method will return
|
||||
@ -975,7 +1041,6 @@ browser.newPage().then(async page => {
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
### class: Request
|
||||
|
||||
Whenever the page sends a request, the following events are emitted by puppeteer's page:
|
||||
|
@ -34,24 +34,38 @@ module.exports = function(sources) {
|
||||
messages.push(Message.error(`Failed to find 'gen:stop' for comamnd ${start[0]}`));
|
||||
break;
|
||||
}
|
||||
commands.push({
|
||||
name: start[1],
|
||||
arg: start[2],
|
||||
source: source,
|
||||
from: commandStartRegex.lastIndex,
|
||||
to: end.index,
|
||||
});
|
||||
const name = start[1];
|
||||
const arg = start[2];
|
||||
const from = commandStartRegex.lastIndex;
|
||||
const to = end.index;
|
||||
commandStartRegex.lastIndex = commandEndRegex.lastIndex;
|
||||
commands.push({name, arg, from, to, source});
|
||||
}
|
||||
}
|
||||
commands.sort((a, b) => b.from - a.from);
|
||||
|
||||
commands = validateCommands(commands, messages);
|
||||
|
||||
// Extract copied text.
|
||||
let copyIds = new Map();
|
||||
for (let command of commands) {
|
||||
if (command.name !== 'copy')
|
||||
continue;
|
||||
const copyText = command.source.text().substring(command.from, command.to);
|
||||
copyIds.set(command.arg, copyText);
|
||||
}
|
||||
|
||||
let changedSources = new Set();
|
||||
// Iterate commands in reverse order so that edits don't conflict.
|
||||
commands.sort((a, b) => b.from - a.from);
|
||||
for (let command of commands) {
|
||||
let newText = command.source.text();
|
||||
if (command.name === 'version')
|
||||
if (command.name === 'version') {
|
||||
newText = replaceInText(newText, command.from, command.to, PUPPETEER_VERSION);
|
||||
else
|
||||
errors.push(`Unknown GEN command in ${command.source.projectPath()}: ${command.name}`);
|
||||
} else if (command.name === 'paste') {
|
||||
let copyText = copyIds.get(command.arg);
|
||||
copyText = `\n<!-- Text below is automatically copied from "gen:copy(${command.arg})" -->` + copyText;
|
||||
newText = replaceInText(newText, command.from, command.to, copyText);
|
||||
}
|
||||
if (command.source.setText(newText))
|
||||
changedSources.add(command.source);
|
||||
}
|
||||
@ -60,6 +74,62 @@ module.exports = function(sources) {
|
||||
return messages;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {!Array<!Object>} commands
|
||||
* @param {!Array<!Message>} outMessages
|
||||
* @return {!Array<!Object>}
|
||||
*/
|
||||
function validateCommands(commands, outMessages) {
|
||||
// Filter sane commands
|
||||
let goodCommands = commands.filter(command => {
|
||||
if (command.name === 'version')
|
||||
return check(command, !command.arg, `"gen:version" should not have argument`);
|
||||
if (command.name === 'copy')
|
||||
return check(command, command.arg, `"gen:copy" should have argument - copyId`);
|
||||
if (command.name === 'paste')
|
||||
return check(command, command.arg, `"gen:paste" should have argument - name of the register to paste from`);
|
||||
check(command, false, `Unknown command: "gen:${command.name}"`);
|
||||
});
|
||||
|
||||
// Make sure copy commands don't clash ids.
|
||||
let copyIds = new Map();
|
||||
goodCommands = goodCommands.filter(command => {
|
||||
if (command.name !== 'copy')
|
||||
return true;
|
||||
const duplicateCopy = copyIds.get(command.arg);
|
||||
const duplicatePath = duplicateCopy ? duplicateCopy.source.projectPath() : '';
|
||||
if (check(command, !duplicateCopy, `"gen:copy" tries to re-define copy id "${command.arg}" - previously defined in ${duplicatePath}`)) {
|
||||
copyIds.set(command.arg, command);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
// Make sure paste commands refer to proper ids, and every copyId is used at least
|
||||
// once.
|
||||
let unusedCopyIds = new Set(copyIds.keys());
|
||||
goodCommands = goodCommands.filter(command => {
|
||||
if (command.name !== 'paste')
|
||||
return true;
|
||||
unusedCopyIds.delete(command.arg);
|
||||
if (check(command, copyIds.has(command.arg), `"gen:paste" refers to unknown copy id "${command.arg}"`))
|
||||
return true;
|
||||
return false;
|
||||
});
|
||||
for (let copyId of unusedCopyIds) {
|
||||
let command = copyIds.get(copyId);
|
||||
check(command, false, `"gen:copy" defines unused copy id "${copyId}"`);
|
||||
}
|
||||
return goodCommands;
|
||||
|
||||
function check(command, condition, message) {
|
||||
if (condition)
|
||||
return true;
|
||||
outMessages.push(Message.error(`${command.source.projectPath()}: ${message}`));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function replaceInText(text, from, to, newText) {
|
||||
return text.substring(0, from) + newText + text.substring(to);
|
||||
}
|
||||
|
@ -19,15 +19,33 @@ const SourceFactory = require('../SourceFactory');
|
||||
const factory = new SourceFactory();
|
||||
const VERSION = require('../../../package.json').version;
|
||||
|
||||
let COPY_INPUT = `
|
||||
<!-- gen:copy("test") -->Heyo!<!-- gen:stop -->
|
||||
<!-- gen:paste("test") --><!-- gen:stop -->
|
||||
`;
|
||||
let COPY_EXPECTED = `
|
||||
<!-- gen:copy("test") -->Heyo!<!-- gen:stop -->
|
||||
<!-- gen:paste("test") -->
|
||||
<!-- Text below is automatically copied from "gen:copy("test")" -->Heyo!<!-- gen:stop -->
|
||||
`;
|
||||
|
||||
describe('preprocessor', function() {
|
||||
it('should throw for unknown command', function() {
|
||||
let source = factory.createForTest('doc.md', getCommand('unknownCommand()'));
|
||||
let messages = preprocessor([source]);
|
||||
expect(source.hasUpdatedText()).toBe(false);
|
||||
expect(messages.length).toBe(1);
|
||||
expect(messages[0].type).toBe('error');
|
||||
expect(messages[0].text).toContain('Unknown command');
|
||||
});
|
||||
describe('gen:version', function() {
|
||||
it('should work', function() {
|
||||
let source = factory.createForTest('doc.md', 'Puppeteer v<!--gen:version--><!--gen:stop-->');
|
||||
let source = factory.createForTest('doc.md', `Puppeteer v${getCommand('version')}`);
|
||||
let messages = preprocessor([source]);
|
||||
expect(messages.length).toBe(1);
|
||||
expect(messages[0].type).toBe('warning');
|
||||
expect(messages[0].text).toContain('doc.md');
|
||||
expect(source.text()).toBe(`Puppeteer v<!--gen:version-->${VERSION}<!--gen:stop-->`);
|
||||
expect(source.text()).toBe(`Puppeteer v${getCommand('version', VERSION)}`);
|
||||
});
|
||||
it('should tolerate different writing', function() {
|
||||
let source = factory.createForTest('doc.md', `Puppeteer v<!-- gEn:version ( ) -->WHAT
|
||||
@ -44,5 +62,60 @@ describe('preprocessor', function() {
|
||||
expect(messages[0].text).toContain(`Failed to find 'gen:stop'`);
|
||||
});
|
||||
});
|
||||
describe('gen:copy', function() {
|
||||
it('should work', function() {
|
||||
let source = factory.createForTest('doc.md', COPY_INPUT);
|
||||
preprocessor([source]);
|
||||
expect(source.hasUpdatedText()).toBe(true);
|
||||
expect(source.text()).toBe(COPY_EXPECTED);
|
||||
});
|
||||
it('should throw if copy does not have argument', function() {
|
||||
let source = factory.createForTest('doc.md', getCommand('copy()'));
|
||||
let messages = preprocessor([source]);
|
||||
expect(source.hasUpdatedText()).toBe(false);
|
||||
expect(messages.length).toBe(1);
|
||||
expect(messages[0].type).toBe('error');
|
||||
expect(messages[0].text).toContain('should have argument');
|
||||
});
|
||||
it('should throw if copyId is not used', function() {
|
||||
let source = factory.createForTest('doc.md', getCommand('copy(command-id)'));
|
||||
let messages = preprocessor([source]);
|
||||
expect(source.hasUpdatedText()).toBe(false);
|
||||
expect(messages.length).toBe(1);
|
||||
expect(messages[0].type).toBe('error');
|
||||
expect(messages[0].text).toContain('unused copy id');
|
||||
});
|
||||
it('should throw if duplicate copy id', function() {
|
||||
const copyCmd = getCommand('copy(foo)');
|
||||
let source = factory.createForTest('doc.md', copyCmd + copyCmd);
|
||||
let messages = preprocessor([source]);
|
||||
messages.sort();
|
||||
expect(source.hasUpdatedText()).toBe(false);
|
||||
expect(messages.length).toBe(2);
|
||||
expect(messages[0].type).toBe('error');
|
||||
expect(messages[0].text).toContain('re-define copy id');
|
||||
});
|
||||
});
|
||||
describe('gen:paste', function() {
|
||||
it('should throw if paste does not have argument', function() {
|
||||
let source = factory.createForTest('doc.md', getCommand('paste()'));
|
||||
let messages = preprocessor([source]);
|
||||
expect(source.hasUpdatedText()).toBe(false);
|
||||
expect(messages.length).toBe(1);
|
||||
expect(messages[0].type).toBe('error');
|
||||
expect(messages[0].text).toContain('should have argument');
|
||||
});
|
||||
it('should throw if copyId is not defined', function() {
|
||||
let source = factory.createForTest('doc.md', getCommand('paste(bar)'));
|
||||
let messages = preprocessor([source]);
|
||||
expect(source.hasUpdatedText()).toBe(false);
|
||||
expect(messages.length).toBe(1);
|
||||
expect(messages[0].type).toBe('error');
|
||||
expect(messages[0].text).toContain('unknown copy id');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function getCommand(name, body = '') {
|
||||
return `<!--gen:${name}-->${body}<!--gen:stop-->`;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user