mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
Puppeteer: staging commit.
This commit is contained in:
parent
ebac211411
commit
2cda8c18d1
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/node_modules/
|
||||
/.local-chromium/
|
||||
/.dev_profile*
|
||||
.DS_Store
|
||||
*.swp
|
||||
*.pyc
|
23
CONTRIBUTING.md
Normal file
23
CONTRIBUTING.md
Normal file
@ -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.
|
38
README.md
38
README.md
@ -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
|
||||
```
|
||||
|
41
examples/custom-chromium-revision.js
Normal file
41
examples/custom-chromium-revision.js
Normal file
@ -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();
|
||||
});
|
||||
|
27
examples/screenshot.js
Normal file
27
examples/screenshot.js
Normal file
@ -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();
|
||||
});
|
60
index.js
Executable file
60
index.js
Executable file
@ -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);
|
32
install.js
Normal file
32
install.js
Normal file
@ -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';
|
||||
}
|
||||
|
142
lib/Browser.js
Normal file
142
lib/Browser.js
Normal file
@ -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();
|
||||
}
|
||||
}
|
123
lib/Downloader.js
Normal file
123
lib/Downloader.js
Normal file
@ -0,0 +1,123 @@
|
||||
/**
|
||||
* 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 os = require('os');
|
||||
var https = require('https');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var extract = require('extract-zip');
|
||||
var util = require('util');
|
||||
|
||||
var CHROMIUM_PATH = path.join(__dirname, '..', '.local-chromium');
|
||||
|
||||
var downloadURLs = {
|
||||
linux: 'https://storage.googleapis.com/chromium-browser-snapshots/Linux_x64/%d/chrome-linux.zip',
|
||||
darwin: 'https://storage.googleapis.com/chromium-browser-snapshots/Mac/%d/chrome-mac.zip',
|
||||
win32: 'https://storage.googleapis.com/chromium-browser-snapshots/Win/%d/chrome-win32.zip',
|
||||
win64: 'https://storage.googleapis.com/chromium-browser-snapshots/Win_x64/%d/chrome-win32.zip',
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
downloadChromium,
|
||||
executablePath,
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} revision
|
||||
* @param {?function(number, number)} progressCallback
|
||||
* @return {!Promise}
|
||||
*/
|
||||
async function downloadChromium(revision, progressCallback) {
|
||||
var url = null;
|
||||
var platform = os.platform();
|
||||
if (platform === 'darwin')
|
||||
url = downloadURLs.darwin;
|
||||
else if (platform === 'linux')
|
||||
url = downloadURLs.linux;
|
||||
else if (platform === 'win32')
|
||||
url = os.arch() === 'x64' ? downloadURLs.win64 : downloadURLs.win32;
|
||||
console.assert(url, `Unsupported platform: ${platform}`);
|
||||
url = util.format(url, revision);
|
||||
var zipPath = path.join(CHROMIUM_PATH, `download-${revision}.zip`);
|
||||
var folderPath = path.join(CHROMIUM_PATH, revision);
|
||||
if (fs.existsSync(folderPath))
|
||||
return;
|
||||
try {
|
||||
if (!fs.existsSync(CHROMIUM_PATH))
|
||||
fs.mkdirSync(CHROMIUM_PATH);
|
||||
await downloadFile(url, zipPath, progressCallback);
|
||||
await extractZip(zipPath, folderPath);
|
||||
} finally {
|
||||
if (fs.existsSync(zipPath))
|
||||
fs.unlinkSync(zipPath);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
function executablePath(revision) {
|
||||
var platform = os.platform();
|
||||
if (platform === 'darwin')
|
||||
return path.join(CHROMIUM_PATH, revision, 'chrome-mac', 'Chromium.app', 'Contents', 'MacOS', 'Chromium');
|
||||
if (platform === 'linux')
|
||||
return path.join(CHROMIUM_PATH, revision, 'chrome-linux', 'chrome');
|
||||
if (platform === 'win32')
|
||||
return path.join(CHROMIUM_PATH, revision, 'chrome-win32', 'chrome.exe');
|
||||
throw new Error(`Unsupported platform: ${platform}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} url
|
||||
* @param {string} destinationPath
|
||||
* @param {?function(number, number)} progressCallback
|
||||
* @return {!Promise}
|
||||
*/
|
||||
function downloadFile(url, destinationPath, progressCallback) {
|
||||
var fulfill, reject;
|
||||
var promise = new Promise((x, y) => { fulfill = x; reject = y; });
|
||||
var request = https.get(url, response => {
|
||||
if (response.statusCode !== 200) {
|
||||
var error = new Error(`Download failed: server returned code ${response.statusCode}. URL: ${url}`);
|
||||
// consume response data to free up memory
|
||||
response.resume();
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
var file = fs.createWriteStream(destinationPath);
|
||||
file.on('finish', () => fulfill());
|
||||
file.on('error', error => reject(error));
|
||||
response.pipe(file);
|
||||
var totalBytes = parseInt(response.headers['content-length'], 10);
|
||||
if (progressCallback)
|
||||
response.on('data', onData.bind(null, totalBytes));
|
||||
});
|
||||
request.on('error', error => reject(error));
|
||||
return promise;
|
||||
|
||||
function onData(totalBytes, chunk) {
|
||||
progressCallback(totalBytes, chunk.length);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} zipPath
|
||||
* @param {string} folderPath
|
||||
* @return {!Promise<?Error>}
|
||||
*/
|
||||
function extractZip(zipPath, folderPath) {
|
||||
return new Promise(fulfill => extract(zipPath, {dir: folderPath}, fulfill));
|
||||
}
|
350
lib/Page.js
Normal file
350
lib/Page.js
Normal file
@ -0,0 +1,350 @@
|
||||
/**
|
||||
* 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 fs = require('fs');
|
||||
var EventEmitter = require('events');
|
||||
var helpers = require('./helpers');
|
||||
|
||||
class Page extends EventEmitter {
|
||||
/**
|
||||
* @param {!Browser} browser
|
||||
* @param {!CDP} client
|
||||
* @return {!Promise<!Page>}
|
||||
*/
|
||||
static async create(browser, client) {
|
||||
await Promise.all([
|
||||
client.send('Network.enable', {}),
|
||||
client.send('Page.enable', {}),
|
||||
client.send('Runtime.enable', {}),
|
||||
client.send('Security.enable', {}),
|
||||
]);
|
||||
var screenDPI = await helpers.evaluate(client, () => window.devicePixelRatio, []);
|
||||
var page = new Page(browser, client, screenDPI.result.value);
|
||||
// Initialize default page size.
|
||||
await page.setSize({width: 400, height: 300});
|
||||
return page;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!Browser} browser
|
||||
* @param {!CDP} client
|
||||
* @param {number} screenDPI
|
||||
*/
|
||||
constructor(browser, client, screenDPI) {
|
||||
super();
|
||||
this._browser = browser;
|
||||
this._client = client;
|
||||
this._screenDPI = screenDPI;
|
||||
this._extraHeaders = {};
|
||||
/** @type {!Map<string, function()>} */
|
||||
this._scriptIdToPageCallback = new Map();
|
||||
/** @type {!Map<string, string>} */
|
||||
this._scriptIdToCallbackName = new Map();
|
||||
|
||||
client.on('Debugger.paused', event => this._onDebuggerPaused(event));
|
||||
client.on('Network.responseReceived', event => this.emit(Page.Events.ResponseReceived, event.response));
|
||||
client.on('Network.loadingFailed', event => this.emit(Page.Events.ResourceLoadingFailed, event));
|
||||
client.on('Runtime.consoleAPICalled', event => this._onConsoleAPI(event));
|
||||
client.on('Page.javascriptDialogOpening', dialog => this.emit(Page.Events.DialogOpened, dialog));
|
||||
client.on('Runtime.exceptionThrown', exception => this._handleException(exception.exceptionDetails));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @param {function(?)} callback
|
||||
*/
|
||||
async setInPageCallback(name, callback) {
|
||||
var hasCallback = await this.evaluate(function(name) {
|
||||
return !!window[name];
|
||||
}, name);
|
||||
if (hasCallback)
|
||||
throw new Error(`Failed to set in-page callback with name ${name}: window['${name}'] already exists!`);
|
||||
|
||||
var sourceURL = '__in_page_callback__' + name;
|
||||
// Ensure debugger is enabled.
|
||||
await this._client.send('Debugger.enable', {});
|
||||
var scriptPromise = helpers.waitForScriptWithURL(this._client, sourceURL);
|
||||
helpers.evaluate(this._client, inPageCallback, [name], false /* awaitPromise */, sourceURL);
|
||||
var script = await scriptPromise;
|
||||
if (!script)
|
||||
throw new Error(`Failed to set in-page callback with name "${name}"`);
|
||||
this._scriptIdToPageCallback.set(script.scriptId, callback);
|
||||
this._scriptIdToCallbackName.set(script.scriptId, name);
|
||||
|
||||
function inPageCallback(callbackName) {
|
||||
window[callbackName] = (...args) => {
|
||||
window[callbackName].__args = args;
|
||||
window[callbackName].__result = undefined;
|
||||
debugger;
|
||||
return window[callbackName].__result;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} scriptId
|
||||
*/
|
||||
async _handleInPageCallback(scriptId) {
|
||||
var name = /** @type {string} */ (this._scriptIdToCallbackName.get(scriptId));
|
||||
var callback = /** @type {function()} */ (this._scriptIdToPageCallback.get(scriptId));
|
||||
var args = await this.evaluate(callbackName => window[callbackName].__args, name);
|
||||
var result = callback.apply(null, args);
|
||||
await this.evaluate(assignResult, name, result);
|
||||
this._client.send('Debugger.resume');
|
||||
|
||||
/**
|
||||
* @param {string} callbackName
|
||||
* @param {string} callbackResult
|
||||
*/
|
||||
function assignResult(callbackName, callbackResult) {
|
||||
window[callbackName].__result = callbackResult;
|
||||
}
|
||||
}
|
||||
|
||||
_onDebuggerPaused(event) {
|
||||
var location = event.callFrames[0] ? event.callFrames[0].location : null;
|
||||
if (location && this._scriptIdToPageCallback.has(location.scriptId)) {
|
||||
this._handleInPageCallback(location.scriptId);
|
||||
return;
|
||||
}
|
||||
this._client.send('Debugger.resume');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!Object} headers
|
||||
* @return {!Promise}
|
||||
*/
|
||||
async setExtraHTTPHeaders(headers) {
|
||||
this._extraHeaders = {};
|
||||
// Note: header names are case-insensitive.
|
||||
for (var key of Object.keys(headers))
|
||||
this._extraHeaders[key.toLowerCase()] = headers[key];
|
||||
return this._client.send('Network.setExtraHTTPHeaders', { headers });
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {!Object}
|
||||
*/
|
||||
extraHTTPHeaders() {
|
||||
return Object.assign({}, this._extraHeaders);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} userAgent
|
||||
* @return {!Promise}
|
||||
*/
|
||||
async setUserAgentOverride(userAgent) {
|
||||
this._userAgent = userAgent;
|
||||
return this._client.send('Network.setUserAgentOverride', { userAgent });
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
userAgentOverride() {
|
||||
return this._userAgent;
|
||||
}
|
||||
|
||||
_handleException(exceptionDetails) {
|
||||
var stack = [];
|
||||
if (exceptionDetails.stackTrace) {
|
||||
stack = exceptionDetails.stackTrace.callFrames.map(cf => cf.url);
|
||||
}
|
||||
var stackTrace = exceptionDetails.stackTrace;
|
||||
this.emit(Page.Events.ExceptionThrown, exceptionDetails.exception.description, stack);
|
||||
}
|
||||
|
||||
_onConsoleAPI(event) {
|
||||
var values = event.args.map(arg => arg.value || arg.description || '');
|
||||
this.emit(Page.Events.ConsoleMessageAdded, values.join(' '));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {boolean} accept
|
||||
* @param {string} promptText
|
||||
* @return {!Promise}
|
||||
*/
|
||||
async handleDialog(accept, promptText) {
|
||||
return this._client.send('Page.handleJavaScriptDialog', {accept, promptText});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {!Promise<string>}
|
||||
*/
|
||||
async url() {
|
||||
return this.evaluate(function() {
|
||||
return window.location.href;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} html
|
||||
* @return {!Promise}
|
||||
*/
|
||||
async setContent(html) {
|
||||
var resourceTree = await this._client.send('Page.getResourceTree', {});
|
||||
await this._client.send('Page.setDocumentContent', {
|
||||
frameId: resourceTree.frameTree.frame.id,
|
||||
html: html
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} html
|
||||
* @return {!Promise<boolean>}
|
||||
*/
|
||||
async navigate(url) {
|
||||
var loadPromise = new Promise(fulfill => this._client.once('Page.loadEventFired', fulfill)).then(() => true);
|
||||
var interstitialPromise = new Promise(fulfill => this._client.once('Security.certificateError', fulfill)).then(() => false);
|
||||
var referrer = this._extraHeaders.referer;
|
||||
// Await for the command to throw exception in case of illegal arguments.
|
||||
await this._client.send('Page.navigate', {url, referrer});
|
||||
return await Promise.race([loadPromise, interstitialPromise]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!{width: number, height: number}} size
|
||||
* @return {!Promise}
|
||||
*/
|
||||
async setSize(size) {
|
||||
this._size = size;
|
||||
var width = size.width;
|
||||
var height = size.height;
|
||||
var zoom = this._screenDPI;
|
||||
return Promise.all([
|
||||
this._client.send('Emulation.setDeviceMetricsOverride', {
|
||||
width,
|
||||
height,
|
||||
deviceScaleFactor: 1,
|
||||
scale: 1 / zoom,
|
||||
mobile: false,
|
||||
fitWindow: false
|
||||
}),
|
||||
this._client.send('Emulation.setVisibleSize', {
|
||||
width: width / zoom,
|
||||
height: height / zoom,
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {!{width: number, height: number}}
|
||||
*/
|
||||
size() {
|
||||
return this._size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {function()} fun
|
||||
* @param {!Array<*>} args
|
||||
* @return {!Promise<(!Object|udndefined)>}
|
||||
*/
|
||||
async evaluate(fun, ...args) {
|
||||
var response = await helpers.evaluate(this._client, fun, args, false /* awaitPromise */);
|
||||
if (response.exceptionDetails) {
|
||||
this._handleException(response.exceptionDetails);
|
||||
return;
|
||||
}
|
||||
return response.result.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {function()} fun
|
||||
* @param {!Array<*>} args
|
||||
* @return {!Promise<(!Object|udndefined)>}
|
||||
*/
|
||||
async evaluateAsync(fun, ...args) {
|
||||
var response = await helpers.evaluate(this._client, fun, args, true /* awaitPromise */);
|
||||
if (response.exceptionDetails) {
|
||||
this._handleException(response.exceptionDetails);
|
||||
return;
|
||||
}
|
||||
return response.result.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!Page.ScreenshotType} screenshotType
|
||||
* @param {?{x: number, y: number, width: number, height: number}} clipRect
|
||||
* @return {!Promise<!Buffer>}
|
||||
*/
|
||||
async screenshot(screenshotType, clipRect) {
|
||||
if (clipRect) {
|
||||
await Promise.all([
|
||||
this._client.send('Emulation.setVisibleSize', {
|
||||
width: clipRect.width / this._screenDPI,
|
||||
height: clipRect.height / this._screenDPI,
|
||||
}),
|
||||
this._client.send('Emulation.forceViewport', {
|
||||
x: clipRect.x / this._screenDPI,
|
||||
y: clipRect.y / this._screenDPI,
|
||||
scale: 1,
|
||||
})
|
||||
]);
|
||||
}
|
||||
var result = await this._client.send('Page.captureScreenshot', {
|
||||
fromSurface: true,
|
||||
format: screenshotType,
|
||||
});
|
||||
if (clipRect) {
|
||||
await Promise.all([
|
||||
this.setSize(this.size()),
|
||||
this._client.send('Emulation.resetViewport')
|
||||
]);
|
||||
}
|
||||
return new Buffer(result.data, 'base64');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {!Promise<string>}
|
||||
*/
|
||||
async plainText() {
|
||||
return this.evaluate(function() {
|
||||
return document.body.innerText;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {!Promise<string>}
|
||||
*/
|
||||
async title() {
|
||||
return this.evaluate(function() {
|
||||
return document.title;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {!Promise}
|
||||
*/
|
||||
async close() {
|
||||
return this._browser.closePage(this);
|
||||
}
|
||||
}
|
||||
|
||||
/** @enum {string} */
|
||||
Page.ScreenshotTypes = {
|
||||
PNG: "png",
|
||||
JPG: "jpeg",
|
||||
};
|
||||
|
||||
Page.Events = {
|
||||
ConsoleMessageAdded: 'Page.Events.ConsoleMessageAdded',
|
||||
DialogOpened: 'Page.Events.DialogOpened',
|
||||
ExceptionThrown: 'Page.Events.ExceptionThrown',
|
||||
ResourceLoadingFailed: 'Page.Events.ResourceLoadingFailed',
|
||||
ResponseReceived: 'Page.Events.ResponseReceived',
|
||||
};
|
||||
|
||||
module.exports = Page;
|
68
lib/helpers.js
Normal file
68
lib/helpers.js
Normal file
@ -0,0 +1,68 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* @param {!CDP} client
|
||||
* @param {string} url
|
||||
* @return {!Promise<?Object>}
|
||||
*/
|
||||
waitForScriptWithURL: function(client, url) {
|
||||
var fulfill;
|
||||
var promise = new Promise(x => fulfill = x);
|
||||
client.on('Debugger.scriptParsed', onScriptParsed);
|
||||
client.on('Debugger.scriptFailedToParse', onScriptFailedToParse);
|
||||
return promise;
|
||||
|
||||
function onScriptParsed(event) {
|
||||
if (event.url !== url)
|
||||
return;
|
||||
client.removeListener('Debugger.scriptParsed', onScriptParsed);
|
||||
client.removeListener('Debugger.scriptFailedToParse', onScriptFailedToParse);
|
||||
fulfill(event);
|
||||
}
|
||||
|
||||
function onScriptFailedToParse(event) {
|
||||
if (event.url !== url)
|
||||
return;
|
||||
client.removeListener('Debugger.scriptParsed', onScriptParsed);
|
||||
client.removeListener('Debugger.scriptFailedToParse', onScriptFailedToParse);
|
||||
fulfill(null);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {!CDP} client
|
||||
* @param {function()} fun
|
||||
* @param {!Array<*>} args
|
||||
* @param {boolean} awaitPromise
|
||||
* @param {string=} sourceURL
|
||||
* @return {!Promise<!Object>}
|
||||
*/
|
||||
evaluate: function(client, fun, args, awaitPromise, sourceURL) {
|
||||
var argsString = args.map(x => JSON.stringify(x)).join(',');
|
||||
var code = `(${fun.toString()})(${argsString})`;
|
||||
if (awaitPromise)
|
||||
code = `Promise.resolve(${code})`;
|
||||
if (sourceURL)
|
||||
code += `\n//# sourceURL=${sourceURL}`;
|
||||
return client.send('Runtime.evaluate', {
|
||||
expression: code,
|
||||
awaitPromise: awaitPromise,
|
||||
returnByValue: true
|
||||
});
|
||||
},
|
||||
}
|
28
package.json
Normal file
28
package.json
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "puppeteer",
|
||||
"version": "0.0.1",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "python third_party/phantomjs/test/run-tests.py",
|
||||
"install": "node install.js"
|
||||
},
|
||||
"author": "The Chromium Authors",
|
||||
"license": "SEE LICENSE IN LICENSE",
|
||||
"dependencies": {
|
||||
"chrome-remote-interface": "^0.18.0",
|
||||
"deasync": "^0.1.9",
|
||||
"extract-zip": "^1.6.5",
|
||||
"mime": "^1.3.4",
|
||||
"minimist": "^1.2.0",
|
||||
"ncp": "^2.0.0",
|
||||
"progress": "^2.0.0",
|
||||
"rimraf": "^2.6.1"
|
||||
},
|
||||
"bin": {
|
||||
"puppeteer": "index.js"
|
||||
},
|
||||
"puppeteer": {
|
||||
"chromium_revision": "468266"
|
||||
}
|
||||
}
|
365
phantomjs/FileSystem.js
Normal file
365
phantomjs/FileSystem.js
Normal file
@ -0,0 +1,365 @@
|
||||
/**
|
||||
* 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 path = require('path');
|
||||
var fs = require('fs');
|
||||
var deasync = require('deasync');
|
||||
var removeRecursive = require('rimraf').sync;
|
||||
var copyRecursive = deasync(require('ncp').ncp);
|
||||
|
||||
class FileSystem {
|
||||
constructor() {
|
||||
this.separator = path.sep;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
get workingDirectory() {
|
||||
return process.cwd();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} directoryPath
|
||||
*/
|
||||
changeWorkingDirectory(directoryPath) {
|
||||
try {
|
||||
process.chdir(directoryPath);
|
||||
return true;
|
||||
} catch (e){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} relativePath
|
||||
* @return {string}
|
||||
*/
|
||||
absolute(relativePath) {
|
||||
relativePath = path.normalize(relativePath);
|
||||
if (path.isAbsolute(relativePath))
|
||||
return relativePath;
|
||||
return path.resolve(path.join(process.cwd(), relativePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} filePath
|
||||
* @return {boolean}
|
||||
*/
|
||||
exists(filePath) {
|
||||
return fs.existsSync(filePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} fromPath
|
||||
* @param {string} toPath
|
||||
*/
|
||||
copy(fromPath, toPath) {
|
||||
var content = fs.readFileSync(fromPath);
|
||||
fs.writeFileSync(toPath, content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} fromPath
|
||||
* @param {string} toPath
|
||||
*/
|
||||
move(fromPath, toPath) {
|
||||
var content = fs.readFileSync(fromPath);
|
||||
fs.writeFileSync(toPath, content);
|
||||
fs.unlinkSync(fromPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} filePath
|
||||
* @return {number}
|
||||
*/
|
||||
size(filePath) {
|
||||
return fs.statSync(filePath).size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} filePath
|
||||
*/
|
||||
touch(filePath) {
|
||||
fs.closeSync(fs.openSync(filePath, 'a'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} filePath
|
||||
*/
|
||||
remove(filePath) {
|
||||
fs.unlinkSync(filePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} filePath
|
||||
*/
|
||||
lastModified(filePath) {
|
||||
return fs.statSync(filePath).mtime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} dirPath
|
||||
*/
|
||||
makeDirectory(dirPath) {
|
||||
try {
|
||||
fs.mkdirSync(dirPath);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} dirPath
|
||||
*/
|
||||
removeTree(dirPath) {
|
||||
removeRecursive(dirPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} fromPath
|
||||
* @param {string} toPath
|
||||
*/
|
||||
copyTree(fromPath, toPath) {
|
||||
copyRecursive(fromPath, toPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} dirPath
|
||||
* @return {!Array<string>}
|
||||
*/
|
||||
list(dirPath) {
|
||||
return fs.readdirSync(dirPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} linkPath
|
||||
* @return {string}
|
||||
*/
|
||||
readLink(linkPath) {
|
||||
return fs.readlinkSync(linkPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} filePath
|
||||
* @param {Object} data
|
||||
* @param {string} mode
|
||||
*/
|
||||
write(filePath, data, mode) {
|
||||
var fd = new FileDescriptor(filePath, mode, 'utf8');
|
||||
fd.write(data);
|
||||
fd.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} somePath
|
||||
* @return {boolean}
|
||||
*/
|
||||
isAbsolute(somePath) {
|
||||
return path.isAbsolute(somePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
read(filePath) {
|
||||
return fs.readFileSync(filePath, 'utf8');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} filePath
|
||||
* @return {boolean}
|
||||
*/
|
||||
isFile(filePath) {
|
||||
return fs.existsSync(filePath) && fs.lstatSync(filePath).isFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} dirPath
|
||||
* @return {boolean}
|
||||
*/
|
||||
isDirectory(dirPath) {
|
||||
return fs.existsSync(dirPath) && fs.lstatSync(dirPath).isDirectory();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} filePath
|
||||
* @return {boolean}
|
||||
*/
|
||||
isLink(filePath) {
|
||||
return fs.existsSync(filePath) && fs.lstatSync(filePath).isSymbolicLink();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} filePath
|
||||
* @return {boolean}
|
||||
*/
|
||||
isReadable(filePath) {
|
||||
try {
|
||||
fs.accessSync(filePath, fs.constants.R_OK);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} filePath
|
||||
* @return {boolean}
|
||||
*/
|
||||
isWritable(filePath) {
|
||||
try {
|
||||
fs.accessSync(filePath, fs.constants.W_OK);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} filePath
|
||||
* @return {boolean}
|
||||
*/
|
||||
isExecutable(filePath) {
|
||||
try {
|
||||
fs.accessSync(filePath, fs.constants.X_OK);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} somePath
|
||||
* @return {!Array<string>}
|
||||
*/
|
||||
split(somePath) {
|
||||
somePath = path.normalize(somePath);
|
||||
if (somePath.endsWith(path.sep))
|
||||
somePath = somePath.substring(0, somePath.length - path.sep.length);
|
||||
return somePath.split(path.sep);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} path1
|
||||
* @param {string} path2
|
||||
* @return {string}
|
||||
*/
|
||||
join(...args) {
|
||||
if (args[0] === '' && args.length > 1)
|
||||
args[0] = path.sep;
|
||||
args = args.filter(part => typeof part === 'string');
|
||||
return path.join.apply(path, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} filePath
|
||||
* @param {(string|!Object)} option
|
||||
* @return {!FileDescriptor}
|
||||
*/
|
||||
open(filePath, option) {
|
||||
if (typeof option === 'string')
|
||||
return new FileDescriptor(filePath, option);
|
||||
return new FileDescriptor(filePath, option.mode);
|
||||
}
|
||||
}
|
||||
|
||||
var fdwrite = deasync(fs.write);
|
||||
var fdread = deasync(fs.read);
|
||||
|
||||
class FileDescriptor {
|
||||
/**
|
||||
* @param {string} filePath
|
||||
* @param {string} mode
|
||||
*/
|
||||
constructor(filePath, mode) {
|
||||
this._position = 0;
|
||||
this._encoding = 'utf8';
|
||||
if (mode === 'rb') {
|
||||
this._mode = 'r';
|
||||
this._encoding = 'latin1';
|
||||
} else if (mode === 'wb' || mode === 'b') {
|
||||
this._mode = 'w';
|
||||
this._encoding = 'latin1';
|
||||
} else if (mode === 'rw+') {
|
||||
this._mode = 'a+';
|
||||
this._position = fs.existsSync(filePath) ? fs.statSync(filePath).size : 0;
|
||||
} else {
|
||||
this._mode = mode;
|
||||
}
|
||||
this._fd = fs.openSync(filePath, this._mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} data
|
||||
*/
|
||||
write(data) {
|
||||
var buffer = Buffer.from(data, this._encoding);
|
||||
var written = fdwrite(this._fd, buffer, 0, buffer.length, this._position);
|
||||
this._position += written;
|
||||
}
|
||||
|
||||
getEncoding() {
|
||||
return 'UTF-8';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} data
|
||||
*/
|
||||
writeLine(data) {
|
||||
this.write(data + '\n');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number=} size
|
||||
* @return {string}
|
||||
*/
|
||||
read(size) {
|
||||
var position = this._position;
|
||||
if (!size) {
|
||||
size = fs.fstatSync(this._fd).size;
|
||||
position = 0;
|
||||
}
|
||||
var buffer = new Buffer(size);
|
||||
var bytesRead = fdread(this._fd, buffer, 0, size, position);
|
||||
this._position += bytesRead;
|
||||
return buffer.toString(this._encoding);
|
||||
}
|
||||
|
||||
flush() {
|
||||
// noop.
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} position
|
||||
*/
|
||||
seek(position) {
|
||||
this._position = position;
|
||||
}
|
||||
|
||||
close() {
|
||||
fs.closeSync(this._fd);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
atEnd() {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = FileSystem;
|
139
phantomjs/Phantom.js
Normal file
139
phantomjs/Phantom.js
Normal file
@ -0,0 +1,139 @@
|
||||
/**
|
||||
* 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 fs = require('fs');
|
||||
var path = require('path');
|
||||
var vm = require('vm');
|
||||
var url = require('url');
|
||||
|
||||
/**
|
||||
* @param {!Object} context
|
||||
* @param {string} scriptPath
|
||||
*/
|
||||
module.exports.create = function(context, scriptPath) {
|
||||
var phantom = {
|
||||
page: {
|
||||
onConsoleMessage: null,
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} relative
|
||||
* @param {string} base
|
||||
* @return {string}
|
||||
*/
|
||||
resolveRelativeUrl: function(relative, base) {
|
||||
return url.resolve(base, relative);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} url
|
||||
* @return {string}
|
||||
*/
|
||||
fullyDecodeUrl: function(url) {
|
||||
return decodeURI(url);
|
||||
},
|
||||
|
||||
libraryPath: path.dirname(scriptPath),
|
||||
|
||||
onError: null,
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
get outputEncoding() {
|
||||
return 'UTF-8';
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
*/
|
||||
set outputEncoding(value) {
|
||||
throw new Error('Phantom.outputEncoding setter is not implemented');
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
get cookiesEnabled() {
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {boolean} value
|
||||
*/
|
||||
set cookiesEnabled(value) {
|
||||
throw new Error('Phantom.cookiesEnabled setter is not implemented');
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {!{major: number, minor: number, patch: number}}
|
||||
*/
|
||||
get version() {
|
||||
var versionParts = require('../package.json').version.split('.');
|
||||
return {
|
||||
major: parseInt(versionParts[0], 10),
|
||||
minor: parseInt(versionParts[1], 10),
|
||||
patch: parseInt(versionParts[2], 10),
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {number=} code
|
||||
*/
|
||||
exit: function(code) {
|
||||
process.exit(code);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} filePath
|
||||
* @return {boolean}
|
||||
*/
|
||||
injectJs: function(filePath) {
|
||||
filePath = path.resolve(phantom.libraryPath, filePath);
|
||||
if (!fs.existsSync(filePath))
|
||||
return false;
|
||||
var code = fs.readFileSync(filePath, 'utf8');
|
||||
if (code.startsWith('#!'))
|
||||
code = code.substring(code.indexOf('\n'));
|
||||
vm.runInContext(code, context, {
|
||||
filename: filePath,
|
||||
displayErrors: true
|
||||
});
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} moduleSource
|
||||
* @param {string} filename
|
||||
*/
|
||||
loadModule: function(moduleSource, filename) {
|
||||
var code = [
|
||||
"(function(require, exports, module) {\n",
|
||||
moduleSource,
|
||||
"\n}.call({},",
|
||||
"require.cache['" + filename + "']._getRequire(),",
|
||||
"require.cache['" + filename + "'].exports,",
|
||||
"require.cache['" + filename + "']",
|
||||
"));"
|
||||
].join('');
|
||||
vm.runInContext(code, context, {
|
||||
filename: filename,
|
||||
displayErrors: true
|
||||
});
|
||||
},
|
||||
};
|
||||
return phantom;
|
||||
}
|
118
phantomjs/System.js
Normal file
118
phantomjs/System.js
Normal file
@ -0,0 +1,118 @@
|
||||
/**
|
||||
* 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 readline = require('readline');
|
||||
var await = require('./utilities').await;
|
||||
var os = require('os');
|
||||
|
||||
class System {
|
||||
/**
|
||||
* @param {!Array<string>} args
|
||||
*/
|
||||
constructor(args) {
|
||||
this.args = args;
|
||||
this.env = {};
|
||||
Object.assign(this.env, process.env);
|
||||
this.stdin = new StandardInput(process.stdin);
|
||||
this.stdout = new StandardOutput(process.stdout);
|
||||
this.stderr = new StandardOutput(process.stderr);
|
||||
this.platform = "phantomjs";
|
||||
this.pid = process.pid;
|
||||
this.isSSLSupported = false;
|
||||
this.os = {
|
||||
architecture: os.arch(),
|
||||
name: os.type(),
|
||||
version: os.release()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class StandardInput {
|
||||
/**
|
||||
* @param {!Readable} readableStream
|
||||
*/
|
||||
constructor(readableStream) {
|
||||
this._readline = readline.createInterface({
|
||||
input: readableStream
|
||||
});
|
||||
this._lines = [];
|
||||
this._closed = false;
|
||||
this._readline.on('line', line => this._lines.push(line));
|
||||
this._readline.on('close', () => this._closed = true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
readLine() {
|
||||
if (this._closed && !this._lines.length)
|
||||
return '';
|
||||
if (!this._lines.length) {
|
||||
var linePromise = new Promise(fulfill => this._readline.once('line', fulfill));
|
||||
await(linePromise);
|
||||
}
|
||||
return this._lines.shift();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
read() {
|
||||
if (!this._closed) {
|
||||
var closePromise = new Promise(fulfill => this._readline.once('close', fulfill));
|
||||
await(closePromise);
|
||||
}
|
||||
var text = this._lines.join('\n');
|
||||
this._lines = [];
|
||||
return text;
|
||||
}
|
||||
|
||||
close() {
|
||||
this._readline.close();
|
||||
}
|
||||
}
|
||||
|
||||
class StandardOutput {
|
||||
/**
|
||||
* @param {!Writable} writableStream
|
||||
*/
|
||||
constructor(writableStream) {
|
||||
this._stream = writableStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} data
|
||||
*/
|
||||
write(data) {
|
||||
this._stream.write(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} data
|
||||
*/
|
||||
writeLine(data) {
|
||||
this._stream.write(data + '\n');
|
||||
}
|
||||
|
||||
flush() {
|
||||
}
|
||||
|
||||
close() {
|
||||
this._stream.end();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = System;
|
327
phantomjs/WebPage.js
Normal file
327
phantomjs/WebPage.js
Normal file
@ -0,0 +1,327 @@
|
||||
/**
|
||||
* 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 await = require('./utilities').await;
|
||||
var EventEmitter = require('events');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var mime = require('mime');
|
||||
|
||||
var PageEvents = require('../lib/Page').Events;
|
||||
var ScreenshotTypes = require('../lib/Page').ScreenshotTypes;
|
||||
|
||||
var noop = function() { };
|
||||
|
||||
class WebPage {
|
||||
/**
|
||||
* @param {!Browser} browser
|
||||
* @param {string} scriptPath
|
||||
* @param {!Object=} options
|
||||
*/
|
||||
constructor(browser, scriptPath, options) {
|
||||
this._page = await(browser.newPage());
|
||||
this.settings = new WebPageSettings(this._page);
|
||||
|
||||
options = options || {};
|
||||
options.settings = options.settings || {};
|
||||
if (options.settings.userAgent)
|
||||
this.settings.userAgent = options.settings.userAgent;
|
||||
if (options.viewportSize)
|
||||
await(this._page.setSize(options.viewportSize));
|
||||
|
||||
await(this._page.setInPageCallback('callPhantom', (...args) => {
|
||||
return this.onCallback.apply(null, args);
|
||||
}));
|
||||
|
||||
this.clipRect = options.clipRect || {left: 0, top: 0, width: 0, height: 0};
|
||||
this.onCallback = null;
|
||||
this.onConsoleMessage = null;
|
||||
this.onLoadFinished = null;
|
||||
this.onResourceError = null;
|
||||
this.onResourceReceived = null;
|
||||
this.libraryPath = path.dirname(scriptPath);
|
||||
|
||||
this._onConfirm = undefined;
|
||||
this._onError = noop;
|
||||
|
||||
this._pageEvents = new AsyncEmitter(this._page);
|
||||
this._pageEvents.on(PageEvents.ResponseReceived, response => this._onResponseReceived(response));
|
||||
this._pageEvents.on(PageEvents.ResourceLoadingFailed, event => (this.onResourceError || noop).call(null, event));
|
||||
this._pageEvents.on(PageEvents.ConsoleMessageAdded, msg => (this.onConsoleMessage || noop).call(null, msg));
|
||||
this._pageEvents.on(PageEvents.DialogOpened, dialog => this._onDialog(dialog));
|
||||
this._pageEvents.on(PageEvents.ExceptionThrown, (exception, stack) => (this._onError || noop).call(null, exception, stack));
|
||||
}
|
||||
|
||||
_onResponseReceived(response) {
|
||||
if (!this.onResourceReceived)
|
||||
return;
|
||||
var headers = [];
|
||||
for (var key in response.headers) {
|
||||
headers.push({
|
||||
name: key,
|
||||
value: response.headers[key]
|
||||
});
|
||||
}
|
||||
response.headers = headers;
|
||||
this.onResourceReceived.call(null, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} url
|
||||
* @param {function()} callback
|
||||
*/
|
||||
includeJs(url, callback) {
|
||||
this._page.evaluateAsync(include, url).then(callback);
|
||||
|
||||
function include(url) {
|
||||
var script = document.createElement('script');
|
||||
script.src = url;
|
||||
var promise = new Promise(x => script.onload = x);
|
||||
document.head.appendChild(script);
|
||||
return promise;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {!{width: number, height: number}}
|
||||
*/
|
||||
get viewportSize() {
|
||||
return this._page.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {!Object}
|
||||
*/
|
||||
get customHeaders() {
|
||||
return this._page.extraHTTPHeaders();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!Object} value
|
||||
*/
|
||||
set customHeaders(value) {
|
||||
await(this._page.setExtraHTTPHeaders(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} filePath
|
||||
*/
|
||||
injectJs(filePath) {
|
||||
if (!fs.existsSync(filePath))
|
||||
filePath = path.resolve(this.libraryPath, filePath);
|
||||
if (!fs.existsSync(filePath))
|
||||
return;
|
||||
var code = fs.readFileSync(filePath, 'utf8');
|
||||
this.evaluate(code);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
get plainText() {
|
||||
return await(this._page.plainText());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
get title() {
|
||||
return await(this._page.title());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {(function()|undefined)}
|
||||
*/
|
||||
get onError() {
|
||||
return this._onError;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {(function()|undefined)} handler
|
||||
*/
|
||||
set onError(handler) {
|
||||
if (typeof handler !== 'function')
|
||||
handler = undefined;
|
||||
this._onError = handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {(function()|undefined)}
|
||||
*/
|
||||
get onConfirm() {
|
||||
return this._onConfirm;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {function()} handler
|
||||
*/
|
||||
set onConfirm(handler) {
|
||||
if (typeof handler !== 'function')
|
||||
handler = undefined;
|
||||
this._onConfirm = handler;
|
||||
}
|
||||
|
||||
_onDialog(dialog) {
|
||||
if (!this._onConfirm)
|
||||
return;
|
||||
var accept = this._onConfirm.call(null);
|
||||
await(this._page.handleDialog(accept));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
get url() {
|
||||
return await(this._page.url());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} html
|
||||
*/
|
||||
set content(html) {
|
||||
await(this._page.setContent(html));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} html
|
||||
* @param {function()=} callback
|
||||
*/
|
||||
open(url, callback) {
|
||||
console.assert(arguments.length <= 2, 'WebPage.open does not support METHOD and DATA arguments');
|
||||
this._page.navigate(url).then(result => {
|
||||
var status = result ? 'success' : 'fail';
|
||||
if (!result) {
|
||||
this.onResourceError.call(null, {
|
||||
url,
|
||||
errorString: 'SSL handshake failed'
|
||||
});
|
||||
}
|
||||
if (this.onLoadFinished)
|
||||
this.onLoadFinished.call(null, status);
|
||||
if (callback)
|
||||
callback.call(null, status);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!{width: number, height: number}} options
|
||||
*/
|
||||
set viewportSize(options) {
|
||||
await(this._page.setSize(options));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {function()} fun
|
||||
* @param {!Array<!Object>} args
|
||||
*/
|
||||
evaluate(fun, ...args) {
|
||||
return await(this._page.evaluate(fun, ...args));
|
||||
}
|
||||
|
||||
/**
|
||||
* {string} fileName
|
||||
*/
|
||||
render(fileName) {
|
||||
var mimeType = mime.lookup(fileName);
|
||||
var screenshotType = null;
|
||||
if (mimeType === 'image/png')
|
||||
screenshotType = ScreenshotTypes.PNG;
|
||||
else if (mimeType === 'image/jpeg')
|
||||
screenshotType = ScreenshotTypes.JPG;
|
||||
if (!screenshotType)
|
||||
throw new Error(`Cannot render to file ${fileName} - unsupported mimeType ${mimeType}`);
|
||||
var clipRect = null;
|
||||
if (this.clipRect && (this.clipRect.left || this.clipRect.top || this.clipRect.width || this.clipRect.height)) {
|
||||
clipRect = {
|
||||
x: this.clipRect.left,
|
||||
y: this.clipRect.top,
|
||||
width: this.clipRect.width,
|
||||
height: this.clipRect.height
|
||||
};
|
||||
}
|
||||
var imageBuffer = await(this._page.screenshot(screenshotType, clipRect));
|
||||
fs.writeFileSync(fileName, imageBuffer);
|
||||
}
|
||||
|
||||
release() {
|
||||
this._page.close();
|
||||
}
|
||||
|
||||
close() {
|
||||
this._page.close();
|
||||
}
|
||||
}
|
||||
|
||||
class WebPageSettings {
|
||||
/**
|
||||
* @param {!Page} page
|
||||
*/
|
||||
constructor(page) {
|
||||
this._page = page;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
*/
|
||||
set userAgent(value) {
|
||||
await(this._page.setUserAgentOverride(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
get userAgent() {
|
||||
return this._page.userAgentOverride();
|
||||
}
|
||||
}
|
||||
|
||||
// To prevent reenterability, eventemitters should emit events
|
||||
// only being in a consistent state.
|
||||
// This is not the case for 'ws' npm module: https://goo.gl/sy3dJY
|
||||
//
|
||||
// Since out phantomjs environment uses nested event loops, we
|
||||
// exploit this condition in 'ws', which probably never happens
|
||||
// in case of regular I/O.
|
||||
//
|
||||
// This class is a wrapper around EventEmitter which re-emits events asynchronously,
|
||||
// helping to overcome the issue.
|
||||
class AsyncEmitter extends EventEmitter {
|
||||
/**
|
||||
* @param {!Page} page
|
||||
*/
|
||||
constructor(page) {
|
||||
super();
|
||||
this._page = page;
|
||||
this._symbol = Symbol('AsyncEmitter');
|
||||
this.on('newListener', this._onListenerAdded);
|
||||
this.on('removeListener', this._onListenerRemoved);
|
||||
}
|
||||
|
||||
_onListenerAdded(event, listener) {
|
||||
// Async listener calls original listener on next tick.
|
||||
var asyncListener = (...args) => {
|
||||
process.nextTick(() => listener.apply(null, args));
|
||||
};
|
||||
listener[this._symbol] = asyncListener;
|
||||
this._page.on(event, asyncListener);
|
||||
}
|
||||
|
||||
_onListenerRemoved(event, listener) {
|
||||
this._page.removeListener(event, listener[this._symbol]);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = WebPage;
|
83
phantomjs/WebServer.js
Normal file
83
phantomjs/WebServer.js
Normal file
@ -0,0 +1,83 @@
|
||||
/**
|
||||
* 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 http = require('http');
|
||||
var await = require('./utilities').await;
|
||||
|
||||
class WebServer {
|
||||
constructor() {
|
||||
this._server = http.createServer();
|
||||
this.objectName = 'WebServer';
|
||||
this.listenOnPort = this.listen;
|
||||
this.newRequest = function(req, res) { }
|
||||
Object.defineProperty(this, 'port', {
|
||||
get: () => {
|
||||
if (!this._server.listening)
|
||||
return '';
|
||||
return this._server.address().port + '';
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: false
|
||||
});
|
||||
}
|
||||
|
||||
close() {
|
||||
this._server.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {nubmer} port
|
||||
* @return {boolean}
|
||||
*/
|
||||
listen(port, callback) {
|
||||
if (this._server.listening)
|
||||
return false;
|
||||
this.newRequest = callback;
|
||||
this._server.listen(port);
|
||||
var errorPromise = new Promise(x => this._server.once('error', x));
|
||||
var successPromise = new Promise(x => this._server.once('listening', x));
|
||||
await(Promise.race([errorPromise, successPromise]));
|
||||
if (!this._server.listening)
|
||||
return false;
|
||||
|
||||
this._server.on('request', (req, res) => {
|
||||
res.close = res.end.bind(res);
|
||||
var headers = res.getHeaders();
|
||||
res.headers = [];
|
||||
for (var key in headers) {
|
||||
res.headers.push({
|
||||
name: key,
|
||||
value: headers[key]
|
||||
});
|
||||
}
|
||||
res.header = res.getHeader;
|
||||
res.setHeaders = (headers) => {
|
||||
for (var key in headers)
|
||||
res.setHeader(key, headers[key]);
|
||||
}
|
||||
Object.defineProperty(res, 'statusCode', {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: res.statusCode
|
||||
});
|
||||
this.newRequest.call(null, req, res);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = WebServer;
|
71
phantomjs/index.js
Normal file
71
phantomjs/index.js
Normal file
@ -0,0 +1,71 @@
|
||||
/**
|
||||
* 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 path = require('path');
|
||||
var fs = require('fs');
|
||||
var Phantom = require('./Phantom');
|
||||
var FileSystem = require('./FileSystem');
|
||||
var System = require('./System');
|
||||
var WebPage = require('./WebPage');
|
||||
var WebServer = require('./WebServer');
|
||||
var child_process = require('child_process');
|
||||
|
||||
var bootstrapPath = path.join(__dirname, '..', 'third_party', 'phantomjs', 'bootstrap.js');
|
||||
var bootstrapCode = fs.readFileSync(bootstrapPath, 'utf8');
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* @param {!Browser} browser
|
||||
* @param {string} scriptPath
|
||||
* @param {!Array<string>} argv
|
||||
* @return {!Object}
|
||||
*/
|
||||
createContext(browser, scriptPath, argv) {
|
||||
var context = {};
|
||||
context.setInterval = setInterval;
|
||||
context.setTimeout = setTimeout;
|
||||
context.clearInterval = clearInterval;
|
||||
context.clearTimeout = clearTimeout;
|
||||
|
||||
context.phantom = Phantom.create(context, scriptPath);
|
||||
context.console = console;
|
||||
context.window = context;
|
||||
context.WebPage = (options) => new WebPage(browser, scriptPath, options);
|
||||
|
||||
vm.createContext(context);
|
||||
|
||||
var nativeExports = {
|
||||
fs: new FileSystem(),
|
||||
system: new System(argv._),
|
||||
webpage: {
|
||||
create: context.WebPage,
|
||||
},
|
||||
webserver: {
|
||||
create: () => new WebServer(),
|
||||
},
|
||||
cookiejar: {
|
||||
create: () => {},
|
||||
},
|
||||
child_process: child_process
|
||||
};
|
||||
vm.runInContext(bootstrapCode, context, {
|
||||
filename: 'bootstrap.js'
|
||||
})(nativeExports);
|
||||
return context;
|
||||
}
|
||||
}
|
||||
|
33
phantomjs/utilities.js
Normal file
33
phantomjs/utilities.js
Normal file
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* 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 loopWhile = require('deasync').loopWhile;
|
||||
|
||||
module.exports = {
|
||||
await: function(promise) {
|
||||
var error;
|
||||
var result;
|
||||
var done = false;
|
||||
promise.then(r => result = r)
|
||||
.catch(err => error = err)
|
||||
.then(() => done = true);
|
||||
loopWhile(() => !done);
|
||||
if (error)
|
||||
throw error;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
19
third_party/phantomjs/CHANGES.md
vendored
Normal file
19
third_party/phantomjs/CHANGES.md
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
Short Name: phantomjs
|
||||
URL: https://github.com/ariya/phantomjs/tree/2.1.1
|
||||
Version: 2.1.1
|
||||
License: BSD
|
||||
License File: LICENSE.BSD
|
||||
Security Critical: no
|
||||
|
||||
Description:
|
||||
This package is used to aid puppeteer in running phantom.js scripts:
|
||||
- test/ - testsuite is used to validate puppeteer running phantom.js scripts
|
||||
- boostrap.js - used to bootstrap puppeteer environment
|
||||
|
||||
Local Modifications:
|
||||
|
||||
- test/run_test.py was changed to run puppeteer instead of phantomjs
|
||||
- Certain tests under test/ were changed where tests were unreasonably strict in their expectations
|
||||
(e.g. validating the exact format of error messages)
|
||||
- bootstrap.js was changed to accept native modules as function arguments.
|
||||
- test/run_test.py was enhanced to support "unsupported" directive
|
22
third_party/phantomjs/LICENSE.BSD
vendored
Normal file
22
third_party/phantomjs/LICENSE.BSD
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
235
third_party/phantomjs/bootstrap.js
vendored
Normal file
235
third_party/phantomjs/bootstrap.js
vendored
Normal file
@ -0,0 +1,235 @@
|
||||
/*jslint sloppy: true, nomen: true */
|
||||
/*global window:true,phantom:true */
|
||||
|
||||
/*
|
||||
This file is part of the PhantomJS project from Ofi Labs.
|
||||
|
||||
Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>
|
||||
Copyright (C) 2011 Ivan De Marino <ivan.de.marino@gmail.com>
|
||||
Copyright (C) 2011 James Roe <roejames12@hotmail.com>
|
||||
Copyright (C) 2011 execjosh, http://execjosh.blogspot.com
|
||||
Copyright (C) 2012 James M. Greene <james.m.greene@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
(function(nativeExports) {
|
||||
// CommonJS module implementation follows
|
||||
|
||||
window.global = window;
|
||||
// fs is loaded at the end, when everything is ready
|
||||
var fs;
|
||||
var cache = {};
|
||||
var paths = [];
|
||||
var extensions = {
|
||||
'.js': function(module, filename) {
|
||||
var code = fs.read(filename);
|
||||
module._compile(code);
|
||||
},
|
||||
|
||||
'.json': function(module, filename) {
|
||||
module.exports = JSON.parse(fs.read(filename));
|
||||
}
|
||||
};
|
||||
|
||||
function dirname(path) {
|
||||
var replaced = path.replace(/\/[^\/]*\/?$/, '');
|
||||
if (replaced == path) {
|
||||
replaced = '';
|
||||
}
|
||||
return replaced;
|
||||
}
|
||||
|
||||
function basename(path) {
|
||||
return path.replace(/.*\//, '');
|
||||
}
|
||||
|
||||
function joinPath() {
|
||||
// It should be okay to hard-code a slash here.
|
||||
// The FileSystem module returns a platform-specific
|
||||
// separator, but the JavaScript engine only expects
|
||||
// the slash.
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
return args.join('/');
|
||||
}
|
||||
|
||||
function tryFile(path) {
|
||||
if (fs.isFile(path)) return path;
|
||||
return null;
|
||||
}
|
||||
|
||||
function tryExtensions(path) {
|
||||
var filename, exts = Object.keys(extensions);
|
||||
for (var i=0; i<exts.length; ++i) {
|
||||
filename = tryFile(path + exts[i]);
|
||||
if (filename) return filename;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function tryPackage(path) {
|
||||
var filename, package, packageFile = joinPath(path, 'package.json');
|
||||
if (fs.isFile(packageFile)) {
|
||||
package = JSON.parse(fs.read(packageFile));
|
||||
if (!package || !package.main) return null;
|
||||
|
||||
filename = fs.absolute(joinPath(path, package.main));
|
||||
|
||||
return tryFile(filename) || tryExtensions(filename) ||
|
||||
tryExtensions(joinPath(filename, 'index'));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function Module(filename, stubs) {
|
||||
if (filename) this._setFilename(filename);
|
||||
this.exports = {};
|
||||
this.stubs = {};
|
||||
for (var name in stubs) {
|
||||
this.stubs[name] = stubs[name];
|
||||
}
|
||||
}
|
||||
|
||||
Module.prototype._setFilename = function(filename) {
|
||||
this.id = this.filename = filename;
|
||||
this.dirname = dirname(filename);
|
||||
};
|
||||
|
||||
Module.prototype._isNative = function() {
|
||||
return this.filename && this.filename[0] === ':';
|
||||
};
|
||||
|
||||
Module.prototype._getPaths = function(request) {
|
||||
var _paths = [], dir;
|
||||
|
||||
if (request[0] === '.') {
|
||||
_paths.push(fs.absolute(joinPath(phantom.webdriverMode ? ":/ghostdriver" : this.dirname, request)));
|
||||
} else if (fs.isAbsolute(request)) {
|
||||
_paths.push(fs.absolute(request));
|
||||
} else {
|
||||
// first look in PhantomJS modules
|
||||
_paths.push(joinPath(':/modules', request));
|
||||
// then look in node_modules directories
|
||||
if (!this._isNative()) {
|
||||
dir = this.dirname;
|
||||
while (dir) {
|
||||
_paths.push(joinPath(dir, 'node_modules', request));
|
||||
dir = dirname(dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i=0; i<paths.length; ++i) {
|
||||
if(fs.isAbsolute(paths[i])) {
|
||||
_paths.push(fs.absolute(joinPath(paths[i], request)));
|
||||
} else {
|
||||
_paths.push(fs.absolute(joinPath(this.dirname, paths[i], request)));
|
||||
}
|
||||
}
|
||||
|
||||
return _paths;
|
||||
};
|
||||
|
||||
Module.prototype._getFilename = function(request) {
|
||||
if (nativeExports[request])
|
||||
return ':/modules/' + request + '.js';
|
||||
var path, filename = null, _paths = this._getPaths(request);
|
||||
|
||||
for (var i=0; i<_paths.length && !filename; ++i) {
|
||||
path = _paths[i];
|
||||
filename = tryFile(path) || tryExtensions(path) || tryPackage(path) ||
|
||||
tryExtensions(joinPath(path, 'index'));
|
||||
}
|
||||
|
||||
return filename;
|
||||
};
|
||||
|
||||
Module.prototype._getRequire = function() {
|
||||
var self = this;
|
||||
|
||||
function require(request) {
|
||||
return self.require(request);
|
||||
}
|
||||
require.cache = cache;
|
||||
require.extensions = extensions;
|
||||
require.paths = paths;
|
||||
require.stub = function(request, exports) {
|
||||
self.stubs[request] = { exports: exports };
|
||||
};
|
||||
|
||||
return require;
|
||||
};
|
||||
|
||||
Module.prototype._load = function() {
|
||||
if (this._isNative())
|
||||
return;
|
||||
var ext = this.filename.match(/\.[^.]+$/)[0];
|
||||
if (!ext) ext = '.js';
|
||||
extensions[ext](this, this.filename);
|
||||
};
|
||||
|
||||
Module.prototype._compile = function(code) {
|
||||
phantom.loadModule(code, this.filename);
|
||||
};
|
||||
|
||||
Module.prototype.require = function(request) {
|
||||
var filename, module;
|
||||
|
||||
// first see if there are any stubs for the request
|
||||
if (this.stubs.hasOwnProperty(request)) {
|
||||
if (this.stubs[request].exports instanceof Function) {
|
||||
this.stubs[request].exports = this.stubs[request].exports();
|
||||
}
|
||||
return this.stubs[request].exports;
|
||||
}
|
||||
|
||||
// else look for a file
|
||||
filename = this._getFilename(request);
|
||||
if (!filename) {
|
||||
throw new Error("Cannot find module '" + request + "'");
|
||||
}
|
||||
|
||||
if (cache.hasOwnProperty(filename)) {
|
||||
return cache[filename].exports;
|
||||
}
|
||||
|
||||
module = new Module(filename, this.stubs);
|
||||
if (module._isNative()) {
|
||||
module.exports = nativeExports[request] || {};
|
||||
}
|
||||
cache[filename] = module;
|
||||
module._load();
|
||||
|
||||
return module.exports;
|
||||
};
|
||||
|
||||
(function() {
|
||||
var cwd, mainFilename, mainModule = new Module();
|
||||
window.require = mainModule._getRequire();
|
||||
fs = nativeExports.fs;
|
||||
cwd = fs.absolute(phantom.libraryPath);
|
||||
mainFilename = joinPath(cwd, basename(require('system').args[0]) || 'repl');
|
||||
mainModule._setFilename(mainFilename);
|
||||
}());
|
||||
})
|
52
third_party/phantomjs/examples/colorwheel.js
vendored
Normal file
52
third_party/phantomjs/examples/colorwheel.js
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
"use strict";
|
||||
var page = require('webpage').create();
|
||||
page.viewportSize = { width: 400, height : 400 };
|
||||
page.content = '<html><body><canvas id="surface"></canvas></body></html>';
|
||||
page.evaluate(function() {
|
||||
var el = document.getElementById('surface'),
|
||||
context = el.getContext('2d'),
|
||||
width = window.innerWidth,
|
||||
height = window.innerHeight,
|
||||
cx = width / 2,
|
||||
cy = height / 2,
|
||||
radius = width / 2.3,
|
||||
imageData,
|
||||
pixels,
|
||||
hue, sat, value,
|
||||
i = 0, x, y, rx, ry, d,
|
||||
f, g, p, u, v, w, rgb;
|
||||
|
||||
el.width = width;
|
||||
el.height = height;
|
||||
imageData = context.createImageData(width, height);
|
||||
pixels = imageData.data;
|
||||
|
||||
for (y = 0; y < height; y = y + 1) {
|
||||
for (x = 0; x < width; x = x + 1, i = i + 4) {
|
||||
rx = x - cx;
|
||||
ry = y - cy;
|
||||
d = rx * rx + ry * ry;
|
||||
if (d < radius * radius) {
|
||||
hue = 6 * (Math.atan2(ry, rx) + Math.PI) / (2 * Math.PI);
|
||||
sat = Math.sqrt(d) / radius;
|
||||
g = Math.floor(hue);
|
||||
f = hue - g;
|
||||
u = 255 * (1 - sat);
|
||||
v = 255 * (1 - sat * f);
|
||||
w = 255 * (1 - sat * (1 - f));
|
||||
pixels[i] = [255, v, u, u, w, 255, 255][g];
|
||||
pixels[i + 1] = [w, 255, 255, v, u, u, w][g];
|
||||
pixels[i + 2] = [u, u, w, 255, 255, v, u][g];
|
||||
pixels[i + 3] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context.putImageData(imageData, 0, 0);
|
||||
document.body.style.backgroundColor = 'white';
|
||||
document.body.style.margin = '0px';
|
||||
});
|
||||
|
||||
page.render('colorwheel.png');
|
||||
|
||||
phantom.exit();
|
8
third_party/phantomjs/test/basics/exit0.js
vendored
Normal file
8
third_party/phantomjs/test/basics/exit0.js
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
//! no-harness
|
||||
//! expect-exit: 0
|
||||
//! expect-stdout: "we are alive"
|
||||
|
||||
var sys = require('system');
|
||||
sys.stdout.write("we are alive\n");
|
||||
phantom.exit();
|
||||
sys.stdout.write("ERROR control passed beyond phantom.exit");
|
8
third_party/phantomjs/test/basics/exit23.js
vendored
Normal file
8
third_party/phantomjs/test/basics/exit23.js
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
//! no-harness
|
||||
//! expect-exit: 23
|
||||
//! expect-stdout: "we are alive"
|
||||
|
||||
var sys = require('system');
|
||||
sys.stdout.write("we are alive\n");
|
||||
phantom.exit(23);
|
||||
sys.stdout.write("ERROR control passed beyond phantom.exit");
|
27
third_party/phantomjs/test/basics/module.js
vendored
Normal file
27
third_party/phantomjs/test/basics/module.js
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
// Test the properties of the 'module' object.
|
||||
// Assumes the 'dummy_exposed' module is to be found in a directory
|
||||
// named 'node_modules'.
|
||||
|
||||
// Module load might fail, so do it in a setup function.
|
||||
var module;
|
||||
setup(function () {
|
||||
module = require("dummy_exposed");
|
||||
});
|
||||
|
||||
test(function() {
|
||||
assert_regexp_match(module.filename, /\/node_modules\/dummy_exposed\.js$/);
|
||||
}, "module.filename is the absolute pathname of the module .js file");
|
||||
|
||||
test(function() {
|
||||
assert_regexp_match(module.dirname, /\/node_modules$/);
|
||||
}, "module.dirname is the absolute pathname of the directory containing "+
|
||||
"the module");
|
||||
|
||||
test(function() {
|
||||
assert_equals(module.id, module.filename);
|
||||
}, "module.id equals module.filename");
|
||||
|
||||
test(function() {
|
||||
var dummy_file = module.require('./dummy_file');
|
||||
assert_equals(dummy_file, 'spec/node_modules/dummy_file');
|
||||
}, "module.require is callable and resolves relative to the module");
|
39
third_party/phantomjs/test/basics/phantom-object.js
vendored
Normal file
39
third_party/phantomjs/test/basics/phantom-object.js
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
test(function () {
|
||||
assert_type_of(phantom, 'object');
|
||||
}, "phantom object");
|
||||
|
||||
test(function () {
|
||||
assert_own_property(phantom, 'libraryPath');
|
||||
assert_type_of(phantom.libraryPath, 'string');
|
||||
assert_greater_than(phantom.libraryPath.length, 0);
|
||||
}, "phantom.libraryPath");
|
||||
|
||||
test(function () {
|
||||
assert_own_property(phantom, 'outputEncoding');
|
||||
assert_type_of(phantom.outputEncoding, 'string');
|
||||
assert_equals(phantom.outputEncoding.toLowerCase(), 'utf-8'); // default
|
||||
}, "phantom.outputEncoding");
|
||||
|
||||
test(function () {
|
||||
assert_own_property(phantom, 'injectJs');
|
||||
assert_type_of(phantom.injectJs, 'function');
|
||||
}, "phantom.injectJs");
|
||||
|
||||
test(function () {
|
||||
assert_own_property(phantom, 'exit');
|
||||
assert_type_of(phantom.exit, 'function');
|
||||
}, "phantom.exit");
|
||||
|
||||
test(function () {
|
||||
assert_own_property(phantom, 'cookiesEnabled');
|
||||
assert_type_of(phantom.cookiesEnabled, 'boolean');
|
||||
assert_is_true(phantom.cookiesEnabled);
|
||||
}, "phantom.cookiesEnabled");
|
||||
|
||||
test(function () {
|
||||
assert_own_property(phantom, 'version');
|
||||
assert_type_of(phantom.version, 'object');
|
||||
assert_type_of(phantom.version.major, 'number');
|
||||
assert_type_of(phantom.version.minor, 'number');
|
||||
assert_type_of(phantom.version.patch, 'number');
|
||||
}, "phantom.version");
|
10
third_party/phantomjs/test/basics/require.js
vendored
Normal file
10
third_party/phantomjs/test/basics/require.js
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
/* The require tests need to run inside a module to work correctly; that
|
||||
module is require/require_spec.js. (That directory also contains a
|
||||
bunch of other files used by this test.) The module exports an array
|
||||
of test functions in the form expected by generate_tests(). */
|
||||
|
||||
var rtests = require("require/require_spec.js").tests;
|
||||
|
||||
for (var i = 0; i < rtests.length; i++) {
|
||||
test.apply(null, rtests[i]);
|
||||
}
|
2
third_party/phantomjs/test/basics/require/a.js
vendored
Normal file
2
third_party/phantomjs/test/basics/require/a.js
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
var b = require('./b');
|
||||
exports.b = b;
|
2
third_party/phantomjs/test/basics/require/b.js
vendored
Normal file
2
third_party/phantomjs/test/basics/require/b.js
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
var a = require('./a');
|
||||
exports.a = a;
|
1
third_party/phantomjs/test/basics/require/dir/dummy.js
vendored
Normal file
1
third_party/phantomjs/test/basics/require/dir/dummy.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
module.exports = 'dir/dummy';
|
1
third_party/phantomjs/test/basics/require/dir/subdir/dummy.js
vendored
Normal file
1
third_party/phantomjs/test/basics/require/dir/subdir/dummy.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
module.exports = 'subdir/dummy';
|
1
third_party/phantomjs/test/basics/require/dir/subdir/loader.js
vendored
Normal file
1
third_party/phantomjs/test/basics/require/dir/subdir/loader.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
exports.dummyFile2 = require('dummy_file2');
|
1
third_party/phantomjs/test/basics/require/dir/subdir2/loader.js
vendored
Normal file
1
third_party/phantomjs/test/basics/require/dir/subdir2/loader.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
module.exports = 'require/subdir2/loader'
|
1
third_party/phantomjs/test/basics/require/dummy.js
vendored
Normal file
1
third_party/phantomjs/test/basics/require/dummy.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
module.exports = 'require/dummy';
|
0
third_party/phantomjs/test/basics/require/empty.js
vendored
Normal file
0
third_party/phantomjs/test/basics/require/empty.js
vendored
Normal file
3
third_party/phantomjs/test/basics/require/json_dummy.json
vendored
Normal file
3
third_party/phantomjs/test/basics/require/json_dummy.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"message": "hello"
|
||||
}
|
1
third_party/phantomjs/test/basics/require/node_modules/dummy_file.js
generated
vendored
Normal file
1
third_party/phantomjs/test/basics/require/node_modules/dummy_file.js
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
module.exports = 'require/node_modules/dummy_file';
|
1
third_party/phantomjs/test/basics/require/node_modules/dummy_module/libdir/dummy_module.js
generated
vendored
Normal file
1
third_party/phantomjs/test/basics/require/node_modules/dummy_module/libdir/dummy_module.js
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
module.exports = 'require/node_modules/dummy_module';
|
4
third_party/phantomjs/test/basics/require/node_modules/dummy_module/package.json
generated
vendored
Normal file
4
third_party/phantomjs/test/basics/require/node_modules/dummy_module/package.json
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "dummy",
|
||||
"main": "./libdir/dummy_module.js"
|
||||
}
|
1
third_party/phantomjs/test/basics/require/node_modules/dummy_module2/index.js
generated
vendored
Normal file
1
third_party/phantomjs/test/basics/require/node_modules/dummy_module2/index.js
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
module.exports = 'require/node_modules/dummy_module2';
|
3
third_party/phantomjs/test/basics/require/not_found.js
vendored
Normal file
3
third_party/phantomjs/test/basics/require/not_found.js
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
exports.requireNonExistent = function() {
|
||||
require('./non_existent');
|
||||
};
|
131
third_party/phantomjs/test/basics/require/require_spec.js
vendored
Normal file
131
third_party/phantomjs/test/basics/require/require_spec.js
vendored
Normal file
@ -0,0 +1,131 @@
|
||||
var fs = require('fs');
|
||||
var tests = [];
|
||||
exports.tests = tests;
|
||||
|
||||
tests.push([function () {
|
||||
assert_no_property(window, 'CoffeeScript');
|
||||
assert_own_property(window, 'require');
|
||||
|
||||
assert_own_property(require('webpage'), 'create');
|
||||
assert_own_property(require('webserver'), 'create');
|
||||
assert_own_property(require('cookiejar'), 'create');
|
||||
|
||||
assert_own_property(require('fs'), 'separator');
|
||||
assert_equals(require('system').platform, 'phantomjs');
|
||||
|
||||
}, "native modules"]);
|
||||
|
||||
tests.push([function () {
|
||||
assert_equals(require('./json_dummy').message, 'hello');
|
||||
assert_equals(require('./dummy.js'), 'require/dummy');
|
||||
}, "JS and JSON modules"]);
|
||||
|
||||
tests.push([function () {
|
||||
require('./empty').hello = 'hola';
|
||||
assert_equals(require('./empty').hello, 'hola');
|
||||
|
||||
// assert_own_property rejects Functions
|
||||
assert_equals(require.hasOwnProperty('cache'), true);
|
||||
|
||||
var exposed = require('dummy_exposed');
|
||||
assert_equals(require.cache[exposed.filename], exposed);
|
||||
|
||||
}, "module caching"]);
|
||||
|
||||
tests.push([function () {
|
||||
var a = require('./a');
|
||||
var b = require('./b');
|
||||
assert_equals(a.b, b);
|
||||
assert_equals(b.a, a);
|
||||
}, "circular dependencies"]);
|
||||
|
||||
tests.push([function () {
|
||||
assert_throws("Cannot find module 'dummy_missing'",
|
||||
function () { require('dummy_missing'); });
|
||||
|
||||
try {
|
||||
require('./not_found').requireNonExistent();
|
||||
} catch (e) {
|
||||
assert_regexp_match(e.stack, /at require /);
|
||||
}
|
||||
}, "error handling 1"]);
|
||||
|
||||
tests.push([function error_handling_2 () {
|
||||
try {
|
||||
require('./thrower').fn();
|
||||
} catch (e) {
|
||||
assert_regexp_match(e.toString() + "\n" + e.stack,
|
||||
/^Error: fn\nError: fn\n at Object.thrower/);
|
||||
}
|
||||
}, "error handling 2"]);
|
||||
|
||||
tests.push([function () {
|
||||
assert_equals(require('./stubber').stubbed, 'stubbed module');
|
||||
assert_equals(require('./stubber').child.stubbed, 'stubbed module');
|
||||
assert_throws("Cannot find module 'stubbed'",
|
||||
function () { require('stubbed'); });
|
||||
|
||||
var count = 0;
|
||||
require.stub('lazily_stubbed', function() {
|
||||
++count;
|
||||
return 'lazily stubbed module';
|
||||
});
|
||||
|
||||
assert_equals(require('lazily_stubbed'), 'lazily stubbed module');
|
||||
require('lazily_stubbed');
|
||||
assert_equals(count, 1);
|
||||
|
||||
}, "stub modules"]);
|
||||
|
||||
tests.push([function () {
|
||||
assert_equals(require('./dummy'), 'require/dummy');
|
||||
assert_equals(require('../fixtures/dummy'), 'spec/dummy');
|
||||
assert_equals(require('./dir/dummy'), 'dir/dummy');
|
||||
assert_equals(require('./dir/subdir/dummy'), 'subdir/dummy');
|
||||
assert_equals(require('./dir/../dummy'), 'require/dummy');
|
||||
assert_equals(require('./dir/./dummy'), 'dir/dummy');
|
||||
assert_equals(require(
|
||||
fs.absolute(module.dirname + '/dummy.js')), 'require/dummy');
|
||||
|
||||
}, "relative and absolute paths"]);
|
||||
|
||||
tests.push([function () {
|
||||
assert_equals(require('dummy_file'), 'require/node_modules/dummy_file');
|
||||
assert_equals(require('dummy_file2'), 'spec/node_modules/dummy_file2');
|
||||
assert_equals(require('./dir/subdir/loader').dummyFile2,
|
||||
'spec/node_modules/dummy_file2');
|
||||
assert_equals(require('dummy_module'),
|
||||
'require/node_modules/dummy_module');
|
||||
assert_equals(require('dummy_module2'),
|
||||
'require/node_modules/dummy_module2');
|
||||
}, "loading from node_modules"]);
|
||||
|
||||
function require_paths_tests_1 () {
|
||||
assert_equals(require('loader').dummyFile2,
|
||||
'spec/node_modules/dummy_file2');
|
||||
assert_equals(require('../subdir2/loader'),
|
||||
'require/subdir2/loader');
|
||||
assert_equals(require('../fixtures/dummy'), 'spec/dummy');
|
||||
}
|
||||
function require_paths_tests_2 () {
|
||||
assert_throws("Cannot find module 'loader'",
|
||||
function () { require('loader'); });
|
||||
}
|
||||
|
||||
tests.push([function () {
|
||||
require.paths.push('dir/subdir');
|
||||
this.add_cleanup(function () { require.paths.pop(); });
|
||||
require_paths_tests_1();
|
||||
}, "relative paths in require.paths"]);
|
||||
|
||||
tests.push([
|
||||
require_paths_tests_2, "relative paths in require paths (after removal)"]);
|
||||
|
||||
tests.push([function () {
|
||||
require.paths.push(fs.absolute(module.dirname + '/dir/subdir'));
|
||||
this.add_cleanup(function () { require.paths.pop(); });
|
||||
require_paths_tests_1();
|
||||
}, "absolute paths in require.paths"]);
|
||||
|
||||
tests.push([
|
||||
require_paths_tests_2, "relative paths in require paths (after removal)"]);
|
5
third_party/phantomjs/test/basics/require/stubber.js
vendored
Normal file
5
third_party/phantomjs/test/basics/require/stubber.js
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
require.stub('stubbed', 'stubbed module');
|
||||
exports.stubbed = require('stubbed');
|
||||
try {
|
||||
exports.child = require('./stubber_child');
|
||||
} catch (e) {}
|
1
third_party/phantomjs/test/basics/require/stubber_child.js
vendored
Normal file
1
third_party/phantomjs/test/basics/require/stubber_child.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
exports.stubbed = require('stubbed');
|
3
third_party/phantomjs/test/basics/require/thrower.js
vendored
Normal file
3
third_party/phantomjs/test/basics/require/thrower.js
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
exports.fn = function thrower() {
|
||||
throw new Error('fn');
|
||||
};
|
14
third_party/phantomjs/test/basics/stacktrace.js
vendored
Normal file
14
third_party/phantomjs/test/basics/stacktrace.js
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
//! unsupported
|
||||
|
||||
// A SyntaxError leaks to phantom.onError, despite the try-catch.
|
||||
setup({ allow_uncaught_exception: true });
|
||||
|
||||
test(function () {
|
||||
var helperFile = "../fixtures/parse-error-helper.js";
|
||||
try {
|
||||
phantom.injectJs(helperFile);
|
||||
} catch (e) {
|
||||
assert_equals(e.stack[0].file, helperFile);
|
||||
assert_equals(e.stack[0].line, 2);
|
||||
}
|
||||
}, "stack trace from syntax error in injected file");
|
33
third_party/phantomjs/test/basics/test-server.js
vendored
Normal file
33
third_party/phantomjs/test/basics/test-server.js
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
//! unsupported
|
||||
/* Test the test server itself. */
|
||||
|
||||
var webpage = require('webpage');
|
||||
|
||||
function test_one_page(url) {
|
||||
var page = webpage.create();
|
||||
page.onResourceReceived = this.step_func(function (response) {
|
||||
assert_equals(response.status, 200);
|
||||
});
|
||||
page.onResourceError = this.unreached_func();
|
||||
page.onResourceTimeout = this.unreached_func();
|
||||
page.onLoadFinished = this.step_func_done(function (status) {
|
||||
assert_equals(status, 'success');
|
||||
});
|
||||
page.open(url);
|
||||
}
|
||||
|
||||
function do_test(path) {
|
||||
var http_url = TEST_HTTP_BASE + path;
|
||||
var https_url = TEST_HTTPS_BASE + path;
|
||||
var http_test = async_test(http_url);
|
||||
var https_test = async_test(https_url);
|
||||
http_test.step(test_one_page, null, http_url);
|
||||
https_test.step(test_one_page, null, https_url);
|
||||
}
|
||||
|
||||
[
|
||||
'hello.html',
|
||||
'status?200',
|
||||
'echo'
|
||||
]
|
||||
.forEach(do_test);
|
7
third_party/phantomjs/test/basics/timeout.js
vendored
Normal file
7
third_party/phantomjs/test/basics/timeout.js
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
//! unsupported
|
||||
//! no-harness
|
||||
//! expect-exit: -15
|
||||
//! expect-stderr: TIMEOUT: Process terminated after 0.25 seconds.
|
||||
//! timeout: 0.25
|
||||
|
||||
// no code, so phantom will just sleep forever
|
16
third_party/phantomjs/test/basics/url-utils.js
vendored
Normal file
16
third_party/phantomjs/test/basics/url-utils.js
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
// These are cursory tests; we assume the underlying Qt
|
||||
// features are properly tested elsewhere.
|
||||
|
||||
test(function () {
|
||||
assert_equals(
|
||||
phantom.resolveRelativeUrl(
|
||||
"../scripts/foo.js",
|
||||
"http://example.com/topic/page.html"),
|
||||
"http://example.com/scripts/foo.js");
|
||||
|
||||
assert_equals(
|
||||
phantom.fullyDecodeUrl(
|
||||
"https://ja.wikipedia.org/wiki/%E8%87%A8%E6%B5%B7%E5%AD%A6%E6%A0%A1"),
|
||||
"https://ja.wikipedia.org/wiki/臨海学校");
|
||||
|
||||
}, "resolveRelativeUrl and fullyDecodeUrl");
|
7
third_party/phantomjs/test/basics/version.js
vendored
Normal file
7
third_party/phantomjs/test/basics/version.js
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
// This is separate from basics/phantom-object.js because it has to be
|
||||
// updated with every release.
|
||||
test(function () {
|
||||
assert_equals(phantom.version.major, 0);
|
||||
assert_equals(phantom.version.minor, 0);
|
||||
assert_equals(phantom.version.patch, 1);
|
||||
}, "PhantomJS version number is accurate");
|
18
third_party/phantomjs/test/certs/https-snakeoil.crt
vendored
Normal file
18
third_party/phantomjs/test/certs/https-snakeoil.crt
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIC+zCCAeOgAwIBAgIJAJ7HwZBrgnLwMA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV
|
||||
BAMMCWxvY2FsaG9zdDAeFw0xNTA4MTEyMjU4MTZaFw0yNTA4MTAyMjU4MTZaMBQx
|
||||
EjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
|
||||
ggEBANFha8c5JKjYrHc7BTqmuFSAxYsSKbUUa0k+0PFpjhj7Io/NOeHhxfdLJX/B
|
||||
LVQXEDhvOlSTDBgC3RQkxCZJmMzKZjMDlj0cxY0esZtcqt0sRpwRvT+EBE9SlFu4
|
||||
TWM2BQ6k5E4OIX/9aUk9HQ99pSjqmhu/7n76n/5DfqxGwkfVZengI1KwfezaB5+Q
|
||||
wAvoS7tadROqTyynV1kd+OF9BJZwO1eR9lAiGc139J/BHegVcqdrI043oR+1vyTw
|
||||
BFpodw4HYdJHNgo7DKAtmXoDAws5myqx2GcnVng1wyzu6LdM65nMV4/p5Y/Y6Ziy
|
||||
RqeV1gVbtpxTcrLmWFnI8BRwFBUCAwEAAaNQME4wHQYDVR0OBBYEFPP1YOkZpJmE
|
||||
x/W48Kwv2N1QC1oDMB8GA1UdIwQYMBaAFPP1YOkZpJmEx/W48Kwv2N1QC1oDMAwG
|
||||
A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAA1NxsrmKxGecAS6TEHNBqFZ
|
||||
9NhV23kXY5sdv8zl7HUmzR+vIBumd9lkSZdOwAy5/hmj6ACReSJ9f2xpyi0fOtx5
|
||||
WZ8Vcrg9Qjuy17qmGi66yL860yr0h6hltzCWCi7e26Eybawm3/9PmbNV3Hcwgxug
|
||||
D+gv4LZLlyj4JI4lg/8RVXaNXqGBZ39YhRH0LFVjbYiFWUGqzfAT9YBoC67Ov8Yv
|
||||
Bl1PoV3sJcagx67X6y8ru+gecc/OOXKJHxSidhjRqhKB6WOWIPfugsMOl1g2FMPv
|
||||
tuPFsIQNSaln7V+ECeDOipJOSp9KAyM5fNcVjldd/e4V+qwcyoOijFywNfSK10M=
|
||||
-----END CERTIFICATE-----
|
28
third_party/phantomjs/test/certs/https-snakeoil.key
vendored
Normal file
28
third_party/phantomjs/test/certs/https-snakeoil.key
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDRYWvHOSSo2Kx3
|
||||
OwU6prhUgMWLEim1FGtJPtDxaY4Y+yKPzTnh4cX3SyV/wS1UFxA4bzpUkwwYAt0U
|
||||
JMQmSZjMymYzA5Y9HMWNHrGbXKrdLEacEb0/hARPUpRbuE1jNgUOpORODiF//WlJ
|
||||
PR0PfaUo6pobv+5++p/+Q36sRsJH1WXp4CNSsH3s2gefkMAL6Eu7WnUTqk8sp1dZ
|
||||
HfjhfQSWcDtXkfZQIhnNd/SfwR3oFXKnayNON6Eftb8k8ARaaHcOB2HSRzYKOwyg
|
||||
LZl6AwMLOZsqsdhnJ1Z4NcMs7ui3TOuZzFeP6eWP2OmYskanldYFW7acU3Ky5lhZ
|
||||
yPAUcBQVAgMBAAECggEAOwI/w8fhAwz9niSuFpeB/57DDayywGveyKfBbygWegfc
|
||||
97YZCAX/KvCswtKImdheI+mFAOzoTaQQ9mpeNYQsYhrwrpPmNZb0Pg9WcritFuQx
|
||||
ii6drVbheBGH6kmI1dsVlcj25uCopE+g6pkkpYb9kwh7IjL3XiX4DUqsWpUej+ub
|
||||
2iL/luW7nYHHIRqzOFgP3v/f29sFHNvYcgihphBMHtgb4VpeYQ/f7AC7k1bFYfA/
|
||||
TmvfUcXdiPwJf0XICZOaLrT/6pigk0bRiLNn8npISu7Wlf4jF60bNAe4+krBVU4O
|
||||
p8UjW99LiGKLDh8GpoudnzlnnngZ3SA5+bO7kwTjCQKBgQDvJwUShOWm2+5wJsr4
|
||||
hWieTVDaZEDb+1WTe7DwtqRWNBWXchh8is9buWeXIe6+1WldBYYiQjgdggQCw8xG
|
||||
IFFg1j1E6kPqk/kzrHYSsJ+/u8uaxypvvrVBhUqt5FduOxFojW2REX9W5n8HTdT4
|
||||
32BGR4mGpuXzR+BsVK00QRgM+wKBgQDgIXtu6rbfx+mdXTFi6apWJoyu5bRWcrL2
|
||||
mGoR+IjCk6NefcvBE33q54H/dk3+0Sxp6+uFo7lyKv4EL3lozQO2oga6sp2LOIEK
|
||||
DUo+KQVOmntCNrjuN/PbjSu2s1j5QDnLNR9VvXGiYBWdpZ7k3YzoKJ1I4ZyB3kGs
|
||||
H/lCXv52LwKBgER1HvaWJEcHXdGsyR0q0y+9Yg+h8w8FexGkrpm5LoGely+q8Wd1
|
||||
NLZE9GpGxFjMLkT6d9MGsZmAxjUkZy0Lwz+9E/zOMnLLuOIZ1BK1jIUN9NJxgKxM
|
||||
IwaGaUItwvlC31DWay7Dm3f8sxAcL4KuLpjvkWaCEAD76joYYxw6JfBRAoGADMe7
|
||||
+xolLWN/3bpHq6U5UkpGcV6lxtwpekg8nCO44Kd8hFHWAX90CaYD0qZTUjlpN+z8
|
||||
9BTe6TSsYV63pJM0KADbM2Al/Z9ONF2Hoz3BkLbcWm02ZFcKb7WADZ3yb9wKr5yq
|
||||
2b/AsAqckO21vsUnWMGgHlzHCNy8j+0O0IsMJX8CgYAORhyGaU7x5t4kEvqBNIan
|
||||
mOzuB0b5nYV9mHxmyFhOsa8LeM25SA4n1rFpTb8h6vmZF1y9+4Zy4uNfCR2wXg0v
|
||||
I51qtZ8npbIksYvNqvHaTPg8ZBcFK5mHr3TDxXJCcc0ylzM98ze08D+qKr0joX4w
|
||||
KlqN6KjGmYfb+RHehLk9sw==
|
||||
-----END PRIVATE KEY-----
|
1
third_party/phantomjs/test/fixtures/dummy.js
vendored
Normal file
1
third_party/phantomjs/test/fixtures/dummy.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
module.exports = 'spec/dummy';
|
9
third_party/phantomjs/test/fixtures/error-helper.js
vendored
Normal file
9
third_party/phantomjs/test/fixtures/error-helper.js
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
ErrorHelper = {
|
||||
foo: function() {
|
||||
this.bar()
|
||||
},
|
||||
|
||||
bar: function bar() {
|
||||
referenceError
|
||||
}
|
||||
};
|
2
third_party/phantomjs/test/fixtures/parse-error-helper.js
vendored
Normal file
2
third_party/phantomjs/test/fixtures/parse-error-helper.js
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
var ok;
|
||||
bar("run away"
|
36
third_party/phantomjs/test/manual/standards/ecma-test262.js
vendored
Normal file
36
third_party/phantomjs/test/manual/standards/ecma-test262.js
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
// Launch the official test suite for ECMA-262
|
||||
|
||||
var webpage = require('webpage');
|
||||
|
||||
page = webpage.create();
|
||||
page.onError = function() {};
|
||||
|
||||
page.open('http://test262.ecmascript.org/', function() {
|
||||
page.evaluate(function() { $('a#run').click(); });
|
||||
page.evaluate(function() { $('img#btnRunAll').click(); });
|
||||
|
||||
function monitor() {
|
||||
|
||||
var data = page.evaluate(function() {
|
||||
return {
|
||||
ran: $('#totalCounter').text(),
|
||||
total: $('#testsToRun').text(),
|
||||
pass: $('#Pass').text(),
|
||||
fail: $('#Fail').text(),
|
||||
progress: $('div#progressbar').text()
|
||||
};
|
||||
});
|
||||
|
||||
console.log('Tests: ', data.ran, 'of', data.total,
|
||||
' Pass:', data.pass, ' Fail:', data.fail);
|
||||
|
||||
if (data.progress.indexOf('complete') > 0) {
|
||||
page.render('report.png');
|
||||
phantom.exit();
|
||||
} else {
|
||||
setTimeout(monitor, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout(monitor, 0);
|
||||
});
|
93
third_party/phantomjs/test/module/cookiejar/cookiejar.js
vendored
Normal file
93
third_party/phantomjs/test/module/cookiejar/cookiejar.js
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
//! unsupported
|
||||
var cookie0 = {
|
||||
'name': 'Valid-Cookie-Name',
|
||||
'value': 'Valid-Cookie-Value',
|
||||
'domain': 'localhost',
|
||||
'path': '/foo',
|
||||
'httponly': true,
|
||||
'secure': false
|
||||
};
|
||||
var cookie1 = {
|
||||
'name': 'Valid-Cookie-Name-1',
|
||||
'value': 'Valid-Cookie-Value',
|
||||
'domain': 'localhost',
|
||||
'path': '/foo',
|
||||
'httponly': true,
|
||||
'secure': false
|
||||
};
|
||||
var cookie2 = {
|
||||
'name': 'Valid-Cookie-Name-2',
|
||||
'value': 'Valid-Cookie-Value',
|
||||
'domain': 'localhost',
|
||||
'path': '/foo',
|
||||
'httponly': true,
|
||||
'secure': false
|
||||
};
|
||||
var cookies = [{
|
||||
'name': 'Valid-Cookie-Name',
|
||||
'value': 'Valid-Cookie-Value',
|
||||
'domain': 'localhost',
|
||||
'path': '/foo',
|
||||
'httponly': true,
|
||||
'secure': false
|
||||
},{
|
||||
'name': 'Valid-Cookie-Name-Sec',
|
||||
'value': 'Valid-Cookie-Value-Sec',
|
||||
'domain': 'localhost',
|
||||
'path': '/foo',
|
||||
'httponly': true,
|
||||
'secure': false,
|
||||
'expires': new Date().getTime() + 3600 //< expires in 1h
|
||||
}];
|
||||
|
||||
var cookiejar, jar1, jar2;
|
||||
setup(function () {
|
||||
cookiejar = require('cookiejar');
|
||||
jar1 = cookiejar.create();
|
||||
jar2 = cookiejar.create();
|
||||
});
|
||||
|
||||
test(function () {
|
||||
assert_type_of(jar1, 'object');
|
||||
assert_not_equals(jar1, null);
|
||||
assert_type_of(jar1.cookies, 'object');
|
||||
|
||||
assert_type_of(jar1.addCookie, 'function');
|
||||
assert_type_of(jar1.deleteCookie, 'function');
|
||||
assert_type_of(jar1.clearCookies, 'function');
|
||||
}, "cookie jar properties");
|
||||
|
||||
test(function () {
|
||||
assert_equals(jar1.cookies.length, 0);
|
||||
|
||||
jar1.addCookie(cookie0);
|
||||
assert_equals(jar1.cookies.length, 1);
|
||||
|
||||
jar1.deleteCookie('Valid-Cookie-Name');
|
||||
assert_equals(jar1.cookies.length, 0);
|
||||
}, "adding and removing cookies");
|
||||
|
||||
test(function () {
|
||||
assert_equals(jar1.cookies.length, 0);
|
||||
|
||||
jar1.cookies = cookies;
|
||||
assert_equals(jar1.cookies.length, 2);
|
||||
|
||||
jar1.clearCookies();
|
||||
assert_equals(jar1.cookies.length, 0);
|
||||
}, "setting and clearing a cookie jar");
|
||||
|
||||
test(function () {
|
||||
jar1.addCookie(cookie1);
|
||||
assert_equals(jar1.cookies.length, 1);
|
||||
assert_equals(jar2.cookies.length, 0);
|
||||
|
||||
jar2.addCookie(cookie2);
|
||||
jar1.deleteCookie('Valid-Cookie-Name-1');
|
||||
assert_equals(jar1.cookies.length, 0);
|
||||
assert_equals(jar2.cookies.length, 1);
|
||||
|
||||
jar1.close();
|
||||
jar2.close();
|
||||
|
||||
}, "cookie jar isolation");
|
52
third_party/phantomjs/test/module/cookiejar/to-map.js
vendored
Normal file
52
third_party/phantomjs/test/module/cookiejar/to-map.js
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
//! unsupported
|
||||
var cookies = {
|
||||
'beforeExpires': {
|
||||
'name': 'beforeExpires',
|
||||
'value': 'expireValue',
|
||||
'domain': '.abc.com',
|
||||
'path': '/',
|
||||
'httponly': false,
|
||||
'secure': false,
|
||||
'expires': 'Tue, 10 Jun 2025 12:28:29 GMT'
|
||||
},
|
||||
'noExpiresDate': {
|
||||
'name': 'noExpiresDate',
|
||||
'value': 'value',
|
||||
'domain': '.abc.com',
|
||||
'path': '/',
|
||||
'httponly': false,
|
||||
'secure': false,
|
||||
'expires': null
|
||||
},
|
||||
'afterExpires': {
|
||||
'name': 'afterExpires',
|
||||
'value': 'value',
|
||||
'domain': '.abc.com',
|
||||
'path': '/',
|
||||
'httponly': false,
|
||||
'secure': false,
|
||||
'expires': 'Mon, 10 Jun 2024 12:28:29 GMT'
|
||||
}
|
||||
};
|
||||
|
||||
test(function () {
|
||||
var i, c, d, prop;
|
||||
for (i in cookies) {
|
||||
if (!cookies.hasOwnProperty(i)) continue;
|
||||
phantom.addCookie(cookies[i]);
|
||||
}
|
||||
for (i in phantom.cookies) {
|
||||
d = phantom.cookies[i];
|
||||
c = cookies[d.name];
|
||||
for (prop in c) {
|
||||
if (!c.hasOwnProperty(prop)) continue;
|
||||
if (c[prop] === null) {
|
||||
assert_no_property(d, prop);
|
||||
} else {
|
||||
assert_own_property(d, prop);
|
||||
assert_equals(c[prop], d[prop]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}, "optional cookie properties should not leak");
|
220
third_party/phantomjs/test/module/fs/basics.js
vendored
Normal file
220
third_party/phantomjs/test/module/fs/basics.js
vendored
Normal file
@ -0,0 +1,220 @@
|
||||
// Basic Files API (read, write, remove, ...)
|
||||
|
||||
var FILENAME = "temp-01.test",
|
||||
FILENAME_COPY = FILENAME + ".copy",
|
||||
FILENAME_MOVED = FILENAME + ".moved",
|
||||
FILENAME_EMPTY = FILENAME + ".empty",
|
||||
FILENAME_ENC = FILENAME + ".enc",
|
||||
FILENAME_BIN = FILENAME + ".bin",
|
||||
ABSENT = "absent-01.test";
|
||||
|
||||
var fs;
|
||||
|
||||
setup(function () {
|
||||
fs = require('fs');
|
||||
var f = fs.open(FILENAME, "w");
|
||||
|
||||
f.write("hello");
|
||||
f.writeLine("");
|
||||
f.writeLine("world");
|
||||
f.close();
|
||||
});
|
||||
|
||||
test(function () {
|
||||
assert_is_true(fs.exists(FILENAME));
|
||||
// we might've gotten DOS line endings
|
||||
assert_greater_than_equal(fs.size(FILENAME), "hello\nworld\n".length);
|
||||
|
||||
}, "create a file with contents");
|
||||
|
||||
test(function () {
|
||||
assert_is_false(fs.exists(FILENAME_EMPTY));
|
||||
fs.touch(FILENAME_EMPTY);
|
||||
assert_is_true(fs.exists(FILENAME_EMPTY));
|
||||
assert_equals(fs.size(FILENAME_EMPTY), 0);
|
||||
|
||||
}, "create (touch) an empty file");
|
||||
|
||||
test(function () {
|
||||
var content = "";
|
||||
var f = fs.open(FILENAME, "r");
|
||||
this.add_cleanup(function () { f.close(); });
|
||||
|
||||
content = f.read();
|
||||
assert_equals(content, "hello\nworld\n");
|
||||
|
||||
}, "read content from a file");
|
||||
|
||||
test(function () {
|
||||
var content = "";
|
||||
var f = fs.open(FILENAME, "r");
|
||||
this.add_cleanup(function () { f.close(); });
|
||||
|
||||
f.seek(3);
|
||||
content = f.read(5);
|
||||
assert_equals(content, "lo\nwo");
|
||||
|
||||
}, "read specific number of bytes from a specific position in a file");
|
||||
|
||||
test(function () {
|
||||
var content = "";
|
||||
var f = fs.open(FILENAME, "rw+");
|
||||
this.add_cleanup(function () { f.close(); });
|
||||
|
||||
f.writeLine("asdf");
|
||||
content = f.read();
|
||||
assert_equals(content, "hello\nworld\nasdf\n");
|
||||
|
||||
}, "append content to a file");
|
||||
|
||||
test(function () {
|
||||
var f = fs.open(FILENAME, "r");
|
||||
this.add_cleanup(function () { f.close(); });
|
||||
assert_equals(f.getEncoding(), "UTF-8");
|
||||
|
||||
}, "get the file encoding (default: UTF-8)");
|
||||
|
||||
test(function () {
|
||||
var f = fs.open(FILENAME, { charset: "UTF-8", mode: "r" });
|
||||
this.add_cleanup(function () { f.close(); });
|
||||
assert_equals(f.getEncoding(), "UTF-8");
|
||||
|
||||
var g = fs.open(FILENAME, { charset: "SJIS", mode: "r" });
|
||||
this.add_cleanup(function () { g.close(); });
|
||||
assert_equals(g.getEncoding(), "Shift_JIS");
|
||||
|
||||
}, "set the encoding on open", {/* unsupported */expected_fail: true});
|
||||
|
||||
test(function () {
|
||||
var f = fs.open(FILENAME, { charset: "UTF-8", mode: "r" });
|
||||
this.add_cleanup(function () { f.close(); });
|
||||
assert_equals(f.getEncoding(), "UTF-8");
|
||||
f.setEncoding("utf8");
|
||||
assert_equals(f.getEncoding(), "UTF-8");
|
||||
|
||||
var g = fs.open(FILENAME, { charset: "SJIS", mode: "r" });
|
||||
this.add_cleanup(function () { g.close(); });
|
||||
assert_equals(g.getEncoding(), "Shift_JIS");
|
||||
g.setEncoding("eucjp");
|
||||
assert_equals(g.getEncoding(), "EUC-JP");
|
||||
|
||||
}, "change the encoding using setEncoding", {/* unsupported */expected_fail: true});
|
||||
|
||||
test(function () {
|
||||
assert_is_false(fs.exists(FILENAME_COPY));
|
||||
fs.copy(FILENAME, FILENAME_COPY);
|
||||
assert_is_true(fs.exists(FILENAME_COPY));
|
||||
assert_equals(fs.read(FILENAME), fs.read(FILENAME_COPY));
|
||||
|
||||
}, "copy a file");
|
||||
|
||||
test(function () {
|
||||
assert_is_true(fs.exists(FILENAME));
|
||||
var contentBeforeMove = fs.read(FILENAME);
|
||||
fs.move(FILENAME, FILENAME_MOVED);
|
||||
assert_is_false(fs.exists(FILENAME));
|
||||
assert_is_true(fs.exists(FILENAME_MOVED));
|
||||
assert_equals(fs.read(FILENAME_MOVED), contentBeforeMove);
|
||||
|
||||
}, "move a file");
|
||||
|
||||
test(function () {
|
||||
assert_is_true(fs.exists(FILENAME_MOVED));
|
||||
assert_is_true(fs.exists(FILENAME_COPY));
|
||||
assert_is_true(fs.exists(FILENAME_EMPTY));
|
||||
|
||||
fs.remove(FILENAME_MOVED);
|
||||
fs.remove(FILENAME_COPY);
|
||||
fs.remove(FILENAME_EMPTY);
|
||||
|
||||
assert_is_false(fs.exists(FILENAME_MOVED));
|
||||
assert_is_false(fs.exists(FILENAME_COPY));
|
||||
assert_is_false(fs.exists(FILENAME_EMPTY));
|
||||
|
||||
}, "remove a file");
|
||||
|
||||
test(function () {
|
||||
assert_throws("Unable to open file '"+ ABSENT +"'",
|
||||
function () { fs.open(ABSENT, "r"); });
|
||||
|
||||
assert_throws("Unable to copy file '" + ABSENT +
|
||||
"' at '" + FILENAME_COPY + "'",
|
||||
function () { fs.copy(ABSENT, FILENAME_COPY); });
|
||||
|
||||
}, "operations on nonexistent files throw an exception", {/* unsupported */expected_fail: true});
|
||||
|
||||
test(function () {
|
||||
var data = "ÄABCÖ";
|
||||
var data_b = String.fromCharCode(
|
||||
0xC3, 0x84, 0x41, 0x42, 0x43, 0xC3, 0x96);
|
||||
|
||||
var f = fs.open(FILENAME_ENC, "w");
|
||||
this.add_cleanup(function () {
|
||||
f.close();
|
||||
fs.remove(FILENAME_ENC);
|
||||
});
|
||||
|
||||
f.write(data);
|
||||
f.close();
|
||||
|
||||
f = fs.open(FILENAME_ENC, "r");
|
||||
assert_equals(f.read(), data);
|
||||
|
||||
var g = fs.open(FILENAME_ENC, "rb");
|
||||
this.add_cleanup(function () { g.close(); });
|
||||
assert_equals(g.read(), data_b);
|
||||
|
||||
}, "read/write UTF-8 text by default");
|
||||
|
||||
test(function () {
|
||||
var data = "ピタゴラスイッチ";
|
||||
var data_b = String.fromCharCode(
|
||||
0x83, 0x73, 0x83, 0x5e, 0x83, 0x53, 0x83, 0x89,
|
||||
0x83, 0x58, 0x83, 0x43, 0x83, 0x62, 0x83, 0x60);
|
||||
|
||||
var f = fs.open(FILENAME_ENC, { mode: "w", charset: "Shift_JIS" });
|
||||
this.add_cleanup(function () {
|
||||
f.close();
|
||||
fs.remove(FILENAME_ENC);
|
||||
});
|
||||
|
||||
f.write(data);
|
||||
f.close();
|
||||
|
||||
f = fs.open(FILENAME_ENC, { mode: "r", charset: "Shift_JIS" });
|
||||
assert_equals(f.read(), data);
|
||||
|
||||
var g = fs.open(FILENAME_ENC, "rb");
|
||||
this.add_cleanup(function () { g.close(); });
|
||||
assert_equals(g.read(), data_b);
|
||||
|
||||
}, "read/write Shift-JIS text with options", {/* unsupported */expected_fail: true});
|
||||
|
||||
test(function () {
|
||||
var data = String.fromCharCode(0, 1, 2, 3, 4, 5);
|
||||
|
||||
var f = fs.open(FILENAME_BIN, "wb");
|
||||
this.add_cleanup(function () {
|
||||
f.close();
|
||||
fs.remove(FILENAME_BIN);
|
||||
});
|
||||
|
||||
f.write(data);
|
||||
f.close();
|
||||
|
||||
f = fs.open(FILENAME_BIN, "rb");
|
||||
assert_equals(f.read(), data);
|
||||
|
||||
}, "read/write binary data");
|
||||
|
||||
test(function () {
|
||||
var data = String.fromCharCode(0, 1, 2, 3, 4, 5);
|
||||
|
||||
fs.write(FILENAME_BIN, data, "b");
|
||||
this.add_cleanup(function () {
|
||||
fs.remove(FILENAME_BIN);
|
||||
});
|
||||
|
||||
assert_equals(fs.read(FILENAME_BIN, "b"), data);
|
||||
|
||||
}, "read/write binary data (shortcuts)");
|
91
third_party/phantomjs/test/module/fs/fileattrs.js
vendored
Normal file
91
third_party/phantomjs/test/module/fs/fileattrs.js
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
|
||||
var fs = require('fs');
|
||||
|
||||
var ABSENT_DIR = "absentdir02",
|
||||
ABSENT_FILE = "absentfile02",
|
||||
TEST_DIR = "testdir02",
|
||||
TEST_FILE = "temp-02.test",
|
||||
TEST_FILE_PATH = fs.join(TEST_DIR, TEST_FILE),
|
||||
TEST_CONTENT = "test content",
|
||||
CONTENT_MULTIPLIER = 1024;
|
||||
|
||||
test(function () {
|
||||
assert_throws("Unable to read file '"+ ABSENT_FILE +"' size",
|
||||
function () { fs.size(ABSENT_FILE); });
|
||||
|
||||
assert_equals(fs.lastModified(ABSENT_FILE), null);
|
||||
|
||||
}, "size/date queries on nonexistent files", {/* unsupported */expected_fail: true});
|
||||
|
||||
test(function () {
|
||||
// Round down to the nearest multiple of two seconds, because
|
||||
// file timestamps might only have that much precision.
|
||||
var before_creation = Math.floor(Date.now() / 2000) * 2000;
|
||||
|
||||
var f = fs.open(TEST_FILE, "w");
|
||||
this.add_cleanup(function () {
|
||||
if (f !== null) f.close();
|
||||
fs.remove(TEST_FILE);
|
||||
});
|
||||
|
||||
for (var i = 0; i < CONTENT_MULTIPLIER; i++) {
|
||||
f.write(TEST_CONTENT);
|
||||
}
|
||||
f.close(); f = null;
|
||||
|
||||
// Similarly, but round _up_.
|
||||
var after_creation = Math.ceil(Date.now() / 2000) * 2000;
|
||||
|
||||
assert_equals(fs.size(TEST_FILE),
|
||||
TEST_CONTENT.length * CONTENT_MULTIPLIER);
|
||||
|
||||
var flm = fs.lastModified(TEST_FILE).getTime();
|
||||
|
||||
assert_greater_than_equal(flm, before_creation);
|
||||
assert_less_than_equal(flm, after_creation);
|
||||
|
||||
}, "size/date queries on existing files");
|
||||
|
||||
test(function () {
|
||||
fs.makeDirectory(TEST_DIR);
|
||||
this.add_cleanup(function () { fs.removeTree(TEST_DIR); });
|
||||
fs.write(TEST_FILE_PATH, TEST_CONTENT, "w");
|
||||
|
||||
assert_is_true(fs.exists(TEST_FILE_PATH));
|
||||
assert_is_true(fs.exists(TEST_DIR));
|
||||
assert_is_false(fs.exists(ABSENT_FILE));
|
||||
assert_is_false(fs.exists(ABSENT_DIR));
|
||||
|
||||
assert_is_true(fs.isDirectory(TEST_DIR));
|
||||
assert_is_false(fs.isDirectory(ABSENT_DIR));
|
||||
|
||||
|
||||
assert_is_true(fs.isFile(TEST_FILE_PATH));
|
||||
assert_is_false(fs.isFile(ABSENT_FILE));
|
||||
|
||||
var absPath = fs.absolute(TEST_FILE_PATH);
|
||||
assert_is_false(fs.isAbsolute(TEST_FILE_PATH));
|
||||
assert_is_true(fs.isAbsolute(absPath));
|
||||
|
||||
assert_is_true(fs.isReadable(TEST_FILE_PATH));
|
||||
assert_is_true(fs.isWritable(TEST_FILE_PATH));
|
||||
assert_is_false(fs.isExecutable(TEST_FILE_PATH));
|
||||
|
||||
assert_is_false(fs.isReadable(ABSENT_FILE));
|
||||
assert_is_false(fs.isWritable(ABSENT_FILE));
|
||||
assert_is_false(fs.isExecutable(ABSENT_FILE));
|
||||
|
||||
assert_is_true(fs.isReadable(TEST_DIR));
|
||||
assert_is_true(fs.isWritable(TEST_DIR));
|
||||
assert_is_true(fs.isExecutable(TEST_DIR));
|
||||
|
||||
assert_is_false(fs.isReadable(ABSENT_DIR));
|
||||
assert_is_false(fs.isWritable(ABSENT_DIR));
|
||||
assert_is_false(fs.isExecutable(ABSENT_DIR));
|
||||
|
||||
assert_is_false(fs.isLink(TEST_DIR));
|
||||
assert_is_false(fs.isLink(TEST_FILE_PATH));
|
||||
assert_is_false(fs.isLink(ABSENT_DIR));
|
||||
assert_is_false(fs.isLink(ABSENT_FILE));
|
||||
|
||||
}, "file types and access modes");
|
72
third_party/phantomjs/test/module/fs/paths.js
vendored
Normal file
72
third_party/phantomjs/test/module/fs/paths.js
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
|
||||
var fs = require('fs');
|
||||
var system = require('system');
|
||||
|
||||
var TEST_DIR = "testdir",
|
||||
TEST_FILE = "testfile",
|
||||
START_CWD = fs.workingDirectory;
|
||||
|
||||
test(function () {
|
||||
assert_is_true(fs.makeDirectory(TEST_DIR));
|
||||
this.add_cleanup(function () { fs.removeTree(TEST_DIR); });
|
||||
|
||||
assert_is_true(fs.changeWorkingDirectory(TEST_DIR));
|
||||
this.add_cleanup(function () { fs.changeWorkingDirectory(START_CWD); });
|
||||
|
||||
fs.write(TEST_FILE, TEST_FILE, "w");
|
||||
var suffix = fs.join("", TEST_DIR, TEST_FILE),
|
||||
abs = fs.absolute(".." + suffix),
|
||||
lastIndex = abs.lastIndexOf(suffix);
|
||||
|
||||
assert_not_equals(lastIndex, -1);
|
||||
assert_equals(lastIndex + suffix.length, abs.length);
|
||||
|
||||
}, "manipulation of current working directory");
|
||||
|
||||
test(function () {
|
||||
|
||||
fs.copyTree(phantom.libraryPath, TEST_DIR);
|
||||
this.add_cleanup(function () { fs.removeTree(TEST_DIR); });
|
||||
|
||||
assert_deep_equals(fs.list(phantom.libraryPath), fs.list(TEST_DIR));
|
||||
|
||||
}, "copying a directory tree");
|
||||
|
||||
test(function () {
|
||||
assert_type_of(fs.readLink, 'function');
|
||||
// TODO: test the actual functionality once we can create symlinks.
|
||||
}, "fs.readLink exists");
|
||||
|
||||
generate_tests(function fs_join_test (parts, expected) {
|
||||
var actual = fs.join.apply(null, parts);
|
||||
assert_equals(actual, expected);
|
||||
}, [
|
||||
[ "fs.join: []", [], "." ],
|
||||
[ "fs.join: nonsense", [[], null], "." ],
|
||||
[ "fs.join: 1 element", [""], "." ],
|
||||
[ "fs.join: 2 elements", ["", "a"], "/a" ],
|
||||
[ "fs.join: 3 elements", ["a", "b", "c"], "a/b/c" ],
|
||||
[ "fs.join: 4 elements", ["", "a", "b", "c"], "/a/b/c" ],
|
||||
[ "fs.join: empty elements", ["", "a", "", "b", "", "c"], "/a/b/c" ],
|
||||
[ "fs.join: empty elements 2", ["a", "", "b", "", "c"], "a/b/c" ]
|
||||
]);
|
||||
|
||||
generate_tests(function fs_split_test (input, expected) {
|
||||
var path = input.join(fs.separator);
|
||||
var actual = fs.split(path);
|
||||
assert_deep_equals(actual, expected);
|
||||
}, [
|
||||
[ "fs.split: absolute",
|
||||
["", "a", "b", "c", "d"], ["", "a", "b", "c", "d"] ],
|
||||
[ "fs.split: absolute, trailing",
|
||||
["", "a", "b", "c", "d", ""], ["", "a", "b", "c", "d"] ],
|
||||
[ "fs.split: non-absolute",
|
||||
["a", "b", "c", "d"], ["a", "b", "c", "d"] ],
|
||||
[ "fs.split: non-absolute, trailing",
|
||||
["a", "b", "c", "d", ""], ["a", "b", "c", "d"] ],
|
||||
[ "fs.split: repeated separators",
|
||||
["a", "", "", "",
|
||||
"b", "",
|
||||
"c", "", "",
|
||||
"d", "", "", ""], ["a", "b", "c", "d"] ]
|
||||
]);
|
22
third_party/phantomjs/test/module/system/stdin.js
vendored
Normal file
22
third_party/phantomjs/test/module/system/stdin.js
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
//! stdin: Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich
|
||||
//! stdin: いろはにほへとちりぬるをわかよたれそつねならむうゐのおくやまけふこえてあさきゆめみしゑひもせす
|
||||
|
||||
//^ first line: pangram in German
|
||||
//^ second line: pan+isogram in hiragana (the Iroha)
|
||||
|
||||
var stdin;
|
||||
setup(function () { stdin = require("system").stdin; });
|
||||
|
||||
test(function () {
|
||||
assert_equals(stdin.readLine(),
|
||||
"Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich");
|
||||
}, "input line one (German)");
|
||||
|
||||
test(function () {
|
||||
assert_equals(stdin.readLine(),
|
||||
"いろはにほへとちりぬるをわかよたれそつねならむうゐのおくやまけふこえてあさきゆめみしゑひもせす");
|
||||
}, "input line two (Japanese)");
|
||||
|
||||
test(function () {
|
||||
assert_equals(stdin.readLine(), "");
|
||||
}, "input line three (EOF)");
|
14
third_party/phantomjs/test/module/system/stdout-err.js
vendored
Normal file
14
third_party/phantomjs/test/module/system/stdout-err.js
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
//! no-harness
|
||||
//! expect-stdout: Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich
|
||||
//! expect-stderr: いろはにほへとちりぬるをわかよたれそつねならむうゐのおくやまけふこえてあさきゆめみしゑひもせす
|
||||
|
||||
//^ stdout: pangram in German
|
||||
//^ stderr: pan+isogram in hiragana (the Iroha)
|
||||
|
||||
phantom.onError = function () { phantom.exit(1); };
|
||||
|
||||
var sys = require("system");
|
||||
|
||||
sys.stdout.write("Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich\n");
|
||||
sys.stderr.write("いろはにほへとちりぬるをわかよたれそつねならむうゐのおくやまけふこえてあさきゆめみしゑひもせす");
|
||||
phantom.exit(0);
|
77
third_party/phantomjs/test/module/system/system.js
vendored
Normal file
77
third_party/phantomjs/test/module/system/system.js
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
var system = require('system');
|
||||
|
||||
test(function () {
|
||||
assert_type_of(system, 'object');
|
||||
assert_not_equals(system, null);
|
||||
}, "system object");
|
||||
|
||||
test(function () {
|
||||
assert_own_property(system, 'pid');
|
||||
assert_type_of(system.pid, 'number');
|
||||
assert_greater_than(system.pid, 0);
|
||||
}, "system.pid");
|
||||
|
||||
test(function () {
|
||||
assert_own_property(system, 'isSSLSupported');
|
||||
assert_type_of(system.isSSLSupported, 'boolean');
|
||||
assert_equals(system.isSSLSupported, true);
|
||||
}, "system.isSSLSupported", {/* unsupported */expected_fail: true});
|
||||
|
||||
test(function () {
|
||||
assert_own_property(system, 'args');
|
||||
assert_type_of(system.args, 'object');
|
||||
assert_instance_of(system.args, Array);
|
||||
assert_greater_than_equal(system.args.length, 1);
|
||||
|
||||
// args[0] will be the test harness.
|
||||
assert_regexp_match(system.args[0], /\btestharness\.js$/);
|
||||
}, "system.args", {/* unsupported */expected_fail: true});
|
||||
|
||||
test(function () {
|
||||
assert_own_property(system, 'env');
|
||||
assert_type_of(system.env, 'object');
|
||||
}, "system.env");
|
||||
|
||||
test(function () {
|
||||
assert_own_property(system, 'platform');
|
||||
assert_type_of(system.platform, 'string');
|
||||
assert_equals(system.platform, 'phantomjs');
|
||||
}, "system.platform");
|
||||
|
||||
test(function () {
|
||||
assert_own_property(system, 'os');
|
||||
assert_type_of(system.os, 'object');
|
||||
|
||||
assert_type_of(system.os.architecture, 'string');
|
||||
assert_type_of(system.os.name, 'string');
|
||||
assert_type_of(system.os.version, 'string');
|
||||
|
||||
if (system.os.name === 'mac') {
|
||||
// release is x.y.z with x = 10 for Snow Leopard and 14 for Yosemite
|
||||
assert_type_of(system.os.release, 'string');
|
||||
assert_greater_than_equal(parseInt(system.os.release, 10), 10);
|
||||
}
|
||||
}, "system.os");
|
||||
|
||||
test(function () {
|
||||
assert_type_of(system.stdin, 'object');
|
||||
assert_type_of(system.stdin.read, 'function');
|
||||
assert_type_of(system.stdin.readLine, 'function');
|
||||
assert_type_of(system.stdin.close, 'function');
|
||||
}, "system.stdin");
|
||||
|
||||
test(function () {
|
||||
assert_type_of(system.stdout, 'object');
|
||||
assert_type_of(system.stdout.write, 'function');
|
||||
assert_type_of(system.stdout.writeLine, 'function');
|
||||
assert_type_of(system.stdout.flush, 'function');
|
||||
assert_type_of(system.stdout.close, 'function');
|
||||
}, "system.stdout");
|
||||
|
||||
test(function () {
|
||||
assert_type_of(system.stderr, 'object');
|
||||
assert_type_of(system.stderr.write, 'function');
|
||||
assert_type_of(system.stderr.writeLine, 'function');
|
||||
assert_type_of(system.stderr.flush, 'function');
|
||||
assert_type_of(system.stderr.close, 'function');
|
||||
}, "system.stderr");
|
37
third_party/phantomjs/test/module/webpage/abort-network-request.js
vendored
Normal file
37
third_party/phantomjs/test/module/webpage/abort-network-request.js
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
//! unsupported
|
||||
var webpage = require('webpage');
|
||||
|
||||
async_test(function () {
|
||||
var page = webpage.create();
|
||||
var abortCount = 0;
|
||||
var errorCount = 0;
|
||||
var abortedIds = {};
|
||||
var urlToBlockRegExp = /logo\.png$/i;
|
||||
|
||||
page.onResourceRequested = this.step_func(function(requestData, request) {
|
||||
assert_type_of(request, 'object');
|
||||
assert_type_of(request.abort, 'function');
|
||||
if (urlToBlockRegExp.test(requestData.url)) {
|
||||
request.abort();
|
||||
++abortCount;
|
||||
abortedIds[requestData.id] = 1;
|
||||
}
|
||||
});
|
||||
page.onResourceError = this.step_func(function(error) {
|
||||
// We can't match up errors to requests by URL because error.url will
|
||||
// be the empty string in this case. FIXME.
|
||||
assert_own_property(abortedIds, error.id);
|
||||
++errorCount;
|
||||
});
|
||||
page.onResourceReceived = this.step_func(function(response) {
|
||||
assert_regexp_not_match(response.url, urlToBlockRegExp);
|
||||
});
|
||||
|
||||
page.open(TEST_HTTP_BASE + 'logo.html',
|
||||
this.step_func_done(function (status) {
|
||||
assert_equals(status, 'success');
|
||||
assert_equals(abortCount, 1);
|
||||
assert_equals(errorCount, 1);
|
||||
}));
|
||||
|
||||
}, "can abort network requests");
|
25
third_party/phantomjs/test/module/webpage/add-header.js
vendored
Normal file
25
third_party/phantomjs/test/module/webpage/add-header.js
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
//! unsupported
|
||||
async_test(function () {
|
||||
var webpage = require('webpage');
|
||||
|
||||
// NOTE: HTTP header names are case-insensitive. Our test server
|
||||
// returns the name in lowercase.
|
||||
|
||||
var page = webpage.create();
|
||||
assert_type_of(page.customHeaders, 'object');
|
||||
assert_deep_equals(page.customHeaders, {});
|
||||
|
||||
page.onResourceRequested = this.step_func(function(requestData, request) {
|
||||
assert_type_of(request.setHeader, 'function');
|
||||
request.setHeader('CustomHeader', 'CustomValue');
|
||||
});
|
||||
page.open(TEST_HTTP_BASE + 'echo', this.step_func_done(function (status) {
|
||||
var json, headers;
|
||||
assert_equals(status, 'success');
|
||||
json = JSON.parse(page.plainText);
|
||||
headers = json.headers;
|
||||
assert_own_property(headers, 'customheader');
|
||||
assert_equals(headers.customheader, 'CustomValue');
|
||||
}));
|
||||
|
||||
}, "add custom headers in onResourceRequested");
|
16
third_party/phantomjs/test/module/webpage/callback.js
vendored
Normal file
16
third_party/phantomjs/test/module/webpage/callback.js
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
test(function () {
|
||||
var page = require('webpage').create();
|
||||
|
||||
var msgA = "a",
|
||||
msgB = "b",
|
||||
result,
|
||||
expected = msgA + msgB;
|
||||
page.onCallback = function(a, b) {
|
||||
return a + b;
|
||||
};
|
||||
result = page.evaluate(function(a, b) {
|
||||
return window.callPhantom(a, b);
|
||||
}, msgA, msgB);
|
||||
|
||||
assert_equals(result, expected);
|
||||
}, "page.onCallback");
|
50
third_party/phantomjs/test/module/webpage/capture-content.js
vendored
Normal file
50
third_party/phantomjs/test/module/webpage/capture-content.js
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
//! unsupported
|
||||
var content;
|
||||
setup(function () {
|
||||
var fs = require('fs');
|
||||
// libraryPath is test/module/webpage
|
||||
content = fs.read(fs.join(phantom.libraryPath,
|
||||
"../../www/hello.html"));
|
||||
});
|
||||
|
||||
// XFAIL: This feature had to be backed out for breaking WebSockets.
|
||||
async_test(function () {
|
||||
var page = require('webpage').create();
|
||||
var lastChunk = "";
|
||||
var bodySize = 0;
|
||||
page.captureContent = ['.*'];
|
||||
// Not a step function because it may be called several times
|
||||
// and doesn't need to make assertions.
|
||||
page.onResourceReceived = function (resource) {
|
||||
lastChunk = resource.body;
|
||||
bodySize = resource.bodySize;
|
||||
};
|
||||
page.open(TEST_HTTP_BASE + "hello.html",
|
||||
this.step_func_done(function (status) {
|
||||
assert_equals(status, "success");
|
||||
assert_equals(bodySize, content.length);
|
||||
assert_equals(lastChunk, content);
|
||||
}));
|
||||
|
||||
}, "onResourceReceived sees the body if captureContent is activated",
|
||||
{ expected_fail: true }
|
||||
);
|
||||
|
||||
async_test(function () {
|
||||
var page = require('webpage').create();
|
||||
var lastChunk = "";
|
||||
var bodySize = 0;
|
||||
page.captureContent = ['/some/other/url'];
|
||||
// Not a step function because it may be called several times
|
||||
// and doesn't need to make assertions.
|
||||
page.onResourceReceived = function (resource) {
|
||||
lastChunk = resource.body;
|
||||
bodySize = resource.bodySize;
|
||||
};
|
||||
page.open(TEST_HTTP_BASE + "hello.html",
|
||||
this.step_func_done(function (status) {
|
||||
assert_equals(status, "success");
|
||||
assert_equals(bodySize, 0);
|
||||
assert_equals(lastChunk, "");
|
||||
}));
|
||||
}, "onResourceReceived doesn't see the body if captureContent doesn't match");
|
27
third_party/phantomjs/test/module/webpage/change-request-encoded-url.js
vendored
Normal file
27
third_party/phantomjs/test/module/webpage/change-request-encoded-url.js
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
//! unsupported
|
||||
var webpage = require('webpage');
|
||||
|
||||
async_test(function () {
|
||||
var page = webpage.create();
|
||||
|
||||
var url = TEST_HTTP_BASE + "cdn-cgi/pe/bag?r%5B%5D="+
|
||||
"http%3A%2F%2Fwww.example.org%2Fcdn-cgi%2Fnexp%2F"+
|
||||
"abv%3D927102467%2Fapps%2Fabetterbrowser.js";
|
||||
var receivedUrl;
|
||||
|
||||
page.onResourceRequested = this.step_func(function(requestData, request) {
|
||||
request.changeUrl(requestData.url);
|
||||
});
|
||||
|
||||
page.onResourceReceived = this.step_func(function(data) {
|
||||
if (data.stage === 'end') {
|
||||
receivedUrl = data.url;
|
||||
}
|
||||
});
|
||||
|
||||
page.open(url, this.step_func_done(function (status) {
|
||||
assert_equals(status, 'success');
|
||||
assert_equals(receivedUrl, url);
|
||||
}));
|
||||
|
||||
}, "encoded URLs properly round-trip through request.changeUrl");
|
40
third_party/phantomjs/test/module/webpage/change-request-url.js
vendored
Normal file
40
third_party/phantomjs/test/module/webpage/change-request-url.js
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
//! unsupported
|
||||
var webpage = require('webpage');
|
||||
|
||||
async_test(function () {
|
||||
|
||||
var page = webpage.create();
|
||||
var urlToChange = TEST_HTTP_BASE + 'logo.png';
|
||||
var alternativeUrl = TEST_HTTP_BASE + 'phantomjs-logo.gif';
|
||||
var startStage = 0;
|
||||
var endStage = 0;
|
||||
|
||||
page.onResourceRequested = this.step_func(function(requestData, request) {
|
||||
if (requestData.url === urlToChange) {
|
||||
assert_type_of(request, 'object');
|
||||
assert_type_of(request.changeUrl, 'function');
|
||||
request.changeUrl(alternativeUrl);
|
||||
}
|
||||
});
|
||||
|
||||
page.onResourceReceived = this.step_func(function(data) {
|
||||
if (data.url === alternativeUrl && data.stage === 'start') {
|
||||
++startStage;
|
||||
}
|
||||
if (data.url === alternativeUrl && data.stage === 'end') {
|
||||
++endStage;
|
||||
}
|
||||
});
|
||||
|
||||
page.open(TEST_HTTP_BASE + 'logo.html',
|
||||
this.step_func_done(function (status) {
|
||||
assert_equals(status, 'success');
|
||||
assert_equals(startStage, 1);
|
||||
assert_equals(endStage, 1);
|
||||
|
||||
// The page HTML should still refer to the original image.
|
||||
assert_regexp_match(page.content, /logo\.png/);
|
||||
assert_regexp_not_match(page.content, /logo\.gif/);
|
||||
}));
|
||||
|
||||
}, "request.changeUrl");
|
33
third_party/phantomjs/test/module/webpage/cjk-text-codecs.js
vendored
Normal file
33
third_party/phantomjs/test/module/webpage/cjk-text-codecs.js
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
var webpage = require('webpage');
|
||||
|
||||
function test_one(text) {
|
||||
var t = async_test(text.codec);
|
||||
t.step(function () {
|
||||
var page = webpage.create();
|
||||
page.open(text.url, t.step_func_done(function () {
|
||||
var decodedText = page.evaluate(function() {
|
||||
return document.querySelector('pre').innerText;
|
||||
});
|
||||
var regex = '^' + text.reference + '$';
|
||||
assert_regexp_match(text.reference, new RegExp(regex));
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
function Text(codec, base64, reference) {
|
||||
this.codec = codec;
|
||||
this.base64 = base64;
|
||||
this.reference = reference;
|
||||
this.url = 'data:text/plain;charset=' + this.codec +
|
||||
';base64,' + this.base64;
|
||||
}
|
||||
|
||||
[
|
||||
new Text('Shift_JIS', 'g3SDQIOTg2eDgA==', 'ファントム'),
|
||||
new Text('EUC-JP', 'pdWloaXzpcil4A0K', 'ファントム'),
|
||||
new Text('ISO-2022-JP', 'GyRCJVUlISVzJUglYBsoQg0K', 'ファントム'),
|
||||
new Text('Big5', 'pNu2SA0K', '幻象'),
|
||||
new Text('GBK', 'u8PP8w0K', '幻象'),
|
||||
new Text('EUC-KR', 'yK+/tQ==', '환영'),
|
||||
]
|
||||
.forEach(test_one);
|
19
third_party/phantomjs/test/module/webpage/clip-rect.js
vendored
Normal file
19
third_party/phantomjs/test/module/webpage/clip-rect.js
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
var webpage = require('webpage');
|
||||
|
||||
test(function () {
|
||||
var defaultPage = webpage.create();
|
||||
assert_deep_equals(defaultPage.clipRect, {height:0,left:0,top:0,width:0});
|
||||
}, "default page.clipRect");
|
||||
|
||||
test(function () {
|
||||
var options = {
|
||||
clipRect: {
|
||||
height: 100,
|
||||
left: 10,
|
||||
top: 20,
|
||||
width: 200
|
||||
}
|
||||
};
|
||||
var customPage = webpage.create(options);
|
||||
assert_deep_equals(customPage.clipRect, options.clipRect);
|
||||
}, "custom page.clipRect");
|
59
third_party/phantomjs/test/module/webpage/construction-with-options.js
vendored
Normal file
59
third_party/phantomjs/test/module/webpage/construction-with-options.js
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
//! unsupported
|
||||
test(function () {
|
||||
var opts = {},
|
||||
page = new WebPage(opts);
|
||||
assert_type_of(page, 'object');
|
||||
assert_not_equals(page, null);
|
||||
}, "webpage constructor accepts an opts object");
|
||||
|
||||
async_test(function () {
|
||||
var opts = {
|
||||
onConsoleMessage: this.step_func_done(function (msg) {
|
||||
assert_equals(msg, "test log");
|
||||
})
|
||||
};
|
||||
var page = new WebPage(opts);
|
||||
assert_equals(page.onConsoleMessage, opts.onConsoleMessage);
|
||||
page.evaluate(function () {console.log('test log');});
|
||||
|
||||
}, "specifying onConsoleMessage with opts");
|
||||
|
||||
async_test(function () {
|
||||
var page_opened = false;
|
||||
var opts = {
|
||||
onLoadStarted: this.step_func_done(function (msg) {
|
||||
assert_is_true(page_opened);
|
||||
})
|
||||
};
|
||||
var page = new WebPage(opts);
|
||||
assert_equals(page.onLoadStarted, opts.onLoadStarted);
|
||||
page_opened = true;
|
||||
page.open("about:blank");
|
||||
|
||||
}, "specifying onLoadStarted with opts");
|
||||
|
||||
async_test(function () {
|
||||
var page_opened = false;
|
||||
var opts = {
|
||||
onLoadFinished: this.step_func_done(function (msg) {
|
||||
assert_is_true(page_opened);
|
||||
})
|
||||
};
|
||||
var page = new WebPage(opts);
|
||||
assert_equals(page.onLoadFinished, opts.onLoadFinished);
|
||||
page_opened = true;
|
||||
page.open("about:blank");
|
||||
|
||||
}, "specifying onLoadFinished with opts");
|
||||
|
||||
// FIXME: Actually test that the timeout is effective.
|
||||
test(function () {
|
||||
var opts = {
|
||||
settings: {
|
||||
timeout: 100 // time in ms
|
||||
}
|
||||
};
|
||||
var page = new WebPage(opts);
|
||||
assert_equals(page.settings.timeout, opts.settings.timeout);
|
||||
|
||||
}, "specifying timeout with opts");
|
33
third_party/phantomjs/test/module/webpage/contextclick-event.js
vendored
Normal file
33
third_party/phantomjs/test/module/webpage/contextclick-event.js
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
//! unsupported
|
||||
test(function () {
|
||||
var page = require('webpage').create();
|
||||
|
||||
page.evaluate(function() {
|
||||
window.addEventListener('contextmenu', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || {};
|
||||
window.loggedEvent.contextmenu = event;
|
||||
}, false);
|
||||
});
|
||||
page.sendEvent('contextmenu', 42, 217);
|
||||
|
||||
var event = page.evaluate(function() {
|
||||
return window.loggedEvent;
|
||||
});
|
||||
assert_equals(event.contextmenu.clientX, 42);
|
||||
assert_equals(event.contextmenu.clientY, 217);
|
||||
|
||||
// click with modifier key
|
||||
page.evaluate(function() {
|
||||
window.addEventListener('contextmenu', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || {};
|
||||
window.loggedEvent.contextmenu = event;
|
||||
}, false);
|
||||
});
|
||||
page.sendEvent('contextmenu', 100, 100, 'left', page.event.modifier.shift);
|
||||
|
||||
var event = page.evaluate(function() {
|
||||
return window.loggedEvent.contextmenu;
|
||||
});
|
||||
assert_is_true(event.shiftKey);
|
||||
|
||||
}, "context click events");
|
112
third_party/phantomjs/test/module/webpage/cookies.js
vendored
Normal file
112
third_party/phantomjs/test/module/webpage/cookies.js
vendored
Normal file
@ -0,0 +1,112 @@
|
||||
//! unsupported
|
||||
async_test(function () {
|
||||
var url = TEST_HTTP_BASE + "echo";
|
||||
var page = new WebPage();
|
||||
|
||||
page.cookies = [{
|
||||
'name' : 'Valid-Cookie-Name',
|
||||
'value' : 'Valid-Cookie-Value',
|
||||
'domain' : 'localhost',
|
||||
'path' : '/',
|
||||
'httponly' : true,
|
||||
'secure' : false
|
||||
},{
|
||||
'name' : 'Valid-Cookie-Name-Sec',
|
||||
'value' : 'Valid-Cookie-Value-Sec',
|
||||
'domain' : 'localhost',
|
||||
'path' : '/',
|
||||
'httponly' : true,
|
||||
'secure' : false,
|
||||
'expires' : Date.now() + 3600 //< expires in 1h
|
||||
}];
|
||||
|
||||
page.open(url, this.step_func(function (status) {
|
||||
assert_equals(status, "success");
|
||||
var headers = JSON.parse(page.plainText).headers;
|
||||
assert_own_property(headers, 'cookie');
|
||||
assert_regexp_match(headers.cookie, /\bValid-Cookie-Name\b/);
|
||||
assert_regexp_match(headers.cookie, /\bValid-Cookie-Value\b/);
|
||||
assert_regexp_match(headers.cookie, /\bValid-Cookie-Name-Sec\b/);
|
||||
assert_regexp_match(headers.cookie, /\bValid-Cookie-Value-Sec\b/);
|
||||
assert_not_equals(page.cookies.length, 0);
|
||||
|
||||
page.cookies = [];
|
||||
page.open(url, this.step_func_done(function (status) {
|
||||
assert_equals(status, "success");
|
||||
var headers = JSON.parse(page.plainText).headers;
|
||||
assert_no_property(headers, 'cookie');
|
||||
}));
|
||||
}));
|
||||
}, "adding and deleting cookies with page.cookies");
|
||||
|
||||
async_test(function () {
|
||||
var url = TEST_HTTP_BASE + "echo";
|
||||
var page = new WebPage();
|
||||
|
||||
page.addCookie({
|
||||
'name' : 'Added-Cookie-Name',
|
||||
'value' : 'Added-Cookie-Value',
|
||||
'domain' : 'localhost'
|
||||
});
|
||||
|
||||
page.open(url, this.step_func(function (status) {
|
||||
assert_equals(status, "success");
|
||||
var headers = JSON.parse(page.plainText).headers;
|
||||
assert_own_property(headers, 'cookie');
|
||||
assert_regexp_match(headers.cookie, /\bAdded-Cookie-Name\b/);
|
||||
assert_regexp_match(headers.cookie, /\bAdded-Cookie-Value\b/);
|
||||
|
||||
page.deleteCookie("Added-Cookie-Name");
|
||||
page.open(url, this.step_func_done(function (status) {
|
||||
assert_equals(status, "success");
|
||||
var headers = JSON.parse(page.plainText).headers;
|
||||
assert_no_property(headers, 'cookie');
|
||||
}));
|
||||
}));
|
||||
|
||||
}, "adding and deleting cookies with page.addCookie and page.deleteCookie");
|
||||
|
||||
async_test(function () {
|
||||
var url = TEST_HTTP_BASE + "echo";
|
||||
var page = new WebPage();
|
||||
|
||||
page.cookies = [
|
||||
{ // domain mismatch.
|
||||
'name' : 'Invalid-Cookie-Name-1',
|
||||
'value' : 'Invalid-Cookie-Value-1',
|
||||
'domain' : 'foo.example'
|
||||
},{ // path mismatch: the cookie will be set,
|
||||
// but won't be visible from the given URL (not same path).
|
||||
'name' : 'Invalid-Cookie-Name-2',
|
||||
'value' : 'Invalid-Cookie-Value-2',
|
||||
'domain' : 'localhost',
|
||||
'path' : '/bar'
|
||||
},{ // cookie expired.
|
||||
'name' : 'Invalid-Cookie-Name-3',
|
||||
'value' : 'Invalid-Cookie-Value-3',
|
||||
'domain' : 'localhost',
|
||||
'expires' : 'Sat, 01 Jan 2000 00:00:00 GMT'
|
||||
},{ // https only: the cookie will be set,
|
||||
// but won't be visible from the given URL (not https).
|
||||
'name' : 'Invalid-Cookie-Name-4',
|
||||
'value' : 'Invalid-Cookie-Value-4',
|
||||
'domain' : 'localhost',
|
||||
'secure' : true
|
||||
},{ // cookie expired (date in "sec since epoch").
|
||||
'name' : 'Invalid-Cookie-Name-5',
|
||||
'value' : 'Invalid-Cookie-Value-5',
|
||||
'domain' : 'localhost',
|
||||
'expires' : new Date().getTime() - 1 //< date in the past
|
||||
},{ // cookie expired (date in "sec since epoch" - using "expiry").
|
||||
'name' : 'Invalid-Cookie-Name-6',
|
||||
'value' : 'Invalid-Cookie-Value-6',
|
||||
'domain' : 'localhost',
|
||||
'expiry' : new Date().getTime() - 1 //< date in the past
|
||||
}];
|
||||
|
||||
page.open(url, this.step_func_done(function (status) {
|
||||
assert_equals(status, "success");
|
||||
var headers = JSON.parse(page.plainText).headers;
|
||||
assert_no_property(headers, 'cookie');
|
||||
}));
|
||||
}, "page.cookies provides cookies only to appropriate requests");
|
30
third_party/phantomjs/test/module/webpage/custom-headers.js
vendored
Normal file
30
third_party/phantomjs/test/module/webpage/custom-headers.js
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
async_test(function () {
|
||||
var webpage = require('webpage');
|
||||
var page = webpage.create();
|
||||
assert_type_of(page.customHeaders, 'object');
|
||||
assert_deep_equals(page.customHeaders, {});
|
||||
|
||||
// NOTE: HTTP header names are case-insensitive. Our test server
|
||||
// returns the name in lowercase.
|
||||
page.customHeaders = {
|
||||
'Custom-Key': 'Custom-Value',
|
||||
'User-Agent': 'Overriden-UA',
|
||||
'Referer': 'http://example.com/'
|
||||
};
|
||||
page.open(TEST_HTTP_BASE + 'echo', this.step_func_done(function (status) {
|
||||
var json, headers;
|
||||
assert_equals(status, 'success');
|
||||
json = JSON.parse(page.plainText);
|
||||
assert_type_of(json, 'object');
|
||||
headers = json.headers;
|
||||
assert_type_of(headers, 'object');
|
||||
|
||||
assert_own_property(headers, 'custom-key');
|
||||
assert_own_property(headers, 'user-agent');
|
||||
assert_own_property(headers, 'referer');
|
||||
assert_equals(headers['custom-key'], 'Custom-Value');
|
||||
assert_equals(headers['user-agent'], 'Overriden-UA');
|
||||
assert_equals(headers['referer'], 'http://example.com/');
|
||||
}));
|
||||
|
||||
}, "adding custom headers with page.customHeaders");
|
14
third_party/phantomjs/test/module/webpage/evaluate-broken-json.js
vendored
Normal file
14
third_party/phantomjs/test/module/webpage/evaluate-broken-json.js
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
test(function () {
|
||||
var webpage = require('webpage');
|
||||
var page = webpage.create();
|
||||
|
||||
// Hijack JSON.parse to something completely useless.
|
||||
page.content = '<html><script>JSON.parse = function() {}</script></html>';
|
||||
|
||||
var result = page.evaluate(function(obj) {
|
||||
return obj.value * obj.value;
|
||||
}, { value: 4 });
|
||||
|
||||
assert_equals(result, 16);
|
||||
|
||||
}, "page script should not interfere with page.evaluate");
|
56
third_party/phantomjs/test/module/webpage/file-upload.js
vendored
Normal file
56
third_party/phantomjs/test/module/webpage/file-upload.js
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
//! unsupported
|
||||
|
||||
// Note: uses various files in module/webpage as things to be uploaded.
|
||||
// Which files they are doesn't matter.
|
||||
|
||||
var page;
|
||||
setup(function () {
|
||||
page = new WebPage();
|
||||
page.content =
|
||||
'<input type="file" id="file">\n' +
|
||||
'<input type="file" id="file2" multiple>\n' +
|
||||
'<input type="file" id="file3" multiple>' +
|
||||
'<input type="file" id="file4">';
|
||||
page.uploadFile("#file", "file-upload.js");
|
||||
page.uploadFile("#file2", "file-upload.js");
|
||||
page.uploadFile("#file3", ["file-upload.js", "object.js"]);
|
||||
});
|
||||
|
||||
function test_one_elt(id, names) {
|
||||
var files = page.evaluate(function (id) {
|
||||
var elt = document.getElementById(id);
|
||||
var rv = [];
|
||||
for (var i = 0; i < elt.files.length; i++) {
|
||||
rv.push(elt.files[i].fileName);
|
||||
}
|
||||
return rv;
|
||||
}, id);
|
||||
assert_deep_equals(files, names);
|
||||
}
|
||||
|
||||
generate_tests(test_one_elt, [
|
||||
["single upload single file", "file", ["file-upload.js"]],
|
||||
["multiple upload single file", "file2", ["file-upload.js"]],
|
||||
["multiple upload multiple file", "file3", ["file-upload.js", "object.js"]],
|
||||
], { expected_fail: true });
|
||||
|
||||
async_test(function () {
|
||||
page.onFilePicker = this.step_func(function (oldFile) {
|
||||
assert_equals(oldFile, "");
|
||||
return "no-plugin.js";
|
||||
});
|
||||
|
||||
test_one_elt("file4", []);
|
||||
|
||||
page.evaluate(function () {
|
||||
var fileUp = document.querySelector("#file4");
|
||||
var ev = document.createEvent("MouseEvents");
|
||||
ev.initEvent("click", true, true);
|
||||
fileUp.dispatchEvent(ev);
|
||||
});
|
||||
|
||||
setTimeout(this.step_func_done(function () {
|
||||
test_one_elt("file4", ["no-plugin.js"]);
|
||||
}, 0));
|
||||
|
||||
}, "page.onFilePicker", { expected_fail: true });
|
69
third_party/phantomjs/test/module/webpage/frame-switching-deprecated.js
vendored
Normal file
69
third_party/phantomjs/test/module/webpage/frame-switching-deprecated.js
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
//! unsupported
|
||||
async_test(function () {
|
||||
var p = require("webpage").create();
|
||||
|
||||
function pageTitle(page) {
|
||||
return page.evaluate(function(){
|
||||
return window.document.title;
|
||||
});
|
||||
}
|
||||
|
||||
function setPageTitle(page, newTitle) {
|
||||
page.evaluate(function(newTitle){
|
||||
window.document.title = newTitle;
|
||||
}, newTitle);
|
||||
}
|
||||
|
||||
function testFrameSwitchingDeprecated() {
|
||||
assert_equals(pageTitle(p), "index");
|
||||
assert_equals(p.currentFrameName(), "");
|
||||
assert_equals(p.childFramesCount(), 2);
|
||||
assert_deep_equals(p.childFramesName(), ["frame1", "frame2"]);
|
||||
setPageTitle(p, pageTitle(p) + "-visited");
|
||||
|
||||
assert_is_true(p.switchToChildFrame("frame1"));
|
||||
assert_equals(pageTitle(p), "frame1");
|
||||
assert_equals(p.currentFrameName(), "frame1");
|
||||
assert_equals(p.childFramesCount(), 2);
|
||||
assert_deep_equals(p.childFramesName(), ["frame1-1", "frame1-2"]);
|
||||
setPageTitle(p, pageTitle(p) + "-visited");
|
||||
|
||||
assert_is_true(p.switchToChildFrame("frame1-2"));
|
||||
assert_equals(pageTitle(p), "frame1-2");
|
||||
assert_equals(p.currentFrameName(), "frame1-2");
|
||||
assert_equals(p.childFramesCount(), 0);
|
||||
assert_deep_equals(p.childFramesName(), []);
|
||||
setPageTitle(p, pageTitle(p) + "-visited");
|
||||
|
||||
assert_is_true(p.switchToParentFrame());
|
||||
assert_equals(pageTitle(p), "frame1-visited");
|
||||
assert_equals(p.currentFrameName(), "frame1");
|
||||
assert_equals(p.childFramesCount(), 2);
|
||||
assert_deep_equals(p.childFramesName(), ["frame1-1", "frame1-2"]);
|
||||
|
||||
assert_is_true(p.switchToChildFrame(0));
|
||||
assert_equals(pageTitle(p), "frame1-1");
|
||||
assert_equals(p.currentFrameName(), "frame1-1");
|
||||
assert_equals(p.childFramesCount(), 0);
|
||||
assert_deep_equals(p.childFramesName(), []);
|
||||
|
||||
assert_equals(p.switchToMainFrame(), undefined);
|
||||
assert_equals(pageTitle(p), "index-visited");
|
||||
assert_equals(p.currentFrameName(), "");
|
||||
assert_equals(p.childFramesCount(), 2);
|
||||
assert_deep_equals(p.childFramesName(), ["frame1", "frame2"]);
|
||||
|
||||
assert_is_true(p.switchToChildFrame("frame2"));
|
||||
assert_equals(pageTitle(p), "frame2");
|
||||
assert_equals(p.currentFrameName(), "frame2");
|
||||
assert_equals(p.childFramesCount(), 3);
|
||||
assert_deep_equals(p.childFramesName(),
|
||||
["frame2-1", "frame2-2", "frame2-3"]);
|
||||
}
|
||||
|
||||
p.open(TEST_HTTP_BASE + "frameset", this.step_func_done(function (s) {
|
||||
assert_equals(s, "success");
|
||||
testFrameSwitchingDeprecated();
|
||||
}));
|
||||
|
||||
}, "frame switching deprecated API");
|
98
third_party/phantomjs/test/module/webpage/frame-switching.js
vendored
Normal file
98
third_party/phantomjs/test/module/webpage/frame-switching.js
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
//! unsupported
|
||||
async_test(function () {
|
||||
var p = require("webpage").create();
|
||||
|
||||
function pageTitle(page) {
|
||||
return page.evaluate(function(){
|
||||
return window.document.title;
|
||||
});
|
||||
}
|
||||
|
||||
function setPageTitle(page, newTitle) {
|
||||
page.evaluate(function(newTitle){
|
||||
window.document.title = newTitle;
|
||||
}, newTitle);
|
||||
}
|
||||
|
||||
function testFrameSwitching() {
|
||||
assert_equals(pageTitle(p), "index");
|
||||
assert_equals(p.frameName, "");
|
||||
assert_equals(p.framesCount, 2);
|
||||
assert_deep_equals(p.framesName, ["frame1", "frame2"]);
|
||||
setPageTitle(p, pageTitle(p) + "-visited");
|
||||
|
||||
assert_is_true(p.switchToFrame("frame1"));
|
||||
assert_equals(pageTitle(p), "frame1");
|
||||
assert_equals(p.frameName, "frame1");
|
||||
assert_equals(p.framesCount, 2);
|
||||
assert_deep_equals(p.framesName, ["frame1-1", "frame1-2"]);
|
||||
setPageTitle(p, pageTitle(p) + "-visited");
|
||||
|
||||
assert_is_true(p.switchToFrame("frame1-2"));
|
||||
assert_equals(pageTitle(p), "frame1-2");
|
||||
assert_equals(p.frameName, "frame1-2");
|
||||
assert_equals(p.framesCount, 0);
|
||||
assert_deep_equals(p.framesName, []);
|
||||
setPageTitle(p, pageTitle(p) + "-visited");
|
||||
|
||||
assert_is_true(p.switchToParentFrame());
|
||||
assert_equals(pageTitle(p), "frame1-visited");
|
||||
assert_equals(p.frameName, "frame1");
|
||||
assert_equals(p.framesCount, 2);
|
||||
assert_deep_equals(p.framesName, ["frame1-1", "frame1-2"]);
|
||||
|
||||
assert_is_true(p.switchToFrame(0));
|
||||
assert_equals(pageTitle(p), "frame1-1");
|
||||
assert_equals(p.frameName, "frame1-1");
|
||||
assert_equals(p.framesCount, 0);
|
||||
assert_deep_equals(p.framesName, []);
|
||||
|
||||
assert_equals(p.switchToMainFrame(), undefined);
|
||||
assert_equals(pageTitle(p), "index-visited");
|
||||
assert_equals(p.frameName, "");
|
||||
assert_equals(p.framesCount, 2);
|
||||
assert_deep_equals(p.framesName, ["frame1", "frame2"]);
|
||||
|
||||
assert_is_true(p.switchToFrame("frame2"));
|
||||
assert_equals(pageTitle(p), "frame2");
|
||||
assert_equals(p.frameName, "frame2");
|
||||
assert_equals(p.framesCount, 3);
|
||||
assert_deep_equals(p.framesName,
|
||||
["frame2-1", "frame2-2", "frame2-3"]);
|
||||
|
||||
assert_equals(p.focusedFrameName, "");
|
||||
|
||||
p.evaluate(function(){
|
||||
window.focus();
|
||||
});
|
||||
assert_equals(p.focusedFrameName, "frame2");
|
||||
|
||||
assert_is_true(p.switchToFrame("frame2-1"));
|
||||
p.evaluate(function(){
|
||||
window.focus();
|
||||
});
|
||||
assert_equals(p.focusedFrameName, "frame2-1");
|
||||
|
||||
assert_equals(p.switchToMainFrame(), undefined);
|
||||
p.evaluate(function(){
|
||||
window.focus();
|
||||
});
|
||||
assert_equals(p.focusedFrameName, "");
|
||||
|
||||
p.evaluate(function(){
|
||||
window.frames[0].focus();
|
||||
});
|
||||
assert_equals(p.focusedFrameName, "frame1");
|
||||
assert_equals(p.frameName, "");
|
||||
|
||||
assert_equals(p.switchToFocusedFrame(), undefined);
|
||||
assert_equals(p.frameName, "frame1");
|
||||
}
|
||||
|
||||
p.open(TEST_HTTP_BASE + "frameset",
|
||||
this.step_func_done(function (s) {
|
||||
assert_equals(s, "success");
|
||||
testFrameSwitching();
|
||||
}));
|
||||
|
||||
}, "frame switching API");
|
15
third_party/phantomjs/test/module/webpage/https-bad-cert.js
vendored
Normal file
15
third_party/phantomjs/test/module/webpage/https-bad-cert.js
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
async_test(function () {
|
||||
// This loads the same page as https-good-cert.js, but does not
|
||||
// tell PhantomJS to trust the snakeoil certificate that the test
|
||||
// HTTPS server uses, so it should fail.
|
||||
|
||||
var page = require('webpage').create();
|
||||
var url = TEST_HTTPS_BASE;
|
||||
page.onResourceError = this.step_func(function (err) {
|
||||
assert_equals(err.url, url);
|
||||
assert_equals(err.errorString, "SSL handshake failed");
|
||||
});
|
||||
page.open(url, this.step_func_done(function (status) {
|
||||
assert_not_equals(status, "success");
|
||||
}));
|
||||
}, "should fail to load an HTTPS webpage with a self-signed certificate");
|
14
third_party/phantomjs/test/module/webpage/https-good-cert.js
vendored
Normal file
14
third_party/phantomjs/test/module/webpage/https-good-cert.js
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
//! unsupported
|
||||
//! snakeoil
|
||||
async_test(function () {
|
||||
// This loads the same page as https-bad-cert.js, but tells
|
||||
// PhantomJS to trust the snakeoil certificate
|
||||
// that the test HTTPS server uses, so it should succeed.
|
||||
|
||||
var page = require('webpage').create();
|
||||
var url = TEST_HTTPS_BASE;
|
||||
page.onResourceError = this.unreached_func();
|
||||
page.open(url, this.step_func_done(function (status) {
|
||||
assert_equals(status, "success");
|
||||
}));
|
||||
}, "loading an HTTPS webpage");
|
42
third_party/phantomjs/test/module/webpage/includejs.js
vendored
Normal file
42
third_party/phantomjs/test/module/webpage/includejs.js
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
var webpage = require('webpage');
|
||||
|
||||
async_test(function () {
|
||||
var page = webpage.create();
|
||||
page.open(TEST_HTTP_BASE + 'includejs1.html',
|
||||
this.step_func(function (status) {
|
||||
assert_equals(status, 'success');
|
||||
page.includeJs(TEST_HTTP_BASE + 'includejs.js',
|
||||
this.step_func_done(function () {
|
||||
var title = page.evaluate('getTitle');
|
||||
assert_equals(title, 'i am includejs one');
|
||||
}));
|
||||
}));
|
||||
|
||||
}, "including JS in a page");
|
||||
|
||||
async_test(function () {
|
||||
var page = webpage.create();
|
||||
var already = false;
|
||||
page.open(TEST_HTTP_BASE + 'includejs1.html',
|
||||
this.step_func(function (status) {
|
||||
assert_equals(status, 'success');
|
||||
page.includeJs(TEST_HTTP_BASE + 'includejs.js',
|
||||
this.step_func(function () {
|
||||
assert_is_false(already);
|
||||
already = true;
|
||||
var title = page.evaluate('getTitle');
|
||||
assert_equals(title, 'i am includejs one');
|
||||
page.open(TEST_HTTP_BASE + 'includejs2.html',
|
||||
this.step_func(function (status) {
|
||||
assert_equals(status, 'success');
|
||||
page.includeJs(TEST_HTTP_BASE + 'includejs.js',
|
||||
this.step_func_done(function () {
|
||||
assert_is_true(already);
|
||||
var title = page.evaluate('getTitle');
|
||||
assert_equals(title, 'i am includejs two');
|
||||
}));
|
||||
}));
|
||||
}));
|
||||
}));
|
||||
|
||||
}, "after-inclusion callbacks should fire only once");
|
21
third_party/phantomjs/test/module/webpage/keydown-event.js
vendored
Normal file
21
third_party/phantomjs/test/module/webpage/keydown-event.js
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
//! unsupported
|
||||
test(function () {
|
||||
var webpage = require('webpage');
|
||||
|
||||
var page = webpage.create();
|
||||
|
||||
page.evaluate(function() {
|
||||
window.addEventListener('keydown', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || [];
|
||||
window.loggedEvent.push(event);
|
||||
}, false);
|
||||
});
|
||||
|
||||
page.sendEvent('keydown', page.event.key.A);
|
||||
var loggedEvent = page.evaluate(function() {
|
||||
return window.loggedEvent;
|
||||
});
|
||||
|
||||
assert_equals(loggedEvent.length, 1);
|
||||
assert_equals(loggedEvent[0].which, page.event.key.A);
|
||||
}, "key-down events");
|
66
third_party/phantomjs/test/module/webpage/keypress-event.js
vendored
Normal file
66
third_party/phantomjs/test/module/webpage/keypress-event.js
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
//! unsupported
|
||||
test(function () {
|
||||
var webpage = require('webpage');
|
||||
|
||||
var page = webpage.create();
|
||||
|
||||
page.evaluate(function() {
|
||||
window.addEventListener('keypress', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || [];
|
||||
window.loggedEvent.push(event);
|
||||
}, false);
|
||||
});
|
||||
|
||||
page.sendEvent('keypress', page.event.key.C);
|
||||
var loggedEvent = page.evaluate(function() {
|
||||
return window.loggedEvent;
|
||||
});
|
||||
|
||||
assert_equals(loggedEvent.length, 1);
|
||||
assert_equals(loggedEvent[0].which, page.event.key.C);
|
||||
|
||||
|
||||
// Send keypress events to an input element and observe the effect.
|
||||
|
||||
page.content = '<input type="text">';
|
||||
page.evaluate(function() {
|
||||
document.querySelector('input').focus();
|
||||
});
|
||||
|
||||
function getText() {
|
||||
return page.evaluate(function() {
|
||||
return document.querySelector('input').value;
|
||||
});
|
||||
}
|
||||
|
||||
page.sendEvent('keypress', page.event.key.A);
|
||||
assert_equals(getText(), 'A');
|
||||
page.sendEvent('keypress', page.event.key.B);
|
||||
assert_equals(getText(), 'AB');
|
||||
page.sendEvent('keypress', page.event.key.Backspace);
|
||||
assert_equals(getText(), 'A');
|
||||
page.sendEvent('keypress', page.event.key.Backspace);
|
||||
assert_equals(getText(), '');
|
||||
|
||||
page.sendEvent('keypress', 'XYZ');
|
||||
assert_equals(getText(), 'XYZ');
|
||||
|
||||
// Special character: A with umlaut
|
||||
page.sendEvent('keypress', 'ä');
|
||||
assert_equals(getText(), 'XYZä');
|
||||
|
||||
// 0x02000000 is the Shift modifier.
|
||||
page.sendEvent('keypress', page.event.key.Home, null, null, 0x02000000);
|
||||
page.sendEvent('keypress', page.event.key.Delete);
|
||||
assert_equals(getText(), '');
|
||||
|
||||
// Cut and Paste
|
||||
// 0x04000000 is the Control modifier.
|
||||
page.sendEvent('keypress', 'ABCD');
|
||||
assert_equals(getText(), 'ABCD');
|
||||
page.sendEvent('keypress', page.event.key.Home, null, null, 0x02000000);
|
||||
page.sendEvent('keypress', 'x', null, null, 0x04000000);
|
||||
assert_equals(getText(), '');
|
||||
page.sendEvent('keypress', 'v', null, null, 0x04000000);
|
||||
assert_equals(getText(), 'ABCD');
|
||||
}, "key press events");
|
21
third_party/phantomjs/test/module/webpage/keyup-event.js
vendored
Normal file
21
third_party/phantomjs/test/module/webpage/keyup-event.js
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
//! unsupported
|
||||
test(function () {
|
||||
var webpage = require('webpage');
|
||||
|
||||
var page = webpage.create();
|
||||
|
||||
page.evaluate(function() {
|
||||
window.addEventListener('keyup', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || [];
|
||||
window.loggedEvent.push(event);
|
||||
}, false);
|
||||
});
|
||||
|
||||
page.sendEvent('keyup', page.event.key.B);
|
||||
var loggedEvent = page.evaluate(function() {
|
||||
return window.loggedEvent;
|
||||
});
|
||||
|
||||
assert_equals(loggedEvent.length, 1);
|
||||
assert_equals(loggedEvent[0].which, page.event.key.B);
|
||||
}, "key-up events");
|
22
third_party/phantomjs/test/module/webpage/loading.js
vendored
Normal file
22
third_party/phantomjs/test/module/webpage/loading.js
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
//! unsupported
|
||||
async_test(function () {
|
||||
var webpage = require('webpage');
|
||||
var page = webpage.create();
|
||||
|
||||
assert_type_of(page, 'object');
|
||||
assert_type_of(page.loading, 'boolean');
|
||||
assert_type_of(page.loadingProgress, 'number');
|
||||
|
||||
assert_is_false(page.loading);
|
||||
assert_equals(page.loadingProgress, 0);
|
||||
|
||||
page.open(TEST_HTTP_BASE + 'hello.html',
|
||||
this.step_func_done(function (status) {
|
||||
assert_equals(status, 'success');
|
||||
assert_equals(page.loading, false);
|
||||
assert_equals(page.loadingProgress, 100);
|
||||
}));
|
||||
|
||||
assert_is_true(page.loading);
|
||||
assert_greater_than(page.loadingProgress, 0);
|
||||
}, "page loading progress");
|
23
third_party/phantomjs/test/module/webpage/local-urls-disabled-iframe.js
vendored
Normal file
23
third_party/phantomjs/test/module/webpage/local-urls-disabled-iframe.js
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
//! unsupported
|
||||
//! phantomjs: --web-security=no --local-url-access=no
|
||||
|
||||
var webpage = require("webpage");
|
||||
|
||||
async_test(function () {
|
||||
var page = webpage.create();
|
||||
var url = TEST_HTTP_BASE + "iframe.html#file:///nonexistent";
|
||||
var rsErrorCalled = false;
|
||||
|
||||
page.onResourceError = this.step_func(function (error) {
|
||||
rsErrorCalled = true;
|
||||
assert_equals(error.url, "file:///nonexistent");
|
||||
assert_equals(error.errorCode, 301);
|
||||
assert_equals(error.errorString, 'Protocol "file" is unknown');
|
||||
});
|
||||
|
||||
page.open(url, this.step_func_done(function () {
|
||||
assert_is_true(rsErrorCalled);
|
||||
}));
|
||||
|
||||
},
|
||||
"doesn't attempt to load a file: URL in an iframe with --local-url-access=no");
|
22
third_party/phantomjs/test/module/webpage/local-urls-disabled.js
vendored
Normal file
22
third_party/phantomjs/test/module/webpage/local-urls-disabled.js
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
//! unsupported
|
||||
//! phantomjs: --local-url-access=no
|
||||
|
||||
var webpage = require("webpage");
|
||||
|
||||
async_test(function () {
|
||||
var page = webpage.create();
|
||||
var url = "file:///nonexistent";
|
||||
var rsErrorCalled = false;
|
||||
|
||||
page.onResourceError = this.step_func(function (error) {
|
||||
rsErrorCalled = true;
|
||||
assert_equals(error.url, url);
|
||||
assert_equals(error.errorCode, 301);
|
||||
assert_equals(error.errorString, 'Protocol "file" is unknown');
|
||||
});
|
||||
|
||||
page.open(url, this.step_func_done(function () {
|
||||
assert_is_true(rsErrorCalled);
|
||||
}));
|
||||
|
||||
}, "doesn't attempt to load a file: URL with --local-url-access=no");
|
23
third_party/phantomjs/test/module/webpage/local-urls-enabled-iframe.js
vendored
Normal file
23
third_party/phantomjs/test/module/webpage/local-urls-enabled-iframe.js
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
//! unsupported
|
||||
//! phantomjs: --web-security=no --local-url-access=yes
|
||||
|
||||
var webpage = require("webpage");
|
||||
|
||||
async_test(function () {
|
||||
var page = webpage.create();
|
||||
var url = TEST_HTTP_BASE + "iframe.html#file:///nonexistent";
|
||||
var rsErrorCalled = false;
|
||||
|
||||
page.onResourceError = this.step_func(function (error) {
|
||||
rsErrorCalled = true;
|
||||
assert_equals(error.url, "file:///nonexistent");
|
||||
assert_equals(error.errorCode, 203);
|
||||
assert_regexp_match(error.errorString,
|
||||
/^Error opening\b.*?\bnonexistent:/);
|
||||
});
|
||||
|
||||
page.open(url, this.step_func_done(function () {
|
||||
assert_is_true(rsErrorCalled);
|
||||
}));
|
||||
|
||||
}, "attempts to load a file: URL in an iframe with --local-url-access=yes");
|
23
third_party/phantomjs/test/module/webpage/local-urls-enabled.js
vendored
Normal file
23
third_party/phantomjs/test/module/webpage/local-urls-enabled.js
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
//! unsupported
|
||||
//! phantomjs: --local-url-access=yes
|
||||
|
||||
var webpage = require("webpage");
|
||||
|
||||
async_test(function () {
|
||||
var page = webpage.create();
|
||||
var url = "file:///nonexistent";
|
||||
var rsErrorCalled = false;
|
||||
|
||||
page.onResourceError = this.step_func(function (error) {
|
||||
rsErrorCalled = true;
|
||||
assert_equals(error.url, url);
|
||||
assert_equals(error.errorCode, 203);
|
||||
assert_regexp_match(error.errorString,
|
||||
/^Error opening\b.*?\bnonexistent:/);
|
||||
});
|
||||
|
||||
page.open(url, this.step_func_done(function () {
|
||||
assert_is_true(rsErrorCalled);
|
||||
}));
|
||||
|
||||
}, "attempts to load a file: URL with --local-url-access=yes");
|
19
third_party/phantomjs/test/module/webpage/long-running-javascript.js
vendored
Normal file
19
third_party/phantomjs/test/module/webpage/long-running-javascript.js
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
//! unsupported
|
||||
async_test(function () {
|
||||
var page = require('webpage').create();
|
||||
|
||||
page.onLongRunningScript = this.step_func_done(function () {
|
||||
page.stopJavaScript();
|
||||
});
|
||||
|
||||
page.open(TEST_HTTP_BASE + "js-infinite-loop.html",
|
||||
this.step_func(function (s) {
|
||||
assert_equals(s, "success");
|
||||
}));
|
||||
|
||||
}, "page.onLongRunningScript can interrupt scripts", {
|
||||
skip: true // https://github.com/ariya/phantomjs/issues/13490
|
||||
// The underlying WebKit feature is so broken that an
|
||||
// infinite loop in a _page_ script prevents timeouts
|
||||
// from firing in the _controller_!
|
||||
});
|
28
third_party/phantomjs/test/module/webpage/modify-header.js
vendored
Normal file
28
third_party/phantomjs/test/module/webpage/modify-header.js
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
//! unsupported
|
||||
async_test(function () {
|
||||
var webpage = require('webpage');
|
||||
|
||||
// NOTE: HTTP header names are case-insensitive. Our test server
|
||||
// returns the name in lowercase.
|
||||
|
||||
var page = webpage.create();
|
||||
assert_type_of(page.customHeaders, 'object');
|
||||
assert_deep_equals(page.customHeaders, {});
|
||||
|
||||
page.customHeaders = { 'CustomHeader': 'CustomValue' };
|
||||
|
||||
page.onResourceRequested = this.step_func(function(requestData, request) {
|
||||
assert_type_of(request.setHeader, 'function');
|
||||
request.setHeader('CustomHeader', 'ModifiedCustomValue');
|
||||
});
|
||||
|
||||
page.open(TEST_HTTP_BASE + 'echo', this.step_func_done(function (status) {
|
||||
var json, headers;
|
||||
assert_equals(status, 'success');
|
||||
json = JSON.parse(page.plainText);
|
||||
headers = json.headers;
|
||||
assert_own_property(headers, 'customheader');
|
||||
assert_equals(headers.customheader, 'ModifiedCustomValue');
|
||||
}));
|
||||
|
||||
}, "modifying HTTP headers");
|
39
third_party/phantomjs/test/module/webpage/mouseclick-event.js
vendored
Normal file
39
third_party/phantomjs/test/module/webpage/mouseclick-event.js
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
//! unsupported
|
||||
test(function () {
|
||||
var page = require('webpage').create();
|
||||
|
||||
page.evaluate(function() {
|
||||
window.addEventListener('mousedown', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || {};
|
||||
window.loggedEvent.mousedown = event;
|
||||
}, false);
|
||||
window.addEventListener('mouseup', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || {};
|
||||
window.loggedEvent.mouseup = event;
|
||||
}, false);
|
||||
});
|
||||
page.sendEvent('click', 42, 217);
|
||||
|
||||
var event = page.evaluate(function() {
|
||||
return window.loggedEvent;
|
||||
});
|
||||
assert_equals(event.mouseup.clientX, 42);
|
||||
assert_equals(event.mouseup.clientY, 217);
|
||||
assert_equals(event.mousedown.clientX, 42);
|
||||
assert_equals(event.mousedown.clientY, 217);
|
||||
|
||||
// click with modifier key
|
||||
page.evaluate(function() {
|
||||
window.addEventListener('click', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || {};
|
||||
window.loggedEvent.click = event;
|
||||
}, false);
|
||||
});
|
||||
page.sendEvent('click', 100, 100, 'left', page.event.modifier.shift);
|
||||
|
||||
var event = page.evaluate(function() {
|
||||
return window.loggedEvent.click;
|
||||
});
|
||||
assert_is_true(event.shiftKey);
|
||||
|
||||
}, "mouse click events");
|
31
third_party/phantomjs/test/module/webpage/mousedoubleclick-event.js
vendored
Normal file
31
third_party/phantomjs/test/module/webpage/mousedoubleclick-event.js
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
//! unsupported
|
||||
test(function () {
|
||||
var page = require('webpage').create();
|
||||
|
||||
page.content = '<input id="doubleClickField" type="text" onclick="document.getElementById(\'doubleClickField\').value=\'clicked\';" ondblclick="document.getElementById(\'doubleClickField\').value=\'doubleclicked\';" oncontextmenu="document.getElementById(\'doubleClickField\').value=\'rightclicked\'; return false;" value="hello"/>';
|
||||
var point = page.evaluate(function () {
|
||||
var el = document.querySelector('input');
|
||||
var rect = el.getBoundingClientRect();
|
||||
return { x: rect.left + Math.floor(rect.width / 2), y: rect.top + (rect.height / 2) };
|
||||
});
|
||||
page.sendEvent('doubleclick', point.x, point.y);
|
||||
|
||||
var text = page.evaluate(function () {
|
||||
return document.querySelector('input').value;
|
||||
});
|
||||
assert_equals(text, "doubleclicked");
|
||||
|
||||
// click with modifier key
|
||||
page.evaluate(function() {
|
||||
window.addEventListener('dblclick', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || {};
|
||||
window.loggedEvent.dblclick = event;
|
||||
}, false);
|
||||
});
|
||||
page.sendEvent('doubleclick', 100, 100, 'left', page.event.modifier.shift);
|
||||
|
||||
var event = page.evaluate(function() {
|
||||
return window.loggedEvent.dblclick;
|
||||
});
|
||||
assert_is_true(event.shiftKey);
|
||||
}, "mouse double-click events");
|
27
third_party/phantomjs/test/module/webpage/mousedown-event.js
vendored
Normal file
27
third_party/phantomjs/test/module/webpage/mousedown-event.js
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
//! unsupported
|
||||
test(function () {
|
||||
var page = require('webpage').create();
|
||||
|
||||
page.evaluate(function() {
|
||||
window.addEventListener('mousedown', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || [];
|
||||
window.loggedEvent.push(event);
|
||||
}, false);
|
||||
});
|
||||
|
||||
page.sendEvent('mousedown', 42, 217);
|
||||
var loggedEvent = page.evaluate(function() {
|
||||
return window.loggedEvent;
|
||||
});
|
||||
assert_equals(loggedEvent.length, 1);
|
||||
assert_equals(loggedEvent[0].clientX, 42);
|
||||
assert_equals(loggedEvent[0].clientY, 217);
|
||||
|
||||
page.sendEvent('mousedown', 100, 100, 'left', page.event.modifier.shift);
|
||||
loggedEvent = page.evaluate(function() {
|
||||
return window.loggedEvent;
|
||||
});
|
||||
assert_equals(loggedEvent.length, 2);
|
||||
assert_is_true(loggedEvent[1].shiftKey);
|
||||
|
||||
}, "mouse-down events");
|
19
third_party/phantomjs/test/module/webpage/mousemove-event.js
vendored
Normal file
19
third_party/phantomjs/test/module/webpage/mousemove-event.js
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
//! unsupported
|
||||
test(function () {
|
||||
var page = require('webpage').create();
|
||||
|
||||
page.evaluate(function() {
|
||||
window.addEventListener('mousemove', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || [];
|
||||
window.loggedEvent.push(event);
|
||||
}, false);
|
||||
});
|
||||
|
||||
page.sendEvent('mousemove', 14, 3);
|
||||
var loggedEvent = page.evaluate(function() {
|
||||
return window.loggedEvent;
|
||||
});
|
||||
assert_equals(loggedEvent.length, 1);
|
||||
assert_equals(loggedEvent[0].clientX, 14);
|
||||
assert_equals(loggedEvent[0].clientY, 3);
|
||||
}, "mouse-move events");
|
27
third_party/phantomjs/test/module/webpage/mouseup-event.js
vendored
Normal file
27
third_party/phantomjs/test/module/webpage/mouseup-event.js
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
//! unsupported
|
||||
test(function () {
|
||||
var webpage = require('webpage');
|
||||
var page = webpage.create();
|
||||
|
||||
page.evaluate(function() {
|
||||
window.addEventListener('mouseup', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || [];
|
||||
window.loggedEvent.push(event);
|
||||
}, false);
|
||||
});
|
||||
|
||||
page.sendEvent('mouseup', 42, 217);
|
||||
var loggedEvent = page.evaluate(function() {
|
||||
return window.loggedEvent;
|
||||
});
|
||||
assert_equals(loggedEvent.length, 1);
|
||||
assert_equals(loggedEvent[0].clientX, 42);
|
||||
assert_equals(loggedEvent[0].clientY, 217);
|
||||
|
||||
page.sendEvent('mouseup', 100, 100, 'left', page.event.modifier.shift);
|
||||
loggedEvent = page.evaluate(function() {
|
||||
return window.loggedEvent;
|
||||
});
|
||||
assert_equals(loggedEvent.length, 2);
|
||||
assert_is_true(loggedEvent[1].shiftKey);
|
||||
}, "mouse-up events");
|
31
third_party/phantomjs/test/module/webpage/navigation.js
vendored
Normal file
31
third_party/phantomjs/test/module/webpage/navigation.js
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
//! unsupported
|
||||
async_test(function () {
|
||||
var page = require("webpage").create();
|
||||
var url1 = TEST_HTTP_BASE + "navigation/index.html";
|
||||
var url2 = TEST_HTTP_BASE + "navigation/dest.html";
|
||||
|
||||
var onLoadFinished1 = this.step_func(function (status) {
|
||||
assert_equals(status, "success");
|
||||
assert_equals(page.url, url1);
|
||||
assert_equals(page.evaluate(function () {
|
||||
return document.body.innerHTML;
|
||||
}), "INDEX\n");
|
||||
|
||||
page.onLoadFinished = onLoadFinished2;
|
||||
page.evaluate(function() {
|
||||
window.location = "dest.html";
|
||||
});
|
||||
});
|
||||
|
||||
var onLoadFinished2 = this.step_func_done(function (status) {
|
||||
assert_equals(status, "success");
|
||||
assert_equals(page.url, url2);
|
||||
assert_equals(page.evaluate(function () {
|
||||
return document.body.innerHTML;
|
||||
}), "DEST\n");
|
||||
});
|
||||
|
||||
page.onLoadFinished = onLoadFinished1;
|
||||
page.open(url1);
|
||||
|
||||
}, "navigating to a relative URL using window.location");
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user