forked from puppeteer/puppeteer
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ebac211
commit 2cda8c1
Showing
180 changed files
with
19,038 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
/node_modules/ | ||
/.local-chromium/ | ||
/.dev_profile* | ||
.DS_Store | ||
*.swp | ||
*.pyc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# How to Contribute | ||
|
||
We'd love to accept your patches and contributions to this project. There are | ||
just a few small guidelines you need to follow. | ||
|
||
## Contributor License Agreement | ||
|
||
Contributions to this project must be accompanied by a Contributor License | ||
Agreement. You (or your employer) retain the copyright to your contribution, | ||
this simply gives us permission to use and redistribute your contributions as | ||
part of the project. Head over to <https://cla.developers.google.com/> to see | ||
your current agreements on file or to sign a new one. | ||
|
||
You generally only need to submit a CLA once, so if you've already submitted one | ||
(even if it was for a different project), you probably don't need to do it | ||
again. | ||
|
||
## Code reviews | ||
|
||
All submissions, including submissions by project members, require review. We | ||
use GitHub pull requests for this purpose. Consult | ||
[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more | ||
information on using pull requests. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,36 @@ | ||
# puppeteer | ||
Headless Chrome Node API | ||
### Status | ||
|
||
Test results on Mac OS X in headless mode: | ||
``` | ||
111 passed | ||
20 failed as expected | ||
1 skipped | ||
49 unsupported | ||
``` | ||
|
||
### Installing | ||
|
||
```bash | ||
npm i | ||
npm link # this adds puppeteer to $PATH | ||
``` | ||
|
||
### Run | ||
|
||
```bash | ||
# run phantomjs script | ||
puppeteer third_party/phantomjs/examples/colorwheel.js | ||
|
||
# run 'headful' | ||
puppeteer --no-headless third_party/phantomjs/examples/colorwheel.js | ||
|
||
# run puppeteer example | ||
node examples/screenshot.js | ||
``` | ||
|
||
### Tests | ||
|
||
Run phantom.js tests using puppeteer: | ||
``` | ||
./third_party/phantomjs/test/run-tests.py | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/** | ||
* Copyright 2017 Google Inc. All rights reserved. | ||
* | ||
* 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. | ||
*/ | ||
|
||
var Browser = require('../lib/Browser'); | ||
var Downloader = require('../lib/Downloader'); | ||
|
||
var revision = "464642"; | ||
console.log('Downloading custom chromium revision - ' + revision); | ||
Downloader.downloadChromium(revision).then(async () => { | ||
console.log('Done.'); | ||
var executablePath = Downloader.executablePath(revision); | ||
var browser1 = new Browser({ | ||
remoteDebuggingPort: 9228, | ||
executablePath, | ||
}); | ||
var browser2 = new Browser({ | ||
remoteDebuggingPort: 9229, | ||
}); | ||
var [version1, version2] = await Promise.all([ | ||
browser1.version(), | ||
browser2.version() | ||
]); | ||
console.log('browser1: ' + version1); | ||
console.log('browser2: ' + version2); | ||
browser1.close(); | ||
browser2.close(); | ||
}); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/** | ||
* Copyright 2017 Google Inc. All rights reserved. | ||
* | ||
* 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. | ||
*/ | ||
|
||
var Browser = require('./lib/Browser'); | ||
var Page = require('./lib/Page'); | ||
var fs = require('fs'); | ||
var browser = new Browser(); | ||
|
||
browser.newPage().then(async page => { | ||
await page.navigate('http://example.com'); | ||
var screenshotBuffer = await page.screenshot(Page.ScreenshotTypes.PNG); | ||
fs.writeFileSync('example.png', screenshotBuffer); | ||
browser.close(); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
#!/usr/bin/env node | ||
/** | ||
* Copyright 2017 Google Inc. All rights reserved. | ||
* | ||
* 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. | ||
*/ | ||
|
||
var vm = require('vm'); | ||
var fs = require('fs'); | ||
var path = require('path'); | ||
var Browser = require('./lib/Browser'); | ||
var argv = require('minimist')(process.argv.slice(2), { | ||
alias: { v: 'version' }, | ||
boolean: ['headless'], | ||
default: {'headless': true }, | ||
}); | ||
|
||
if (argv.version) { | ||
console.log('Puppeteer v' + require('./package.json').version); | ||
return; | ||
} | ||
|
||
if (argv['ssl-certificates-path']) { | ||
console.error('Flag --ssl-certificates-path is not currently supported.\nMore information at https://github.com/aslushnikov/puppeteer/issues/1'); | ||
process.exit(1); | ||
return; | ||
} | ||
|
||
var scriptArguments = argv._; | ||
if (!scriptArguments.length) { | ||
console.log('puppeteer [scriptfile]'); | ||
return; | ||
} | ||
|
||
var scriptPath = path.resolve(process.cwd(), scriptArguments[0]); | ||
if (!fs.existsSync(scriptPath)) { | ||
console.error(`script not found: ${scriptPath}`); | ||
process.exit(1); | ||
return; | ||
} | ||
|
||
var browser = new Browser({ | ||
remoteDebuggingPort: 9229, | ||
headless: argv.headless, | ||
}); | ||
|
||
var PhatomJs = require('./phantomjs'); | ||
var context = PhatomJs.createContext(browser, scriptPath, argv); | ||
var scriptContent = fs.readFileSync(scriptPath, 'utf8'); | ||
vm.runInContext(scriptContent, context); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
var Downloader = require('./lib/Downloader'); | ||
var revision = require('./package').puppeteer.chromium_revision; | ||
var fs = require('fs'); | ||
var ProgressBar = require('progress'); | ||
|
||
var executable = Downloader.executablePath(revision); | ||
if (fs.existsSync(executable)) | ||
return; | ||
|
||
Downloader.downloadChromium(revision, onProgress) | ||
.catch(error => { | ||
console.error('Download failed: ' + error.message); | ||
}); | ||
|
||
var progressBar = null; | ||
function onProgress(bytesTotal, delta) { | ||
if (!progressBar) { | ||
progressBar = new ProgressBar(`Downloading Chromium - ${toMegabytes(bytesTotal)} [:bar] :percent :etas `, { | ||
complete: '=', | ||
incomplete: ' ', | ||
width: 20, | ||
total: bytesTotal, | ||
}); | ||
} | ||
progressBar.tick(delta); | ||
} | ||
|
||
function toMegabytes(bytes) { | ||
var mb = bytes / 1024 / 1024; | ||
return (Math.round(mb * 10) / 10) + ' Mb'; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
/** | ||
* Copyright 2017 Google Inc. All rights reserved. | ||
* | ||
* 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. | ||
*/ | ||
|
||
var CDP = require('chrome-remote-interface'); | ||
var http = require('http'); | ||
var path = require('path'); | ||
var removeRecursive = require('rimraf').sync; | ||
var Page = require('./Page'); | ||
var childProcess = require('child_process'); | ||
var Downloader = require('./Downloader'); | ||
|
||
var CHROME_PROFILE_PATH = path.resolve(__dirname, '..', '.dev_profile'); | ||
var browserId = 0; | ||
|
||
var DEFAULT_ARGS = [ | ||
'--disable-background-timer-throttling', | ||
'--no-first-run', | ||
]; | ||
|
||
class Browser { | ||
/** | ||
* @param {(!Object|undefined)} options | ||
*/ | ||
constructor(options) { | ||
options = options || {}; | ||
++browserId; | ||
this._userDataDir = CHROME_PROFILE_PATH + browserId; | ||
this._remoteDebuggingPort = 9229; | ||
if (typeof options.remoteDebuggingPort === 'number') | ||
this._remoteDebuggingPort = options.remoteDebuggingPort; | ||
this._chromeArguments = DEFAULT_ARGS.concat([ | ||
`--user-data-dir=${this._userDataDir}`, | ||
`--remote-debugging-port=${this._remoteDebuggingPort}`, | ||
]); | ||
if (typeof options.headless !== 'boolean' || options.headless) { | ||
this._chromeArguments.push(...[ | ||
`--headless`, | ||
`--disable-gpu`, | ||
]); | ||
} | ||
if (typeof options.executablePath === 'string') { | ||
this._chromeExecutable = options.executablePath; | ||
} else { | ||
var chromiumRevision = require('../package.json').puppeteer.chromium_revision; | ||
this._chromeExecutable = Downloader.executablePath(chromiumRevision); | ||
} | ||
if (Array.isArray(options.args)) | ||
this._chromeArguments.push(...options.args); | ||
this._chromeProcess = null; | ||
this._tabSymbol = Symbol('Browser.TabSymbol'); | ||
} | ||
|
||
/** | ||
* @return {!Promise<!Page>} | ||
*/ | ||
async newPage() { | ||
await this._ensureChromeIsRunning(); | ||
if (!this._chromeProcess || this._chromeProcess.killed) | ||
throw new Error('ERROR: this chrome instance is not alive any more!'); | ||
var tab = await CDP.New({port: this._remoteDebuggingPort}); | ||
var client = await CDP({tab: tab, port: this._remoteDebuggingPort}); | ||
var page = await Page.create(this, client); | ||
page[this._tabSymbol] = tab; | ||
return page; | ||
} | ||
|
||
/** | ||
* @param {!Page} page | ||
*/ | ||
async closePage(page) { | ||
if (!this._chromeProcess || this._chromeProcess.killed) | ||
throw new Error('ERROR: this chrome instance is not running'); | ||
var tab = page[this._tabSymbol]; | ||
if (!tab) | ||
throw new Error('ERROR: page does not belong to this chrome instance'); | ||
await CDP.Close({id: tab.id, port: this._remoteDebuggingPort}); | ||
} | ||
|
||
/** | ||
* @return {string} | ||
*/ | ||
async version() { | ||
await this._ensureChromeIsRunning(); | ||
var version = await CDP.Version({port: this._remoteDebuggingPort}); | ||
return version.Browser; | ||
} | ||
|
||
async _ensureChromeIsRunning() { | ||
if (this._chromeProcess) | ||
return; | ||
this._chromeProcess = childProcess.spawn(this._chromeExecutable, this._chromeArguments, {}); | ||
// Cleanup as processes exit. | ||
process.on('exit', () => this._chromeProcess.kill()); | ||
this._chromeProcess.on('exit', () => removeRecursive(this._userDataDir)); | ||
|
||
await waitForChromeResponsive(this._remoteDebuggingPort); | ||
} | ||
|
||
close() { | ||
if (!this._chromeProcess) | ||
return; | ||
this._chromeProcess.kill(); | ||
} | ||
} | ||
|
||
module.exports = Browser; | ||
|
||
function waitForChromeResponsive(remoteDebuggingPort) { | ||
var fulfill; | ||
var promise = new Promise(x => fulfill = x); | ||
var options = { | ||
method: 'GET', | ||
host: 'localhost', | ||
port: remoteDebuggingPort, | ||
path: '/json/list' | ||
}; | ||
var probeTimeout = 100; | ||
var probeAttempt = 1; | ||
sendRequest(); | ||
return promise; | ||
|
||
function sendRequest() { | ||
var req = http.request(options, res => { | ||
fulfill() | ||
}); | ||
req.on('error', e => setTimeout(sendRequest, probeTimeout)); | ||
req.end(); | ||
} | ||
} |
Oops, something went wrong.